Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2025 Project CHIP Authors
4 : *
5 : * Licensed under the Apache License, Version 2.0 (the "License");
6 : * you may not use this file except in compliance with the License.
7 : * You may obtain a copy of the License at
8 : *
9 : * http://www.apache.org/licenses/LICENSE-2.0
10 : *
11 : * Unless required by applicable law or agreed to in writing, software
12 : * distributed under the License is distributed on an "AS IS" BASIS,
13 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 : * See the License for the specific language governing permissions and
15 : * limitations under the License.
16 : */
17 :
18 : /**
19 : * @file
20 : * openSSL based implementation of CHIP crypto primitives
21 : */
22 :
23 : #include "CHIPCryptoPAL.h"
24 : #include "CHIPCryptoPALOpenSSL.h"
25 :
26 : #include <limits>
27 : #include <type_traits>
28 :
29 : #if !CHIP_CRYPTO_BORINGSSL && defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x30200000L
30 : #include <openssl/core_names.h>
31 : #include <openssl/params.h>
32 : #elif CHIP_CRYPTO_BORINGSSL
33 : #include <openssl/aead.h>
34 : #endif
35 :
36 : #include <openssl/ec.h>
37 : #include <openssl/err.h>
38 : #include <openssl/evp.h>
39 : #include <openssl/hmac.h>
40 : #include <openssl/sha.h>
41 :
42 : #include <lib/core/CHIPSafeCasts.h>
43 : #include <lib/support/BufferWriter.h>
44 : #include <lib/support/BytesToHex.h>
45 : #include <lib/support/CodeUtils.h>
46 : #include <lib/support/SafeInt.h>
47 :
48 : namespace chip {
49 : namespace Crypto {
50 :
51 2368 : static inline void from_EC_KEY(EC_KEY * key, P256KeypairContext * context)
52 : {
53 2368 : *SafePointerCast<EC_KEY **>(context) = key;
54 2368 : }
55 :
56 2968 : static inline EC_KEY * to_EC_KEY(P256KeypairContext * context)
57 : {
58 2968 : return *SafePointerCast<EC_KEY **>(context);
59 : }
60 :
61 970 : static inline const EC_KEY * to_const_EC_KEY(const P256KeypairContext * context)
62 : {
63 970 : return *SafePointerCast<const EC_KEY * const *>(context);
64 : }
65 :
66 : // helper function to populate octet key into EVP_PKEY out_evp_pkey. Caller must free out_evp_pkey
67 26 : static CHIP_ERROR _create_evp_key_from_binary_p256_key(const P256PublicKey & key, EVP_PKEY ** out_evp_pkey)
68 : {
69 :
70 26 : CHIP_ERROR error = CHIP_NO_ERROR;
71 26 : EC_KEY * ec_key = nullptr;
72 26 : int result = -1;
73 26 : EC_POINT * point = nullptr;
74 26 : EC_GROUP * group = nullptr;
75 26 : int nid = NID_undef;
76 :
77 26 : VerifyOrExit(*out_evp_pkey == nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
78 :
79 26 : nid = GetNidForCurve(MapECName(key.Type()));
80 26 : VerifyOrExit(nid != NID_undef, error = CHIP_ERROR_INTERNAL);
81 :
82 26 : ec_key = EC_KEY_new_by_curve_name(nid);
83 26 : VerifyOrExit(ec_key != nullptr, error = CHIP_ERROR_INTERNAL);
84 :
85 26 : group = EC_GROUP_new_by_curve_name(nid);
86 26 : VerifyOrExit(group != nullptr, error = CHIP_ERROR_INTERNAL);
87 :
88 26 : point = EC_POINT_new(group);
89 26 : VerifyOrExit(point != nullptr, error = CHIP_ERROR_INTERNAL);
90 :
91 26 : result = EC_POINT_oct2point(group, point, Uint8::to_const_uchar(key), key.Length(), nullptr);
92 26 : VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
93 :
94 26 : result = EC_KEY_set_public_key(ec_key, point);
95 :
96 26 : VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
97 :
98 26 : *out_evp_pkey = EVP_PKEY_new();
99 26 : VerifyOrExit(*out_evp_pkey != nullptr, error = CHIP_ERROR_INTERNAL);
100 :
101 26 : result = EVP_PKEY_set1_EC_KEY(*out_evp_pkey, ec_key);
102 26 : VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
103 :
104 26 : exit:
105 26 : if (ec_key != nullptr)
106 : {
107 26 : EC_KEY_free(ec_key);
108 26 : ec_key = nullptr;
109 : }
110 :
111 52 : if (error != CHIP_NO_ERROR && *out_evp_pkey)
112 : {
113 0 : EVP_PKEY_free(*out_evp_pkey);
114 0 : out_evp_pkey = nullptr;
115 : }
116 :
117 26 : if (point != nullptr)
118 : {
119 26 : EC_POINT_free(point);
120 26 : point = nullptr;
121 : }
122 :
123 26 : if (group != nullptr)
124 : {
125 26 : EC_GROUP_free(group);
126 26 : group = nullptr;
127 : }
128 :
129 26 : return error;
130 : }
131 :
132 : // Encode an ECDSA_SIG (r, s) pair as a raw P256ECDSASignature (r || s, each zero-padded to kP256_FE_Length).
133 560 : static CHIP_ERROR encode_signature(const ECDSA_SIG * sig, P256ECDSASignature & out_signature)
134 : {
135 560 : const BIGNUM * r = nullptr;
136 560 : const BIGNUM * s = nullptr;
137 560 : ECDSA_SIG_get0(sig, &r, &s); // sig keeps ownership of r and s
138 560 : VerifyOrReturnError((r != nullptr) && (s != nullptr), CHIP_ERROR_INTERNAL);
139 :
140 560 : VerifyOrReturnError(BN_bn2binpad(r, out_signature.Bytes(), kP256_FE_Length) == kP256_FE_Length, CHIP_ERROR_INTERNAL);
141 560 : VerifyOrReturnError(BN_bn2binpad(s, out_signature.Bytes() + kP256_FE_Length, kP256_FE_Length) == kP256_FE_Length,
142 : CHIP_ERROR_INTERNAL);
143 560 : return out_signature.SetLength(kP256_ECDSA_Signature_Length_Raw);
144 : }
145 :
146 562 : CHIP_ERROR P256Keypair::ECDSA_sign_msg(const uint8_t * msg, const size_t msg_length, P256ECDSASignature & out_signature) const
147 : {
148 562 : CHIP_ERROR error = CHIP_NO_ERROR;
149 562 : int nid = NID_undef;
150 562 : EC_KEY * ec_key = nullptr;
151 562 : ECDSA_SIG * sig = nullptr;
152 :
153 562 : VerifyOrReturnError((msg != nullptr) && (msg_length > 0), CHIP_ERROR_INVALID_ARGUMENT);
154 :
155 : uint8_t digest[kSHA256_Hash_Length];
156 560 : SHA256(msg, msg_length, digest);
157 :
158 560 : ERR_clear_error();
159 :
160 : static_assert(P256ECDSASignature::Capacity() >= kP256_ECDSA_Signature_Length_Raw, "P256ECDSASignature must be large enough");
161 560 : VerifyOrExit(mInitialized, error = CHIP_ERROR_UNINITIALIZED);
162 560 : nid = GetNidForCurve(MapECName(mPublicKey.Type()));
163 560 : VerifyOrExit(nid != NID_undef, error = CHIP_ERROR_INVALID_ARGUMENT);
164 :
165 560 : ec_key = to_EC_KEY(&mKeypair);
166 560 : VerifyOrExit(ec_key != nullptr, error = CHIP_ERROR_INTERNAL);
167 :
168 560 : sig = ECDSA_do_sign(Uint8::to_const_uchar(&digest[0]), static_cast<boringssl_size_t_openssl_int>(sizeof(digest)), ec_key);
169 560 : VerifyOrExit(sig != nullptr, error = CHIP_ERROR_INTERNAL);
170 560 : error = encode_signature(sig, out_signature);
171 :
172 560 : exit:
173 560 : if (sig != nullptr)
174 : {
175 560 : ECDSA_SIG_free(sig);
176 : }
177 :
178 1120 : if (error != CHIP_NO_ERROR)
179 : {
180 0 : SSLErrorLog();
181 : }
182 :
183 560 : return error;
184 : }
185 :
186 : #if !CHIP_CRYPTO_BORINGSSL && defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x30200000L
187 :
188 : // OpenSSL 3.2+ natively supports deterministic ECDSA (RFC 6979) via the EVP signing API.
189 : CHIP_ERROR P256Keypair::ECDSA_sign_msg_det(const uint8_t * msg, size_t msg_length, P256ECDSASignature & out_signature) const
190 : {
191 : VerifyOrReturnError((msg != nullptr) && (msg_length > 0), CHIP_ERROR_INVALID_ARGUMENT);
192 : VerifyOrReturnError(mInitialized, CHIP_ERROR_UNINITIALIZED);
193 :
194 : ERR_clear_error();
195 :
196 : CHIP_ERROR error = CHIP_NO_ERROR;
197 : EVP_MD_CTX * md_ctx = nullptr;
198 : EVP_PKEY * evp_pkey = nullptr;
199 : EC_KEY * ec_key = nullptr;
200 :
201 : ec_key = EC_KEY_dup(to_const_EC_KEY(&mKeypair));
202 : VerifyOrExit(ec_key != nullptr, error = CHIP_ERROR_INTERNAL);
203 :
204 : evp_pkey = EVP_PKEY_new();
205 : VerifyOrExit(evp_pkey != nullptr, error = CHIP_ERROR_INTERNAL);
206 : VerifyOrExit(EVP_PKEY_set1_EC_KEY(evp_pkey, ec_key) == 1, error = CHIP_ERROR_INTERNAL);
207 :
208 : md_ctx = EVP_MD_CTX_new();
209 : VerifyOrExit(md_ctx != nullptr, error = CHIP_ERROR_INTERNAL);
210 :
211 : {
212 : // EVP_DigestSignInit sets pkey_ctx; it is owned by md_ctx and must not be freed separately.
213 : EVP_PKEY_CTX * pkey_ctx = nullptr;
214 : VerifyOrExit(EVP_DigestSignInit(md_ctx, &pkey_ctx, EVP_sha256(), nullptr, evp_pkey) == 1, error = CHIP_ERROR_INTERNAL);
215 :
216 : // Request deterministic nonce generation (RFC 6979).
217 : unsigned int nonce_type = 1;
218 : OSSL_PARAM params[] = {
219 : OSSL_PARAM_construct_uint(OSSL_SIGNATURE_PARAM_NONCE_TYPE, &nonce_type),
220 : OSSL_PARAM_END,
221 : };
222 : VerifyOrExit(EVP_PKEY_CTX_set_params(pkey_ctx, params) == 1, error = CHIP_ERROR_INTERNAL);
223 : }
224 :
225 : // EVP_DigestSign produces a DER-encoded ECDSA signature; decode it to raw (r || s).
226 : {
227 : uint8_t der_sig[kP256_ECDSA_Signature_Length_Raw + 16]; // DER overhead is at most ~8 bytes for P-256
228 : size_t der_sig_len = sizeof(der_sig);
229 : VerifyOrExit(EVP_DigestSign(md_ctx, der_sig, &der_sig_len, msg, msg_length) == 1, error = CHIP_ERROR_INTERNAL);
230 :
231 : const uint8_t * p = der_sig;
232 : ECDSA_SIG * sig = d2i_ECDSA_SIG(nullptr, &p, static_cast<long>(der_sig_len));
233 : VerifyOrExit(sig != nullptr, error = CHIP_ERROR_INTERNAL);
234 : error = encode_signature(sig, out_signature);
235 : ECDSA_SIG_free(sig);
236 : }
237 :
238 : exit:
239 : if (md_ctx != nullptr)
240 : {
241 : EVP_MD_CTX_free(md_ctx);
242 : }
243 : if (evp_pkey != nullptr)
244 : {
245 : EVP_PKEY_free(evp_pkey);
246 : }
247 : if (ec_key != nullptr)
248 : {
249 : EC_KEY_free(ec_key);
250 : }
251 : if (error != CHIP_NO_ERROR)
252 : {
253 : SSLErrorLog();
254 : }
255 : return error;
256 : }
257 :
258 : #elif CHIP_CRYPTO_BORINGSSL
259 :
260 : // BoringSSL removed RFC 6979 support, so we implement it manually:
261 : // derive k per RFC 6979 section 3.2, then sign with an explicit nonce.
262 :
263 : // Constant-time helper: returns (v != 0) ? ~0 : 0
264 : static inline unsigned int ct_nonzero_mask(unsigned int v)
265 : {
266 : return -((v | -v) >> (std::numeric_limits<decltype(v)>::digits - 1));
267 : }
268 :
269 : // Constant-time buffer comparison: returns (a >= b) ? ~0 : 0
270 : // where a and b are interpreted as big-endian unsigned integers.
271 : static unsigned int ct_buffer_gte(const volatile uint8_t * a, const volatile uint8_t * b, size_t n)
272 : {
273 : // Loosely based on mbedtls_ct_memcmp() from third_party/mbedtls/repo/library/constant_time.c
274 : unsigned int diff = 0;
275 : for (size_t i = 0; i < n; i++)
276 : {
277 : unsigned int x = a[i], y = b[i];
278 : diff |= ~ct_nonzero_mask(diff) & (x - y);
279 : }
280 :
281 : // If a < b, the first byte difference will be negative, i.e. have MSB == 1,
282 : // so extract the MSB, spread it to all bits via unary minus, and invert.
283 : return ~-(diff >> (std::numeric_limits<decltype(diff)>::digits - 1));
284 : }
285 :
286 : // HMAC_K(V || sep || x || h1_reduced) -> K, used in RFC 6979 steps d and f.
287 : static bool rfc6979_hmac_update_kv(uint8_t K[kSHA256_Hash_Length], const uint8_t V[kSHA256_Hash_Length], uint8_t sep,
288 : const uint8_t x[kP256_FE_Length], const uint8_t h1_reduced[kP256_FE_Length])
289 : {
290 : HMAC_CTX * ctx = HMAC_CTX_new();
291 : VerifyOrReturnValue(ctx != nullptr, false);
292 : unsigned int len = kSHA256_Hash_Length;
293 : bool ok = HMAC_Init_ex(ctx, K, kSHA256_Hash_Length, EVP_sha256(), nullptr) && //
294 : HMAC_Update(ctx, V, kSHA256_Hash_Length) && //
295 : HMAC_Update(ctx, &sep, 1) && //
296 : HMAC_Update(ctx, x, kP256_FE_Length) && //
297 : HMAC_Update(ctx, h1_reduced, kP256_FE_Length) && //
298 : HMAC_Final(ctx, K, &len);
299 : HMAC_CTX_free(ctx);
300 : return ok;
301 : }
302 :
303 : // RFC 6979 section 3.2 - Deterministic k generation for ECDSA with HMAC-SHA256.
304 : // For P-256 with SHA-256, qlen == hlen == 256 bits, so int2octets is the identity
305 : // on 32-byte values. bits2octets requires reducing the hash modulo the group order.
306 : //
307 : // Derives a valid nonce k in [1, order) and writes it as 32 big-endian bytes to out_k.
308 : // The private key x and hash h1 must each be exactly kP256_FE_Length bytes.
309 : static CHIP_ERROR rfc6979_derive_k(const EC_KEY * ec_key, const uint8_t x[kP256_FE_Length], const uint8_t h1[kSHA256_Hash_Length],
310 : uint8_t out_k[kP256_FE_Length])
311 : {
312 : unsigned int success = 0;
313 : CHIP_ERROR error = CHIP_NO_ERROR;
314 : memset(out_k, 0x00, kP256_FE_Length);
315 :
316 : // Serialize the group order for constant-time comparison in the candidate loop below.
317 : uint8_t order[kP256_FE_Length];
318 : const EC_GROUP * group = EC_KEY_get0_group(ec_key);
319 : const BIGNUM * order_bn = EC_GROUP_get0_order(group);
320 : VerifyOrReturnError(group != nullptr && order_bn != nullptr, CHIP_ERROR_INTERNAL);
321 : VerifyOrReturnError(BN_bn2binpad(order_bn, order, sizeof(order)) == sizeof(order), CHIP_ERROR_INTERNAL);
322 :
323 : BN_CTX * bn_ctx = BN_CTX_new();
324 : VerifyOrReturnError(bn_ctx != nullptr, CHIP_ERROR_INTERNAL);
325 : BN_CTX_start(bn_ctx);
326 :
327 : // bits2octets(h1): reduce hash modulo the group order
328 : uint8_t h1_reduced[kP256_FE_Length];
329 : {
330 : BIGNUM * h1_bn = BN_CTX_get(bn_ctx);
331 : VerifyOrExit(h1_bn != nullptr, error = CHIP_ERROR_INTERNAL);
332 : VerifyOrExit(BN_bin2bn(h1, kSHA256_Hash_Length, h1_bn) != nullptr, error = CHIP_ERROR_INTERNAL);
333 : VerifyOrExit(BN_nnmod(h1_bn, h1_bn, order_bn, bn_ctx) == 1, error = CHIP_ERROR_INTERNAL);
334 : VerifyOrExit(BN_bn2binpad(h1_bn, h1_reduced, sizeof(h1_reduced)) == sizeof(h1_reduced), error = CHIP_ERROR_INTERNAL);
335 : }
336 :
337 : // Steps b-c: initialize V and K
338 : uint8_t V[kSHA256_Hash_Length];
339 : memset(V, 0x01, sizeof(V));
340 :
341 : uint8_t K[kSHA256_Hash_Length];
342 : memset(K, 0x00, sizeof(K));
343 :
344 : // Step d: K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1))
345 : VerifyOrExit(rfc6979_hmac_update_kv(K, V, 0x00, x, h1_reduced), error = CHIP_ERROR_INTERNAL);
346 :
347 : // Step e: V = HMAC_K(V)
348 : VerifyOrExit(HMAC(EVP_sha256(), K, sizeof(K), V, sizeof(V), V, nullptr) != nullptr, error = CHIP_ERROR_INTERNAL);
349 :
350 : // Step f: K = HMAC_K(V || 0x01 || int2octets(x) || bits2octets(h1))
351 : VerifyOrExit(rfc6979_hmac_update_kv(K, V, 0x01, x, h1_reduced), error = CHIP_ERROR_INTERNAL);
352 :
353 : // Step g: V = HMAC_K(V)
354 : VerifyOrExit(HMAC(EVP_sha256(), K, sizeof(K), V, sizeof(V), V, nullptr) != nullptr, error = CHIP_ERROR_INTERNAL);
355 :
356 : // Step h: Generate candidate k, retrying if k is not in [1, order).
357 : // For P-256/SHA-256, one HMAC output (256 bits) == qlen, so one iteration
358 : // of the inner loop suffices to produce a candidate. bits2int is the identity
359 : // since qlen == hlen.
360 : // This logic needs to be constant-time to avoid leaking information about k
361 : // from either the numeric comparison operation to the order, or via the
362 : // number of candidates that had to be tested. The probability of rejection is
363 : // about 1 in 2^32 per round, so with our limit of 8 rounds, the chance of
364 : // failure is approximately 1 in 2^256 (10^77).
365 : for (int attempt = 0; attempt < 8; attempt++)
366 : {
367 : // Generate candidate: V = HMAC_K(V)
368 : VerifyOrExit(HMAC(EVP_sha256(), K, sizeof(K), V, sizeof(V), V, nullptr) != nullptr, error = CHIP_ERROR_INTERNAL);
369 :
370 : // V is our result if it's in range [1, order) and we weren't already successful.
371 : // This is equivalent to !success && !(0 >= V) && !(V >= order)
372 : // Instead of a conditional memcpy(out_k, V) bitwise or everything together with the result mask.
373 : constexpr auto zero = FixedByteSpan<kP256_FE_Length>().data(); // shared buffer of zeroes
374 : unsigned int result = ~success & ~ct_buffer_gte(zero, V, kP256_FE_Length) & ~ct_buffer_gte(V, order, kP256_FE_Length);
375 : for (size_t b = 0; b < kP256_FE_Length; b++)
376 : {
377 : out_k[b] |= V[b] & result;
378 : }
379 : success |= result;
380 :
381 : // RFC 6979 step h.3: K = HMAC_K(V || 0x00), V = HMAC_K(V)
382 : {
383 : HMAC_CTX * ctx = HMAC_CTX_new();
384 : VerifyOrExit(ctx != nullptr, error = CHIP_ERROR_INTERNAL);
385 : unsigned int len = sizeof(K);
386 : uint8_t sep = 0x00;
387 : bool ok = HMAC_Init_ex(ctx, K, sizeof(K), EVP_sha256(), nullptr) && //
388 : HMAC_Update(ctx, V, sizeof(V)) && //
389 : HMAC_Update(ctx, &sep, 1) && //
390 : HMAC_Final(ctx, K, &len);
391 : HMAC_CTX_free(ctx);
392 : VerifyOrExit(ok, error = CHIP_ERROR_INTERNAL);
393 : }
394 : VerifyOrExit(HMAC(EVP_sha256(), K, sizeof(K), V, sizeof(V), V, nullptr) != nullptr, error = CHIP_ERROR_INTERNAL);
395 : }
396 :
397 : VerifyOrExit(success, error = CHIP_ERROR_INTERNAL);
398 :
399 : exit:
400 : ClearSecretData(V);
401 : ClearSecretData(K);
402 : ClearSecretData(h1_reduced);
403 : BN_CTX_end(bn_ctx);
404 : BN_CTX_free(bn_ctx);
405 : return error;
406 : }
407 :
408 : CHIP_ERROR P256Keypair::ECDSA_sign_msg_det(const uint8_t * msg, size_t msg_length, P256ECDSASignature & out_signature) const
409 : {
410 : VerifyOrReturnError((msg != nullptr) && (msg_length > 0), CHIP_ERROR_INVALID_ARGUMENT);
411 : VerifyOrReturnError(mInitialized, CHIP_ERROR_UNINITIALIZED);
412 :
413 : ERR_clear_error();
414 :
415 : CHIP_ERROR error = CHIP_NO_ERROR;
416 : ECDSA_SIG * sig = nullptr;
417 :
418 : // Step a: h1 = Hash(msg)
419 : uint8_t h1[kSHA256_Hash_Length];
420 : SHA256(msg, msg_length, h1);
421 :
422 : const EC_KEY * ec_key = to_const_EC_KEY(&mKeypair);
423 : VerifyOrExit(ec_key != nullptr, error = CHIP_ERROR_INTERNAL);
424 :
425 : // Extract private key as big-endian bytes: int2octets(x)
426 : uint8_t x[kP256_FE_Length];
427 : {
428 : const BIGNUM * privkey_bn = EC_KEY_get0_private_key(ec_key);
429 : VerifyOrExit(privkey_bn != nullptr, error = CHIP_ERROR_INTERNAL);
430 : VerifyOrExit(BN_bn2binpad(privkey_bn, x, sizeof(x)) == sizeof(x), error = CHIP_ERROR_INTERNAL);
431 : }
432 :
433 : // Derive deterministic nonce k via RFC 6979
434 : uint8_t k[kP256_FE_Length];
435 : SuccessOrExit((error = rfc6979_derive_k(ec_key, x, h1, k)));
436 :
437 : // Sign using the deterministic nonce k derived above.
438 : // Despite its alarming name, ECDSA_sign_with_nonce_and_leak_private_key_for_testing is just a
439 : // standard ECDSA sign that accepts a caller-supplied nonce instead of generating one internally.
440 : // This testing hook is the only way to supply a pre-computed nonce. The "leak_private_key" risk
441 : // it guards against are scenarios where a caller reuses a nonce; here we provide a nonce that is
442 : // securely derived from the private key and message as per RFC 6979.
443 : sig = ECDSA_sign_with_nonce_and_leak_private_key_for_testing(h1, sizeof(h1), ec_key, k, sizeof(k));
444 : VerifyOrExit(sig != nullptr, error = CHIP_ERROR_INTERNAL);
445 : error = encode_signature(sig, out_signature);
446 :
447 : exit:
448 : ClearSecretData(x);
449 : ClearSecretData(k);
450 : if (sig != nullptr)
451 : {
452 : ECDSA_SIG_free(sig);
453 : }
454 : if (error != CHIP_NO_ERROR)
455 : {
456 : SSLErrorLog();
457 : }
458 : return error;
459 : }
460 : #endif // CHIP_CRYPTO_BORINGSSL || OPENSSL_VERSION_NUMBER >= 0x30200000L
461 :
462 26 : CHIP_ERROR P256Keypair::ECDH_derive_secret(const P256PublicKey & remote_public_key, P256ECDHDerivedSecret & out_secret) const
463 : {
464 26 : ERR_clear_error();
465 26 : CHIP_ERROR error = CHIP_NO_ERROR;
466 26 : int result = -1;
467 26 : EVP_PKEY * local_key = nullptr;
468 26 : EVP_PKEY * remote_key = nullptr;
469 :
470 26 : EVP_PKEY_CTX * context = nullptr;
471 26 : size_t out_buf_length = 0;
472 :
473 26 : EC_KEY * ec_key = EC_KEY_dup(to_const_EC_KEY(&mKeypair));
474 26 : VerifyOrExit(ec_key != nullptr, error = CHIP_ERROR_INTERNAL);
475 :
476 26 : VerifyOrExit(mInitialized, error = CHIP_ERROR_UNINITIALIZED);
477 :
478 26 : local_key = EVP_PKEY_new();
479 26 : VerifyOrExit(local_key != nullptr, error = CHIP_ERROR_INTERNAL);
480 :
481 26 : result = EVP_PKEY_set1_EC_KEY(local_key, ec_key);
482 26 : VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
483 :
484 26 : error = _create_evp_key_from_binary_p256_key(remote_public_key, &remote_key);
485 26 : SuccessOrExit(error);
486 :
487 26 : context = EVP_PKEY_CTX_new(local_key, nullptr);
488 26 : VerifyOrExit(context != nullptr, error = CHIP_ERROR_INTERNAL);
489 :
490 26 : result = EVP_PKEY_derive_init(context);
491 26 : VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
492 :
493 26 : result = EVP_PKEY_derive_set_peer(context, remote_key);
494 26 : VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
495 :
496 26 : out_buf_length = (out_secret.Length() == 0) ? out_secret.Capacity() : out_secret.Length();
497 26 : result = EVP_PKEY_derive(context, out_secret.Bytes(), &out_buf_length);
498 26 : VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
499 26 : SuccessOrExit(error = out_secret.SetLength(out_buf_length));
500 :
501 26 : exit:
502 26 : if (ec_key != nullptr)
503 : {
504 26 : EC_KEY_free(ec_key);
505 26 : ec_key = nullptr;
506 : }
507 :
508 26 : if (local_key != nullptr)
509 : {
510 26 : EVP_PKEY_free(local_key);
511 26 : local_key = nullptr;
512 : }
513 :
514 26 : if (remote_key != nullptr)
515 : {
516 26 : EVP_PKEY_free(remote_key);
517 26 : remote_key = nullptr;
518 : }
519 :
520 26 : if (context != nullptr)
521 : {
522 26 : EVP_PKEY_CTX_free(context);
523 26 : context = nullptr;
524 : }
525 :
526 26 : SSLErrorLog();
527 26 : return error;
528 : }
529 :
530 232 : CHIP_ERROR P256Keypair::Initialize(ECPKeyTarget key_target)
531 : {
532 232 : ERR_clear_error();
533 :
534 232 : Clear();
535 :
536 232 : CHIP_ERROR error = CHIP_NO_ERROR;
537 232 : int result = 0;
538 232 : EC_KEY * ec_key = nullptr;
539 232 : ECName curve = MapECName(mPublicKey.Type());
540 :
541 232 : int nid = GetNidForCurve(curve);
542 232 : VerifyOrExit(nid != NID_undef, error = CHIP_ERROR_INVALID_ARGUMENT);
543 :
544 232 : ec_key = EC_KEY_new_by_curve_name(nid);
545 232 : VerifyOrExit(ec_key != nullptr, error = CHIP_ERROR_INTERNAL);
546 :
547 232 : result = EC_KEY_generate_key(ec_key);
548 232 : VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
549 :
550 232 : error = P256PublicKeyFromECKey(ec_key, mPublicKey);
551 232 : SuccessOrExit(error);
552 :
553 232 : from_EC_KEY(ec_key, &mKeypair);
554 232 : mInitialized = true;
555 232 : ec_key = nullptr;
556 :
557 232 : exit:
558 232 : if (ec_key != nullptr)
559 : {
560 0 : EC_KEY_free(ec_key);
561 0 : ec_key = nullptr;
562 : }
563 :
564 232 : SSLErrorLog();
565 232 : return error;
566 : }
567 :
568 944 : CHIP_ERROR P256Keypair::Serialize(P256SerializedKeypair & output) const
569 : {
570 944 : CHIP_ERROR error = CHIP_NO_ERROR;
571 :
572 944 : const EC_KEY * ec_key = to_const_EC_KEY(&mKeypair);
573 : uint8_t privkey[kP256_PrivateKey_Length];
574 :
575 944 : int privkey_size = 0;
576 944 : const BIGNUM * privkey_bn = EC_KEY_get0_private_key(ec_key);
577 944 : VerifyOrExit(privkey_bn != nullptr, error = CHIP_ERROR_INTERNAL);
578 :
579 944 : privkey_size = BN_bn2binpad(privkey_bn, privkey, sizeof(privkey));
580 944 : privkey_bn = nullptr;
581 :
582 944 : VerifyOrExit(privkey_size > 0, error = CHIP_ERROR_INTERNAL);
583 944 : VerifyOrExit((size_t) privkey_size == sizeof(privkey), error = CHIP_ERROR_INTERNAL);
584 :
585 : {
586 944 : size_t len = output.Length() == 0 ? output.Capacity() : output.Length();
587 944 : Encoding::BufferWriter bbuf(output.Bytes(), len);
588 944 : bbuf.Put(mPublicKey, mPublicKey.Length());
589 944 : bbuf.Put(privkey, sizeof(privkey));
590 944 : VerifyOrExit(bbuf.Fit(), error = CHIP_ERROR_NO_MEMORY);
591 944 : TEMPORARY_RETURN_IGNORED output.SetLength(bbuf.Needed());
592 : }
593 :
594 944 : exit:
595 944 : ClearSecretData(privkey, sizeof(privkey));
596 944 : SSLErrorLog();
597 944 : return error;
598 : }
599 :
600 2123 : CHIP_ERROR P256Keypair::Deserialize(P256SerializedKeypair & input)
601 : {
602 2123 : Encoding::BufferWriter bbuf(mPublicKey, mPublicKey.Length());
603 :
604 2123 : Clear();
605 :
606 2123 : BIGNUM * pvt_key = nullptr;
607 2123 : EC_GROUP * group = nullptr;
608 2123 : EC_POINT * key_point = nullptr;
609 :
610 2123 : EC_KEY * ec_key = nullptr;
611 2123 : ECName curve = MapECName(mPublicKey.Type());
612 :
613 2123 : ERR_clear_error();
614 2123 : CHIP_ERROR error = CHIP_NO_ERROR;
615 2123 : int result = 0;
616 2123 : int nid = NID_undef;
617 :
618 2123 : const uint8_t * privkey = input.ConstBytes() + mPublicKey.Length();
619 :
620 2123 : VerifyOrExit(input.Length() == mPublicKey.Length() + kP256_PrivateKey_Length, error = CHIP_ERROR_INVALID_ARGUMENT);
621 2122 : bbuf.Put(input.ConstBytes(), mPublicKey.Length());
622 2122 : VerifyOrExit(bbuf.Fit(), error = CHIP_ERROR_NO_MEMORY);
623 :
624 2122 : nid = GetNidForCurve(curve);
625 2122 : VerifyOrExit(nid != NID_undef, error = CHIP_ERROR_INVALID_ARGUMENT);
626 :
627 2122 : group = EC_GROUP_new_by_curve_name(nid);
628 2122 : VerifyOrExit(group != nullptr, error = CHIP_ERROR_INTERNAL);
629 :
630 2122 : key_point = EC_POINT_new(group);
631 2122 : VerifyOrExit(key_point != nullptr, error = CHIP_ERROR_INTERNAL);
632 :
633 2122 : result = EC_POINT_oct2point(group, key_point, Uint8::to_const_uchar(mPublicKey), mPublicKey.Length(), nullptr);
634 2122 : VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
635 :
636 2122 : ec_key = EC_KEY_new_by_curve_name(nid);
637 2122 : VerifyOrExit(ec_key != nullptr, error = CHIP_ERROR_INTERNAL);
638 :
639 2122 : result = EC_KEY_set_public_key(ec_key, key_point);
640 2122 : VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
641 :
642 2122 : pvt_key = BN_bin2bn(privkey, kP256_PrivateKey_Length, nullptr);
643 2122 : VerifyOrExit(pvt_key != nullptr, error = CHIP_ERROR_INTERNAL);
644 :
645 2122 : result = EC_KEY_set_private_key(ec_key, pvt_key);
646 2122 : VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
647 :
648 2122 : from_EC_KEY(ec_key, &mKeypair);
649 2122 : mInitialized = true;
650 2122 : ec_key = nullptr;
651 :
652 2123 : exit:
653 2123 : if (ec_key != nullptr)
654 : {
655 0 : EC_KEY_free(ec_key);
656 0 : ec_key = nullptr;
657 : }
658 :
659 2123 : if (group != nullptr)
660 : {
661 2122 : EC_GROUP_free(group);
662 2122 : group = nullptr;
663 : }
664 :
665 2123 : if (pvt_key != nullptr)
666 : {
667 2122 : BN_clear_free(pvt_key); // wipe!
668 2122 : pvt_key = nullptr;
669 : }
670 :
671 2123 : if (key_point != nullptr)
672 : {
673 2122 : EC_POINT_free(key_point);
674 2122 : key_point = nullptr;
675 : }
676 2123 : SSLErrorLog();
677 2123 : return error;
678 : }
679 :
680 18 : CHIP_ERROR P256Keypair::InitializeFromBitsOrReject(FixedByteSpan<kP256_PrivateKey_Length> privateKeyBits)
681 : {
682 18 : ERR_clear_error();
683 18 : Clear();
684 :
685 : const EC_GROUP * group;
686 : const BIGNUM * order;
687 18 : BIGNUM * pvt_key = nullptr;
688 18 : EC_POINT * pub_point = nullptr;
689 18 : EC_KEY * ec_key = nullptr;
690 :
691 18 : CHIP_ERROR error = CHIP_NO_ERROR;
692 18 : int result = 0;
693 :
694 18 : int nid = GetNidForCurve(MapECName(mPublicKey.Type()));
695 18 : VerifyOrExit(nid != NID_undef, error = CHIP_ERROR_INTERNAL);
696 :
697 18 : ec_key = EC_KEY_new_by_curve_name(nid);
698 18 : VerifyOrExit(ec_key != nullptr, error = CHIP_ERROR_INTERNAL);
699 :
700 18 : group = EC_KEY_get0_group(ec_key);
701 18 : order = EC_GROUP_get0_order(group);
702 :
703 : // Convert private key bits to BIGNUM x, then compute d = x + 1.
704 : // Checking that d < order ensures that x was in [0, order - 2].
705 18 : pvt_key = BN_bin2bn(privateKeyBits.data(), privateKeyBits.size(), nullptr);
706 18 : VerifyOrExit(pvt_key != nullptr, error = CHIP_ERROR_INTERNAL);
707 18 : result = BN_add(pvt_key, pvt_key, BN_value_one());
708 18 : VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
709 18 : VerifyOrExit(BN_cmp(pvt_key, order) < 0, error = CHIP_ERROR_INVALID_ARGUMENT);
710 :
711 : // Compute public key: Q = d * G
712 14 : pub_point = EC_POINT_new(group);
713 14 : VerifyOrExit(pub_point != nullptr, error = CHIP_ERROR_INTERNAL);
714 :
715 14 : result = EC_POINT_mul(group, pub_point, pvt_key, nullptr, nullptr, nullptr);
716 14 : VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
717 :
718 14 : result = EC_KEY_set_private_key(ec_key, pvt_key);
719 14 : VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
720 :
721 14 : result = EC_KEY_set_public_key(ec_key, pub_point);
722 14 : VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
723 :
724 14 : SuccessOrExit(error = P256PublicKeyFromECKey(ec_key, mPublicKey));
725 :
726 14 : from_EC_KEY(ec_key, &mKeypair);
727 14 : mInitialized = true;
728 14 : ec_key = nullptr;
729 :
730 18 : exit:
731 18 : if (ec_key != nullptr)
732 : {
733 4 : EC_KEY_free(ec_key);
734 4 : ec_key = nullptr;
735 : }
736 :
737 18 : if (pub_point != nullptr)
738 : {
739 14 : EC_POINT_free(pub_point);
740 14 : pub_point = nullptr;
741 : }
742 :
743 18 : if (pvt_key != nullptr)
744 : {
745 18 : BN_clear_free(pvt_key); // wipe!
746 18 : pvt_key = nullptr;
747 : }
748 :
749 18 : SSLErrorLog();
750 18 : return error;
751 : }
752 :
753 4727 : void P256Keypair::Clear()
754 : {
755 4727 : if (mInitialized)
756 : {
757 2368 : EC_KEY * ec_key = to_EC_KEY(&mKeypair);
758 2368 : EC_KEY_free(ec_key);
759 2368 : mInitialized = false;
760 : }
761 4727 : }
762 :
763 2337 : P256Keypair::~P256Keypair()
764 : {
765 2337 : Clear();
766 2337 : }
767 :
768 40 : CHIP_ERROR P256Keypair::NewCertificateSigningRequest(uint8_t * out_csr, size_t & csr_length) const
769 : {
770 40 : ERR_clear_error();
771 40 : CHIP_ERROR error = CHIP_NO_ERROR;
772 40 : int result = 0;
773 40 : int csr_length_local = 0;
774 :
775 40 : X509_REQ * x509_req = X509_REQ_new();
776 40 : EVP_PKEY * evp_pkey = nullptr;
777 :
778 40 : EC_KEY * ec_key = to_EC_KEY(&mKeypair);
779 :
780 40 : X509_NAME * subject = X509_NAME_new();
781 40 : VerifyOrExit(subject != nullptr, error = CHIP_ERROR_INTERNAL);
782 :
783 40 : VerifyOrExit(mInitialized, error = CHIP_ERROR_UNINITIALIZED);
784 :
785 40 : result = X509_REQ_set_version(x509_req, 0);
786 40 : VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
787 :
788 40 : result = EC_KEY_check_key(ec_key);
789 40 : VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
790 :
791 40 : evp_pkey = EVP_PKEY_new();
792 40 : VerifyOrExit(evp_pkey != nullptr, error = CHIP_ERROR_INTERNAL);
793 :
794 40 : result = EVP_PKEY_set1_EC_KEY(evp_pkey, ec_key);
795 40 : VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
796 :
797 40 : result = X509_REQ_set_pubkey(x509_req, evp_pkey);
798 40 : VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
799 :
800 : // TODO: mbedTLS CSR parser fails if the subject name is not set (or if empty).
801 : // CHIP Spec doesn't specify the subject name that can be used.
802 : // Figure out the correct value and update this code.
803 40 : result = X509_NAME_add_entry_by_txt(subject, "O", MBSTRING_ASC, Uint8::from_const_char("CSR"), -1, -1, 0);
804 40 : VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
805 :
806 40 : result = X509_REQ_set_subject_name(x509_req, subject);
807 40 : VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
808 :
809 40 : result = X509_REQ_sign(x509_req, evp_pkey, EVP_sha256());
810 40 : VerifyOrExit(result > 0, error = CHIP_ERROR_INTERNAL);
811 :
812 40 : csr_length_local = i2d_X509_REQ(x509_req, nullptr);
813 40 : VerifyOrExit(csr_length_local >= 0, error = CHIP_ERROR_INTERNAL);
814 40 : VerifyOrExit(CanCastTo<size_t>(csr_length_local), error = CHIP_ERROR_BUFFER_TOO_SMALL);
815 40 : VerifyOrExit(static_cast<size_t>(csr_length_local) <= csr_length, error = CHIP_ERROR_BUFFER_TOO_SMALL);
816 40 : csr_length = static_cast<size_t>(i2d_X509_REQ(x509_req, &out_csr));
817 :
818 40 : exit:
819 40 : ec_key = nullptr;
820 :
821 40 : if (evp_pkey != nullptr)
822 : {
823 40 : EVP_PKEY_free(evp_pkey);
824 40 : evp_pkey = nullptr;
825 : }
826 :
827 40 : X509_NAME_free(subject);
828 40 : subject = nullptr;
829 :
830 40 : X509_REQ_free(x509_req);
831 :
832 40 : SSLErrorLog();
833 40 : return error;
834 : }
835 :
836 : } // namespace Crypto
837 : } // namespace chip
|