1 // Copyright 2023 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 a DiceGenerateCertificate implementation that generates a CWT-style
16 // CBOR certificate using the P-384 signature algorithm.
17
18 #include <stddef.h>
19 #include <stdint.h>
20 #include <string.h>
21
22 #include "dice/cbor_writer.h"
23 #include "dice/dice.h"
24 #include "dice/ops.h"
25 #include "dice/ops/trait/cose.h"
26 #include "dice/utils.h"
27
28 #if DICE_PUBLIC_KEY_SIZE != 96
29 #error "96 bytes needed to store the public key."
30 #endif
31 #if DICE_SIGNATURE_SIZE != 96
32 #error "96 bytes needed to store the signature."
33 #endif
34
DiceCoseEncodePublicKey(void * context_not_used,const uint8_t public_key[DICE_PUBLIC_KEY_SIZE],size_t buffer_size,uint8_t * buffer,size_t * encoded_size)35 DiceResult DiceCoseEncodePublicKey(
36 void* context_not_used, const uint8_t public_key[DICE_PUBLIC_KEY_SIZE],
37 size_t buffer_size, uint8_t* buffer, size_t* encoded_size) {
38 (void)context_not_used;
39
40 // Constants per RFC 8152.
41 const int64_t kCoseKeyKtyLabel = 1;
42 const int64_t kCoseKeyAlgLabel = 3;
43 const int64_t kCoseKeyAlgValue = DICE_COSE_KEY_ALG_VALUE;
44 const int64_t kCoseKeyOpsLabel = 4;
45 const int64_t kCoseKeyOpsValue = 2; // Verify
46 const int64_t kCoseKeyKtyValue = 2; // EC2
47 const int64_t kCoseEc2CrvLabel = -1;
48 const int64_t kCoseEc2CrvValue = 2; // P-384
49 const int64_t kCoseEc2XLabel = -2;
50 const int64_t kCoseEc2YLabel = -3;
51
52 struct CborOut out;
53 CborOutInit(buffer, buffer_size, &out);
54 CborWriteMap(/*num_pairs=*/6, &out);
55 // Add the key type.
56 CborWriteInt(kCoseKeyKtyLabel, &out);
57 CborWriteInt(kCoseKeyKtyValue, &out);
58 // Add the algorithm.
59 CborWriteInt(kCoseKeyAlgLabel, &out);
60 CborWriteInt(kCoseKeyAlgValue, &out);
61 // Add the KeyOps.
62 CborWriteInt(kCoseKeyOpsLabel, &out);
63 CborWriteArray(/*num_elements=*/1, &out);
64 CborWriteInt(kCoseKeyOpsValue, &out);
65 // Add the curve.
66 CborWriteInt(kCoseEc2CrvLabel, &out);
67 CborWriteInt(kCoseEc2CrvValue, &out);
68 // Add the subject public key x and y coordinates
69 CborWriteInt(kCoseEc2XLabel, &out);
70 CborWriteBstr(/*data_size=*/DICE_PUBLIC_KEY_SIZE / 2, &public_key[0], &out);
71 CborWriteInt(kCoseEc2YLabel, &out);
72 CborWriteBstr(/*data_size=*/DICE_PUBLIC_KEY_SIZE / 2,
73 &public_key[DICE_PUBLIC_KEY_SIZE / 2], &out);
74
75 *encoded_size = CborOutSize(&out);
76 if (CborOutOverflowed(&out)) {
77 return kDiceResultBufferTooSmall;
78 }
79 return kDiceResultOk;
80 }
81