• 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/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