1 // Copyright 2020 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 // This is an implementation of the DiceGenerateCertificate that generates an
16 // X.509 certificate based on a template using the ED25519-SHA512 signature
17 // scheme.
18 //
19 // If no variable length descriptors are used in a DICE certificate, the
20 // certificate can be constructed from a template instead of using an ASN.1
21 // library. This implementation includes only hashes and inline configuration in
22 // the DICE extension. For convenience this uses the lower level curve25519
23 // implementation in boringssl but does not use anything else (no ASN.1, X.509,
24 // etc). This approach may be especially useful in very low level components
25 // where simplicity is paramount.
26 //
27 // This function will return kDiceResultInvalidInput if 'input_values' specifies
28 // any variable length descriptors. In particular:
29 // * code_descriptor_size must be zero
30 // * authority_descriptor_size must be zero
31 // * config_type must be kDiceConfigTypeInline
32
33 #include <stdint.h>
34 #include <string.h>
35
36 #include "dice/dice.h"
37 #include "dice/ops.h"
38 #include "dice/utils.h"
39 #include "openssl/curve25519.h"
40 #include "openssl/is_boringssl.h"
41
42 // A well-formed certificate, but with zeros in all fields to be filled.
43 static const uint8_t kTemplate[635] = {
44 // Constant encoding.
45 0x30, 0x82, 0x02, 0x77,
46 // Offset 4: TBS starts here.
47 // Constant encoding.
48 0x30, 0x82, 0x02, 0x29, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14,
49 // Offset 15: Serial number, 20 bytes.
50 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52 // Constant encoding.
53 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70, 0x30, 0x33, 0x31, 0x31, 0x30,
54 0x2f, 0x06, 0x03, 0x55, 0x04, 0x05, 0x13, 0x28,
55 // Offset 55: Issuer name, 40 bytes.
56 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
59 0x00, 0x00, 0x00, 0x00,
60 // Constant encoding.
61 0x30, 0x20, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x33, 0x32, 0x32, 0x32, 0x33,
62 0x35, 0x39, 0x35, 0x39, 0x5a, 0x18, 0x0f, 0x39, 0x39, 0x39, 0x39, 0x31,
63 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x33,
64 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x05, 0x13, 0x28,
65 // Offset 142: Subject name, 40 bytes.
66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69 0x00, 0x00, 0x00, 0x00,
70 // Constant encoding.
71 0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70, 0x03, 0x21, 0x00,
72 // Offset 194: Subject public key, 32 bytes.
73 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
75 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
76 // Constant encoding.
77 0xa3, 0x82, 0x01, 0x4b, 0x30, 0x82, 0x01, 0x47, 0x30, 0x1f, 0x06, 0x03,
78 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
79 // Offset 247: Authority key identifier, 20 bytes.
80 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
81 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82 // Constant encoding.
83 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
84 // Offset 278: Subject key identifier, 20 bytes.
85 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
87 // Constant encoding.
88 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04,
89 0x03, 0x02, 0x02, 0x04, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
90 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x81, 0xe3,
91 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x02, 0x01, 0x18,
92 0x04, 0x81, 0xd4, 0x30, 0x81, 0xd1, 0xa0, 0x42, 0x04, 0x40,
93 // Offset 356: Code hash, 64 bytes.
94 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
95 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
96 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
97 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
98 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
99 0x00, 0x00, 0x00, 0x00,
100 // Constant encoding.
101 0xa3, 0x42, 0x04, 0x40,
102 // Offset 424: Configuration value, 64 bytes.
103 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
105 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
107 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
108 0x00, 0x00, 0x00, 0x00,
109 // Constant encoding.
110 0xa4, 0x42, 0x04, 0x40,
111 // Offset 492: Authority hash, 64 bytes.
112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
114 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
115 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
117 0x00, 0x00, 0x00, 0x00,
118 // Constant encoding.
119 0xa6, 0x03, 0x0a, 0x01,
120 // Offset 560: Mode, 1 byte.
121 0x00,
122 // Offset 561: TBS ends here.
123 // Constant encoding.
124 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70, 0x03, 0x41, 0x00,
125 // Offset 571: Signature, 64 bytes.
126 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
127 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
128 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
129 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
130 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
131 0x00, 0x00, 0x00, 0x00};
132
133 static const struct {
134 size_t offset;
135 size_t length;
136 } kFieldTable[] = {{15, 20}, // Serial number
137 {55, 40}, // Issuer name
138 {142, 40}, // Subject name
139 {194, 32}, // Subject public key
140 {247, 20}, // Authority key id
141 {278, 20}, // Subject key id
142 {356, 64}, // Code hash
143 {424, 64}, // Config descriptor
144 {492, 64}, // Authority hash
145 {560, 1}, // Mode
146 {571, 64}, // Signature
147 {4, 557}}; // Entire TBS
148
149 static const size_t kFieldIndexSerial = 0;
150 static const size_t kFieldIndexIssuerName = 1;
151 static const size_t kFieldIndexSubjectName = 2;
152 static const size_t kFieldIndexSubjectPublicKey = 3;
153 static const size_t kFieldIndexAuthorityKeyId = 4;
154 static const size_t kFieldIndexSubjectKeyId = 5;
155 static const size_t kFieldIndexCodeHash = 6;
156 static const size_t kFieldIndexConfigDescriptor = 7;
157 static const size_t kFieldIndexAuthorityHash = 8;
158 static const size_t kFieldIndexMode = 9;
159 static const size_t kFieldIndexSignature = 10;
160 static const size_t kFieldIndexTbs = 11;
161
162 // |buffer| must point to the beginning of the template buffer and |src| must
163 // point to at least <field-length> bytes.
CopyField(const uint8_t * src,size_t index,uint8_t * buffer)164 static void CopyField(const uint8_t* src, size_t index, uint8_t* buffer) {
165 memcpy(&buffer[kFieldTable[index].offset], src, kFieldTable[index].length);
166 }
167
DiceGenerateCertificate(void * context,const uint8_t subject_private_key_seed[DICE_PRIVATE_KEY_SEED_SIZE],const uint8_t authority_private_key_seed[DICE_PRIVATE_KEY_SEED_SIZE],const DiceInputValues * input_values,size_t certificate_buffer_size,uint8_t * certificate,size_t * certificate_actual_size)168 DiceResult DiceGenerateCertificate(
169 void* context,
170 const uint8_t subject_private_key_seed[DICE_PRIVATE_KEY_SEED_SIZE],
171 const uint8_t authority_private_key_seed[DICE_PRIVATE_KEY_SEED_SIZE],
172 const DiceInputValues* input_values, size_t certificate_buffer_size,
173 uint8_t* certificate, size_t* certificate_actual_size) {
174 DiceResult result = kDiceResultOk;
175
176 // Variable length descriptors are not supported.
177 if (input_values->code_descriptor_size > 0 ||
178 input_values->config_type != kDiceConfigTypeInline ||
179 input_values->authority_descriptor_size > 0) {
180 return kDiceResultInvalidInput;
181 }
182
183 // We know the certificate size upfront so we can do the buffer size check.
184 *certificate_actual_size = sizeof(kTemplate);
185 if (certificate_buffer_size < sizeof(kTemplate)) {
186 return kDiceResultBufferTooSmall;
187 }
188
189 // Declare buffers which are cleared on 'goto out'.
190 uint8_t subject_bssl_private_key[64];
191 uint8_t authority_bssl_private_key[64];
192
193 // Derive keys and IDs from the private key seeds.
194 uint8_t subject_public_key[32];
195 ED25519_keypair_from_seed(subject_public_key, subject_bssl_private_key,
196 subject_private_key_seed);
197
198 uint8_t subject_id[DICE_ID_SIZE];
199 result =
200 DiceDeriveCdiCertificateId(context, subject_public_key, 32, subject_id);
201 if (result != kDiceResultOk) {
202 goto out;
203 }
204 uint8_t subject_id_hex[40];
205 DiceHexEncode(subject_id, sizeof(subject_id), subject_id_hex,
206 sizeof(subject_id_hex));
207
208 uint8_t authority_public_key[32];
209 ED25519_keypair_from_seed(authority_public_key, authority_bssl_private_key,
210 authority_private_key_seed);
211
212 uint8_t authority_id[DICE_ID_SIZE];
213 result = DiceDeriveCdiCertificateId(context, authority_public_key, 32,
214 authority_id);
215 if (result != kDiceResultOk) {
216 goto out;
217 }
218 uint8_t authority_id_hex[40];
219 DiceHexEncode(authority_id, sizeof(authority_id), authority_id_hex,
220 sizeof(authority_id_hex));
221
222 // First copy in the entire template, then fill in the fields.
223 memcpy(certificate, kTemplate, sizeof(kTemplate));
224 CopyField(subject_id, kFieldIndexSerial, certificate);
225 CopyField(authority_id_hex, kFieldIndexIssuerName, certificate);
226 CopyField(subject_id_hex, kFieldIndexSubjectName, certificate);
227 CopyField(subject_public_key, kFieldIndexSubjectPublicKey, certificate);
228 CopyField(authority_id, kFieldIndexAuthorityKeyId, certificate);
229 CopyField(subject_id, kFieldIndexSubjectKeyId, certificate);
230 CopyField(input_values->code_hash, kFieldIndexCodeHash, certificate);
231 CopyField(input_values->config_value, kFieldIndexConfigDescriptor,
232 certificate);
233 CopyField(input_values->authority_hash, kFieldIndexAuthorityHash,
234 certificate);
235 certificate[kFieldTable[kFieldIndexMode].offset] = input_values->mode;
236
237 // All the TBS fields are filled in, we're ready to sign.
238 uint8_t signature[64];
239 if (1 != ED25519_sign(signature,
240 &certificate[kFieldTable[kFieldIndexTbs].offset],
241 kFieldTable[kFieldIndexTbs].length,
242 authority_bssl_private_key)) {
243 result = kDiceResultPlatformError;
244 goto out;
245 }
246 if (1 != ED25519_verify(&certificate[kFieldTable[kFieldIndexTbs].offset],
247 kFieldTable[kFieldIndexTbs].length, signature,
248 authority_public_key)) {
249 result = kDiceResultPlatformError;
250 goto out;
251 }
252 CopyField(signature, kFieldIndexSignature, certificate);
253
254 out:
255 DiceClearMemory(context, sizeof(subject_bssl_private_key),
256 subject_bssl_private_key);
257 DiceClearMemory(context, sizeof(authority_bssl_private_key),
258 authority_bssl_private_key);
259 return result;
260 }
261