1 /*
2 * t_cose_make_openssl_test_key.c
3 *
4 * Copyright 2019-2020, Laurence Lundblade
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 *
8 * See BSD-3-Clause license in README.md
9 */
10
11 #include "t_cose_make_test_pub_key.h" /* The interface implemented here */
12
13 #include "openssl/ecdsa.h"
14 #include "openssl/obj_mac.h" /* for NID for EC curve */
15 #include "openssl/err.h"
16
17
18 /*
19 * Some hard coded keys for the test cases here.
20 */
21 #define PUBLIC_KEY_prime256v1 \
22 "0437ab65955fae0466673c3a2934a3" \
23 "4f2f0ec2b3eec224198557998fc04b" \
24 "f4b2b495d9798f2539c90d7d102b3b" \
25 "bbda7fcbdb0e9b58d4e1ad2e61508d" \
26 "a75f84a67b"
27
28 #define PRIVATE_KEY_prime256v1 \
29 "f1b7142343402f3b5de7315ea894f9" \
30 "da5cf503ff7938a37ca14eb0328698" \
31 "8450"
32
33
34 #define PUBLIC_KEY_secp384r1 \
35 "04bdd9c3f818c9cef3e11e2d40e775" \
36 "beb37bc376698d71967f93337a4e03" \
37 "2dffb11b505067dddb4214b56d9bce" \
38 "c59177eccd8ab05f50975933b9a738" \
39 "d90c0b07eb9519567ef9075807cf77" \
40 "139fc1fe85608851361136806123ed" \
41 "c735ce5a03e8e4"
42
43 #define PRIVATE_KEY_secp384r1 \
44 "03df14f4b8a43fd8ab75a6046bd2b5" \
45 "eaa6fd10b2b203fd8a78d7916de20a" \
46 "a241eb37ec3d4c693d23ba2b4f6e5b" \
47 "66f57f"
48
49
50 #define PUBLIC_KEY_secp521r1 \
51 "0400e4d253175a14311fc2dd487687" \
52 "70cb49b07bd15d327beb98aa33e60c" \
53 "d0181b17fb8f1cbf07dbc8652ff5b7" \
54 "b4452c082e0686c0fab8089071cbc5" \
55 "37101d344b94c201e6424f3a18da4f" \
56 "20ecabfbc84b8467c217cd67055fa5" \
57 "dec7fb1ae87082302c1813caa4b7b1" \
58 "cf28d94677e486fb4b317097e9307a" \
59 "bdb9d50187779a3d1e682c123c"
60
61 #define PRIVATE_KEY_secp521r1 \
62 "0045d2d1439435fab333b1c6c8b534" \
63 "f0969396ad64d5f535d65f68f2a160" \
64 "6590bb15fd5322fc97a416c395745e" \
65 "72c7c85198c0921ab3b8e92dd901b5" \
66 "a42159adac6d"
67
68 /*
69 * Public function, see t_cose_make_test_pub_key.h
70 */
71 /*
72 * The key object returned by this is malloced and has to be freed by
73 * by calling free_ecdsa_key_pair(). This heap use is a part of
74 * OpenSSL and not t_cose which does not use the heap
75 */
make_ecdsa_key_pair(int32_t cose_algorithm_id,struct t_cose_key * key_pair)76 enum t_cose_err_t make_ecdsa_key_pair(int32_t cose_algorithm_id,
77 struct t_cose_key *key_pair)
78 {
79 EC_GROUP *ossl_ec_group = NULL;
80 enum t_cose_err_t return_value;
81 BIGNUM *ossl_private_key_bn = NULL;
82 EC_KEY *ossl_ec_key = NULL;
83 int ossl_result;
84 EC_POINT *ossl_pub_key_point = NULL;
85 int nid;
86 const char *public_key;
87 const char *private_key;
88
89 switch (cose_algorithm_id) {
90 case T_COSE_ALGORITHM_ES256:
91 nid = NID_X9_62_prime256v1;
92 public_key = PUBLIC_KEY_prime256v1;
93 private_key = PRIVATE_KEY_prime256v1 ;
94 break;
95
96 case T_COSE_ALGORITHM_ES384:
97 nid = NID_secp384r1;
98 public_key = PUBLIC_KEY_secp384r1;
99 private_key = PRIVATE_KEY_secp384r1;
100 break;
101
102 case T_COSE_ALGORITHM_ES512:
103 nid = NID_secp521r1;
104 public_key = PUBLIC_KEY_secp521r1;
105 private_key = PRIVATE_KEY_secp521r1;
106 break;
107
108 default:
109 return -1;
110 }
111
112 /* Make a group for the particular EC algorithm */
113 ossl_ec_group = EC_GROUP_new_by_curve_name(nid);
114 if(ossl_ec_group == NULL) {
115 return_value = T_COSE_ERR_INSUFFICIENT_MEMORY;
116 goto Done;
117 }
118
119 /* Make an empty EC key object */
120 ossl_ec_key = EC_KEY_new();
121 if(ossl_ec_key == NULL) {
122 return_value = T_COSE_ERR_INSUFFICIENT_MEMORY;
123 goto Done;
124 }
125
126 /* Associate group with key object */
127 ossl_result = EC_KEY_set_group(ossl_ec_key, ossl_ec_group);
128 if (!ossl_result) {
129 return_value = T_COSE_ERR_SIG_FAIL;
130 goto Done;
131 }
132
133 /* Make an instance of a big number to store the private key */
134 ossl_private_key_bn = BN_new();
135 if(ossl_private_key_bn == NULL) {
136 return_value = T_COSE_ERR_INSUFFICIENT_MEMORY;
137 goto Done;
138 }
139 BN_zero(ossl_private_key_bn);
140
141 /* Stuff the specific private key into the big num */
142 ossl_result = BN_hex2bn(&ossl_private_key_bn, private_key);
143 if(ossl_private_key_bn == 0) {
144 return_value = T_COSE_ERR_SIG_FAIL;
145 goto Done;
146 }
147
148 /* Now associate the big num with the key object so we finally
149 * have a key set up and ready for signing */
150 ossl_result = EC_KEY_set_private_key(ossl_ec_key, ossl_private_key_bn);
151 if (!ossl_result) {
152 return_value = T_COSE_ERR_SIG_FAIL;
153 goto Done;
154 }
155
156
157 /* Make an empty EC point into which the public key gets loaded */
158 ossl_pub_key_point = EC_POINT_new(ossl_ec_group);
159 if(ossl_pub_key_point == NULL) {
160 return_value = T_COSE_ERR_INSUFFICIENT_MEMORY;
161 goto Done;
162 }
163
164 /* Turn the serialized public key into an EC point */
165 ossl_pub_key_point = EC_POINT_hex2point(ossl_ec_group,
166 public_key,
167 ossl_pub_key_point,
168 NULL);
169 if(ossl_pub_key_point == NULL) {
170 return_value = T_COSE_ERR_SIG_FAIL;
171 goto Done;
172 }
173
174 /* Associate the EC point with key object */
175 /* The key object has both the public and private keys in it */
176 ossl_result = EC_KEY_set_public_key(ossl_ec_key, ossl_pub_key_point);
177 if(ossl_result == 0) {
178 return_value = T_COSE_ERR_SIG_FAIL;
179 goto Done;
180 }
181
182 key_pair->k.key_ptr = ossl_ec_key;
183 key_pair->crypto_lib = T_COSE_CRYPTO_LIB_OPENSSL;
184 return_value = T_COSE_SUCCESS;
185
186 Done:
187 return return_value;
188 }
189
190
191 /*
192 * Public function, see t_cose_make_test_pub_key.h
193 */
free_ecdsa_key_pair(struct t_cose_key key_pair)194 void free_ecdsa_key_pair(struct t_cose_key key_pair)
195 {
196 EC_KEY_free(key_pair.k.key_ptr);
197 }
198
199
200 /*
201 * Public function, see t_cose_make_test_pub_key.h
202 */
check_for_key_pair_leaks()203 int check_for_key_pair_leaks()
204 {
205 /* So far no good way to do this for OpenSSL or malloc() in general
206 in a nice portable way. The PSA version does check so there is
207 some coverage of the code even though there is no check here.
208 */
209 return 0;
210 }
211
212
213
214