• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/profile_name.h"
39 #include "dice/utils.h"
40 #include "openssl/curve25519.h"
41 #include "openssl/is_boringssl.h"
42 
43 // A well-formed certificate, but with zeros in all fields to be filled.
44 static const uint8_t kTemplate[638] = {
45     // Constant encoding.
46     0x30, 0x82, 0x02, 0x7a,
47     // Offset 4: TBS starts here.
48     // Constant encoding.
49     0x30, 0x82, 0x02, 0x2c, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14,
50     // Offset 15: Serial number, 20 bytes.
51     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53     // Constant encoding.
54     0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70, 0x30, 0x33, 0x31, 0x31, 0x30,
55     0x2f, 0x06, 0x03, 0x55, 0x04, 0x05, 0x13, 0x28,
56     // Offset 55: Issuer name, 40 bytes.
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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
60     0x00, 0x00, 0x00, 0x00,
61     // Constant encoding.
62     0x30, 0x20, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x33, 0x32, 0x32, 0x32, 0x33,
63     0x35, 0x39, 0x35, 0x39, 0x5a, 0x18, 0x0f, 0x39, 0x39, 0x39, 0x39, 0x31,
64     0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x33,
65     0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x05, 0x13, 0x28,
66     // Offset 142: Subject name, 40 bytes.
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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70     0x00, 0x00, 0x00, 0x00,
71     // Constant encoding.
72     0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70, 0x03, 0x21, 0x00,
73     // Offset 194: Subject public key, 32 bytes.
74     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
75     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
76     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
77     // Constant encoding.
78     0xa3, 0x82, 0x01, 0x4e, 0x30, 0x82, 0x01, 0x4a, 0x30, 0x1f, 0x06, 0x03,
79     0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
80     // Offset 247: Authority key identifier, 20 bytes.
81     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83     // Constant encoding.
84     0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
85     // Offset 278: Subject key identifier, 20 bytes.
86     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
87     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
88     // Constant encoding.
89     0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04,
90     0x03, 0x02, 0x02, 0x04, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
91     0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x81, 0xe6,
92     0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x02, 0x01, 0x18,
93     0x01, 0x01, 0xff, 0x04, 0x81, 0xd4, 0x30, 0x81, 0xd1, 0xa0, 0x42, 0x04,
94     0x40,
95     // Offset 356: Code hash, 64 bytes.
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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
101     0x00, 0x00, 0x00, 0x00,
102     // Constant encoding.
103     0xa3, 0x42, 0x04, 0x40,
104     // Offset 424: Configuration value, 64 bytes.
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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
110     0x00, 0x00, 0x00, 0x00,
111     // Constant encoding.
112     0xa4, 0x42, 0x04, 0x40,
113     // Offset 492: Authority hash, 64 bytes.
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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
119     0x00, 0x00, 0x00, 0x00,
120     // Constant encoding.
121     0xa6, 0x03, 0x0a, 0x01,
122     // Offset 560: Mode, 1 byte.
123     0x00,
124     // Offset 561: TBS ends here.
125     // Constant encoding.
126     0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70, 0x03, 0x41, 0x00,
127     // Offset 571: Signature, 64 bytes.
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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
133     0x00, 0x00, 0x00, 0x00};
134 
135 static const struct {
136   size_t offset;
137   size_t length;
138 } kFieldTable[] = {{15, 20},   // Serial number
139                    {55, 40},   // Issuer name
140                    {142, 40},  // Subject name
141                    {194, 32},  // Subject public key
142                    {247, 20},  // Authority key id
143                    {278, 20},  // Subject key id
144                    {359, 64},  // Code hash
145                    {427, 64},  // Config descriptor
146                    {495, 64},  // Authority hash
147                    {563, 1},   // Mode
148                    {574, 64},  // Signature
149                    {4, 560}};  // Entire TBS
150 
151 static const size_t kFieldIndexSerial = 0;
152 static const size_t kFieldIndexIssuerName = 1;
153 static const size_t kFieldIndexSubjectName = 2;
154 static const size_t kFieldIndexSubjectPublicKey = 3;
155 static const size_t kFieldIndexAuthorityKeyId = 4;
156 static const size_t kFieldIndexSubjectKeyId = 5;
157 static const size_t kFieldIndexCodeHash = 6;
158 static const size_t kFieldIndexConfigDescriptor = 7;
159 static const size_t kFieldIndexAuthorityHash = 8;
160 static const size_t kFieldIndexMode = 9;
161 static const size_t kFieldIndexSignature = 10;
162 static const size_t kFieldIndexTbs = 11;
163 
164 // |buffer| must point to the beginning of the template buffer and |src| must
165 // point to at least <field-length> bytes.
CopyField(const uint8_t * src,size_t index,uint8_t * buffer)166 static void CopyField(const uint8_t* src, size_t index, uint8_t* buffer) {
167   memcpy(&buffer[kFieldTable[index].offset], src, kFieldTable[index].length);
168 }
169 
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)170 DiceResult DiceGenerateCertificate(
171     void* context,
172     const uint8_t subject_private_key_seed[DICE_PRIVATE_KEY_SEED_SIZE],
173     const uint8_t authority_private_key_seed[DICE_PRIVATE_KEY_SEED_SIZE],
174     const DiceInputValues* input_values, size_t certificate_buffer_size,
175     uint8_t* certificate, size_t* certificate_actual_size) {
176   DiceResult result = kDiceResultOk;
177 
178   DiceKeyParam key_param;
179   result = DiceGetKeyParam(context, kDicePrincipalSubject, &key_param);
180   if (result != kDiceResultOk) {
181     goto out;
182   }
183 
184   // Variable length descriptors are not supported.
185   if (input_values->code_descriptor_size > 0 ||
186       input_values->config_type != kDiceConfigTypeInline ||
187       input_values->authority_descriptor_size > 0 || DICE_PROFILE_NAME) {
188     return kDiceResultInvalidInput;
189   }
190 
191   // We know the certificate size upfront so we can do the buffer size check.
192   *certificate_actual_size = sizeof(kTemplate);
193   if (certificate_buffer_size < sizeof(kTemplate)) {
194     return kDiceResultBufferTooSmall;
195   }
196 
197   // Declare buffers which are cleared on 'goto out'.
198   uint8_t subject_bssl_private_key[64];
199   uint8_t authority_bssl_private_key[64];
200 
201   // Derive keys and IDs from the private key seeds.
202   uint8_t subject_public_key[32];
203   ED25519_keypair_from_seed(subject_public_key, subject_bssl_private_key,
204                             subject_private_key_seed);
205 
206   uint8_t subject_id[DICE_ID_SIZE];
207   result =
208       DiceDeriveCdiCertificateId(context, subject_public_key, 32, subject_id);
209   if (result != kDiceResultOk) {
210     goto out;
211   }
212   uint8_t subject_id_hex[40];
213   DiceHexEncode(subject_id, sizeof(subject_id), subject_id_hex,
214                 sizeof(subject_id_hex));
215 
216   uint8_t authority_public_key[32];
217   ED25519_keypair_from_seed(authority_public_key, authority_bssl_private_key,
218                             authority_private_key_seed);
219 
220   uint8_t authority_id[DICE_ID_SIZE];
221   result = DiceDeriveCdiCertificateId(context, authority_public_key, 32,
222                                       authority_id);
223   if (result != kDiceResultOk) {
224     goto out;
225   }
226   uint8_t authority_id_hex[40];
227   DiceHexEncode(authority_id, sizeof(authority_id), authority_id_hex,
228                 sizeof(authority_id_hex));
229 
230   // First copy in the entire template, then fill in the fields.
231   memcpy(certificate, kTemplate, sizeof(kTemplate));
232   CopyField(subject_id, kFieldIndexSerial, certificate);
233   CopyField(authority_id_hex, kFieldIndexIssuerName, certificate);
234   CopyField(subject_id_hex, kFieldIndexSubjectName, certificate);
235   CopyField(subject_public_key, kFieldIndexSubjectPublicKey, certificate);
236   CopyField(authority_id, kFieldIndexAuthorityKeyId, certificate);
237   CopyField(subject_id, kFieldIndexSubjectKeyId, certificate);
238   CopyField(input_values->code_hash, kFieldIndexCodeHash, certificate);
239   CopyField(input_values->config_value, kFieldIndexConfigDescriptor,
240             certificate);
241   CopyField(input_values->authority_hash, kFieldIndexAuthorityHash,
242             certificate);
243   certificate[kFieldTable[kFieldIndexMode].offset] = input_values->mode;
244 
245   // All the TBS fields are filled in, we're ready to sign.
246   uint8_t signature[64];
247   if (1 != ED25519_sign(signature,
248                         &certificate[kFieldTable[kFieldIndexTbs].offset],
249                         kFieldTable[kFieldIndexTbs].length,
250                         authority_bssl_private_key)) {
251     result = kDiceResultPlatformError;
252     goto out;
253   }
254   if (1 != ED25519_verify(&certificate[kFieldTable[kFieldIndexTbs].offset],
255                           kFieldTable[kFieldIndexTbs].length, signature,
256                           authority_public_key)) {
257     result = kDiceResultPlatformError;
258     goto out;
259   }
260   CopyField(signature, kFieldIndexSignature, certificate);
261 
262 out:
263   DiceClearMemory(context, sizeof(subject_bssl_private_key),
264                   subject_bssl_private_key);
265   DiceClearMemory(context, sizeof(authority_bssl_private_key),
266                   authority_bssl_private_key);
267   return result;
268 }
269