1 // Copyright 2024 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 configurable, multi-algorithm implementation of signature
16 // operations using boringssl.
17
18 #include <stdint.h>
19 #include <stdio.h>
20
21 #include "dice/boringssl_ecdsa_utils.h"
22 #include "dice/config/cose_key_config.h"
23 #include "dice/dice.h"
24 #include "dice/ops.h"
25 #include "openssl/curve25519.h"
26
27 #if DICE_PRIVATE_KEY_SEED_SIZE != 32
28 #error "Private key seed is expected to be 32 bytes."
29 #endif
30 #if DICE_PUBLIC_KEY_BUFFER_SIZE != 96
31 #error "Multialg needs 96 bytes to for the public key (P-384)"
32 #endif
33 #if DICE_PRIVATE_KEY_BUFFER_SIZE != 64
34 #error "Multialg needs 64 bytes for the private key (Ed25519)"
35 #endif
36 #if DICE_SIGNATURE_BUFFER_SIZE != 96
37 #error "Multialg needs 96 bytes to store the signature (P-384)"
38 #endif
39
40 #define DICE_PROFILE_NAME_ED25519 NULL
41 #define DICE_PROFILE_NAME_P256 "opendice.example.p256"
42 #define DICE_PROFILE_NAME_P384 "opendice.example.p384"
43
DiceGetKeyParam(void * context,DicePrincipal principal,DiceKeyParam * key_param)44 DiceResult DiceGetKeyParam(void* context, DicePrincipal principal,
45 DiceKeyParam* key_param) {
46 DiceKeyAlgorithm alg;
47 DiceResult result = DiceGetKeyAlgorithm(context, principal, &alg);
48 if (result != kDiceResultOk) {
49 return result;
50 }
51 switch (alg) {
52 case kDiceKeyAlgorithmEd25519:
53 key_param->profile_name = DICE_PROFILE_NAME_ED25519;
54 key_param->public_key_size = 32;
55 key_param->signature_size = 64;
56
57 key_param->cose_key_type = kCoseKeyKtyOkp;
58 key_param->cose_key_algorithm = kCoseAlgEdDsa;
59 key_param->cose_key_curve = kCoseCrvEd25519;
60 return kDiceResultOk;
61 case kDiceKeyAlgorithmP256:
62 key_param->profile_name = DICE_PROFILE_NAME_P256;
63 key_param->public_key_size = 64;
64 key_param->signature_size = 64;
65
66 key_param->cose_key_type = kCoseKeyKtyEc2;
67 key_param->cose_key_algorithm = kCoseAlgEs256;
68 key_param->cose_key_curve = kCoseCrvP256;
69 return kDiceResultOk;
70 case kDiceKeyAlgorithmP384:
71 key_param->profile_name = DICE_PROFILE_NAME_P384;
72 key_param->public_key_size = 96;
73 key_param->signature_size = 96;
74
75 key_param->cose_key_type = kCoseKeyKtyEc2;
76 key_param->cose_key_algorithm = kCoseAlgEs384;
77 key_param->cose_key_curve = kCoseCrvP384;
78 return kDiceResultOk;
79 }
80 return kDiceResultPlatformError;
81 }
82
DiceKeypairFromSeed(void * context,DicePrincipal principal,const uint8_t seed[DICE_PRIVATE_KEY_SEED_SIZE],uint8_t public_key[DICE_PUBLIC_KEY_BUFFER_SIZE],uint8_t private_key[DICE_PRIVATE_KEY_BUFFER_SIZE])83 DiceResult DiceKeypairFromSeed(
84 void* context, DicePrincipal principal,
85 const uint8_t seed[DICE_PRIVATE_KEY_SEED_SIZE],
86 uint8_t public_key[DICE_PUBLIC_KEY_BUFFER_SIZE],
87 uint8_t private_key[DICE_PRIVATE_KEY_BUFFER_SIZE]) {
88 DiceKeyAlgorithm alg;
89 DiceResult result = DiceGetKeyAlgorithm(context, principal, &alg);
90 if (result != kDiceResultOk) {
91 return result;
92 }
93 switch (alg) {
94 case kDiceKeyAlgorithmEd25519:
95 ED25519_keypair_from_seed(public_key, private_key, seed);
96 return kDiceResultOk;
97 case kDiceKeyAlgorithmP256:
98 if (1 == P256KeypairFromSeed(public_key, private_key, seed)) {
99 return kDiceResultOk;
100 }
101 break;
102 case kDiceKeyAlgorithmP384:
103 if (1 == P384KeypairFromSeed(public_key, private_key, seed)) {
104 return kDiceResultOk;
105 }
106 break;
107 }
108 return kDiceResultPlatformError;
109 }
110
DiceSign(void * context,const uint8_t * message,size_t message_size,const uint8_t private_key[DICE_PRIVATE_KEY_BUFFER_SIZE],uint8_t signature[DICE_SIGNATURE_BUFFER_SIZE])111 DiceResult DiceSign(void* context, const uint8_t* message, size_t message_size,
112 const uint8_t private_key[DICE_PRIVATE_KEY_BUFFER_SIZE],
113 uint8_t signature[DICE_SIGNATURE_BUFFER_SIZE]) {
114 DiceKeyAlgorithm alg;
115 DiceResult result =
116 DiceGetKeyAlgorithm(context, kDicePrincipalAuthority, &alg);
117 if (result != kDiceResultOk) {
118 return result;
119 }
120 switch (alg) {
121 case kDiceKeyAlgorithmEd25519:
122 if (1 == ED25519_sign(signature, message, message_size, private_key)) {
123 return kDiceResultOk;
124 }
125 break;
126 case kDiceKeyAlgorithmP256:
127 if (1 == P256Sign(signature, message, message_size, private_key)) {
128 return kDiceResultOk;
129 }
130 break;
131 case kDiceKeyAlgorithmP384:
132 if (1 == P384Sign(signature, message, message_size, private_key)) {
133 return kDiceResultOk;
134 }
135 break;
136 }
137 return kDiceResultPlatformError;
138 }
139
DiceVerify(void * context,const uint8_t * message,size_t message_size,const uint8_t signature[DICE_SIGNATURE_BUFFER_SIZE],const uint8_t public_key[DICE_PUBLIC_KEY_BUFFER_SIZE])140 DiceResult DiceVerify(void* context, const uint8_t* message,
141 size_t message_size,
142 const uint8_t signature[DICE_SIGNATURE_BUFFER_SIZE],
143 const uint8_t public_key[DICE_PUBLIC_KEY_BUFFER_SIZE]) {
144 DiceKeyAlgorithm alg;
145 DiceResult result =
146 DiceGetKeyAlgorithm(context, kDicePrincipalAuthority, &alg);
147 if (result != kDiceResultOk) {
148 return result;
149 }
150 switch (alg) {
151 case kDiceKeyAlgorithmEd25519:
152 if (1 == ED25519_verify(message, message_size, signature, public_key)) {
153 return kDiceResultOk;
154 }
155 break;
156 case kDiceKeyAlgorithmP256:
157 if (1 == P256Verify(message, message_size, signature, public_key)) {
158 return kDiceResultOk;
159 }
160 break;
161 case kDiceKeyAlgorithmP384:
162 if (1 == P384Verify(message, message_size, signature, public_key)) {
163 return kDiceResultOk;
164 }
165 break;
166 }
167 return kDiceResultPlatformError;
168 }
169