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[638] = {
44 // Constant encoding.
45 0x30, 0x82, 0x02, 0x7a,
46 // Offset 4: TBS starts here.
47 // Constant encoding.
48 0x30, 0x82, 0x02, 0x2c, 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, 0x4e, 0x30, 0x82, 0x01, 0x4a, 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, 0xe6,
91 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x02, 0x01, 0x18,
92 0x01, 0x01, 0xff, 0x04, 0x81, 0xd4, 0x30, 0x81, 0xd1, 0xa0, 0x42, 0x04,
93 0x40,
94 // Offset 356: Code hash, 64 bytes.
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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
100 0x00, 0x00, 0x00, 0x00,
101 // Constant encoding.
102 0xa3, 0x42, 0x04, 0x40,
103 // Offset 424: Configuration value, 64 bytes.
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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
109 0x00, 0x00, 0x00, 0x00,
110 // Constant encoding.
111 0xa4, 0x42, 0x04, 0x40,
112 // Offset 492: Authority hash, 64 bytes.
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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
118 0x00, 0x00, 0x00, 0x00,
119 // Constant encoding.
120 0xa6, 0x03, 0x0a, 0x01,
121 // Offset 560: Mode, 1 byte.
122 0x00,
123 // Offset 561: TBS ends here.
124 // Constant encoding.
125 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70, 0x03, 0x41, 0x00,
126 // Offset 571: Signature, 64 bytes.
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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
132 0x00, 0x00, 0x00, 0x00};
133
134 static const struct {
135 size_t offset;
136 size_t length;
137 } kFieldTable[] = {{15, 20}, // Serial number
138 {55, 40}, // Issuer name
139 {142, 40}, // Subject name
140 {194, 32}, // Subject public key
141 {247, 20}, // Authority key id
142 {278, 20}, // Subject key id
143 {359, 64}, // Code hash
144 {427, 64}, // Config descriptor
145 {495, 64}, // Authority hash
146 {563, 1}, // Mode
147 {574, 64}, // Signature
148 {4, 560}}; // Entire TBS
149
150 static const size_t kFieldIndexSerial = 0;
151 static const size_t kFieldIndexIssuerName = 1;
152 static const size_t kFieldIndexSubjectName = 2;
153 static const size_t kFieldIndexSubjectPublicKey = 3;
154 static const size_t kFieldIndexAuthorityKeyId = 4;
155 static const size_t kFieldIndexSubjectKeyId = 5;
156 static const size_t kFieldIndexCodeHash = 6;
157 static const size_t kFieldIndexConfigDescriptor = 7;
158 static const size_t kFieldIndexAuthorityHash = 8;
159 static const size_t kFieldIndexMode = 9;
160 static const size_t kFieldIndexSignature = 10;
161 static const size_t kFieldIndexTbs = 11;
162
163 // |buffer| must point to the beginning of the template buffer and |src| must
164 // point to at least <field-length> bytes.
CopyField(const uint8_t * src,size_t index,uint8_t * buffer)165 static void CopyField(const uint8_t* src, size_t index, uint8_t* buffer) {
166 memcpy(&buffer[kFieldTable[index].offset], src, kFieldTable[index].length);
167 }
168
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)169 DiceResult DiceGenerateCertificate(
170 void* context,
171 const uint8_t subject_private_key_seed[DICE_PRIVATE_KEY_SEED_SIZE],
172 const uint8_t authority_private_key_seed[DICE_PRIVATE_KEY_SEED_SIZE],
173 const DiceInputValues* input_values, size_t certificate_buffer_size,
174 uint8_t* certificate, size_t* certificate_actual_size) {
175 DiceResult result = kDiceResultOk;
176
177 // Variable length descriptors are not supported.
178 if (input_values->code_descriptor_size > 0 ||
179 input_values->config_type != kDiceConfigTypeInline ||
180 input_values->authority_descriptor_size > 0 || DICE_PROFILE_NAME) {
181 return kDiceResultInvalidInput;
182 }
183
184 // We know the certificate size upfront so we can do the buffer size check.
185 *certificate_actual_size = sizeof(kTemplate);
186 if (certificate_buffer_size < sizeof(kTemplate)) {
187 return kDiceResultBufferTooSmall;
188 }
189
190 // Declare buffers which are cleared on 'goto out'.
191 uint8_t subject_bssl_private_key[64];
192 uint8_t authority_bssl_private_key[64];
193
194 // Derive keys and IDs from the private key seeds.
195 uint8_t subject_public_key[32];
196 ED25519_keypair_from_seed(subject_public_key, subject_bssl_private_key,
197 subject_private_key_seed);
198
199 uint8_t subject_id[DICE_ID_SIZE];
200 result =
201 DiceDeriveCdiCertificateId(context, subject_public_key, 32, subject_id);
202 if (result != kDiceResultOk) {
203 goto out;
204 }
205 uint8_t subject_id_hex[40];
206 DiceHexEncode(subject_id, sizeof(subject_id), subject_id_hex,
207 sizeof(subject_id_hex));
208
209 uint8_t authority_public_key[32];
210 ED25519_keypair_from_seed(authority_public_key, authority_bssl_private_key,
211 authority_private_key_seed);
212
213 uint8_t authority_id[DICE_ID_SIZE];
214 result = DiceDeriveCdiCertificateId(context, authority_public_key, 32,
215 authority_id);
216 if (result != kDiceResultOk) {
217 goto out;
218 }
219 uint8_t authority_id_hex[40];
220 DiceHexEncode(authority_id, sizeof(authority_id), authority_id_hex,
221 sizeof(authority_id_hex));
222
223 // First copy in the entire template, then fill in the fields.
224 memcpy(certificate, kTemplate, sizeof(kTemplate));
225 CopyField(subject_id, kFieldIndexSerial, certificate);
226 CopyField(authority_id_hex, kFieldIndexIssuerName, certificate);
227 CopyField(subject_id_hex, kFieldIndexSubjectName, certificate);
228 CopyField(subject_public_key, kFieldIndexSubjectPublicKey, certificate);
229 CopyField(authority_id, kFieldIndexAuthorityKeyId, certificate);
230 CopyField(subject_id, kFieldIndexSubjectKeyId, certificate);
231 CopyField(input_values->code_hash, kFieldIndexCodeHash, certificate);
232 CopyField(input_values->config_value, kFieldIndexConfigDescriptor,
233 certificate);
234 CopyField(input_values->authority_hash, kFieldIndexAuthorityHash,
235 certificate);
236 certificate[kFieldTable[kFieldIndexMode].offset] = input_values->mode;
237
238 // All the TBS fields are filled in, we're ready to sign.
239 uint8_t signature[64];
240 if (1 != ED25519_sign(signature,
241 &certificate[kFieldTable[kFieldIndexTbs].offset],
242 kFieldTable[kFieldIndexTbs].length,
243 authority_bssl_private_key)) {
244 result = kDiceResultPlatformError;
245 goto out;
246 }
247 if (1 != ED25519_verify(&certificate[kFieldTable[kFieldIndexTbs].offset],
248 kFieldTable[kFieldIndexTbs].length, signature,
249 authority_public_key)) {
250 result = kDiceResultPlatformError;
251 goto out;
252 }
253 CopyField(signature, kFieldIndexSignature, certificate);
254
255 out:
256 DiceClearMemory(context, sizeof(subject_bssl_private_key),
257 subject_bssl_private_key);
258 DiceClearMemory(context, sizeof(authority_bssl_private_key),
259 authority_bssl_private_key);
260 return result;
261 }
262