3 * Copyright (c) 2020-2021 Project CHIP Authors
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 * openSSL based implementation of CHIP crypto primitives
23 #include "CHIPCryptoPAL.h"
25 #include <type_traits>
27 #include <openssl/bn.h>
28 #include <openssl/conf.h>
29 #include <openssl/ec.h>
30 #include <openssl/ecdsa.h>
31 #include <openssl/err.h>
32 #include <openssl/evp.h>
33 #include <openssl/hmac.h>
34 #include <openssl/kdf.h>
35 #include <openssl/ossl_typ.h>
36 #include <openssl/pem.h>
37 #include <openssl/rand.h>
38 #include <openssl/sha.h>
39 #include <openssl/x509.h>
41 #include <core/CHIPSafeCasts.h>
42 #include <support/BufferWriter.h>
43 #include <support/CodeUtils.h>
44 #include <support/SafeInt.h>
45 #include <support/SafePointerCast.h>
46 #include <support/logging/CHIPLogging.h>
53 #define kKeyLengthInBits 256
66 nlSTATIC_ASSERT_PRINT(kMax_ECDH_Secret_Length >= 32, "ECDH shared secret is too short");
67 nlSTATIC_ASSERT_PRINT(kMax_ECDSA_Signature_Length >= 72, "ECDSA signature buffer length is too short");
69 static int _nidForCurve(ECName name)
74 return EC_curve_nist2nid("P-256");
83 static bool _isValidTagLength(size_t tag_length)
85 return tag_length == 8 || tag_length == 12 || tag_length == 16;
88 static bool _isValidKeyLength(size_t length)
90 // 16 bytes key for AES-CCM-128, 32 for AES-CCM-256
91 return length == 16 || length == 32;
94 static void _logSSLError()
96 unsigned long ssl_err_code = ERR_get_error();
97 while (ssl_err_code != 0)
99 const char * err_str_lib = ERR_lib_error_string(ssl_err_code);
100 const char * err_str_routine = ERR_func_error_string(ssl_err_code);
101 const char * err_str_reason = ERR_reason_error_string(ssl_err_code);
104 ChipLogError(Crypto, " ssl err %s %s %s\n", err_str_lib, err_str_routine, err_str_reason);
106 ssl_err_code = ERR_get_error();
110 static const EVP_MD * _digestForType(DigestType digestType)
114 case DigestType::SHA256:
124 CHIP_ERROR AES_CCM_encrypt(const uint8_t * plaintext, size_t plaintext_length, const uint8_t * aad, size_t aad_length,
125 const uint8_t * key, size_t key_length, const uint8_t * iv, size_t iv_length, uint8_t * ciphertext,
126 uint8_t * tag, size_t tag_length)
128 EVP_CIPHER_CTX * context = nullptr;
129 int bytesWritten = 0;
130 size_t ciphertext_length = 0;
131 CHIP_ERROR error = CHIP_NO_ERROR;
133 const EVP_CIPHER * type = nullptr;
135 VerifyOrExit(plaintext != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
136 VerifyOrExit(plaintext_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
137 VerifyOrExit(key != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
138 VerifyOrExit(_isValidKeyLength(key_length), error = CHIP_ERROR_INVALID_ARGUMENT);
139 VerifyOrExit(iv != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
140 VerifyOrExit(iv_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
141 VerifyOrExit(CanCastTo<int>(iv_length), error = CHIP_ERROR_INVALID_ARGUMENT);
142 VerifyOrExit(tag != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
143 VerifyOrExit(_isValidTagLength(tag_length), error = CHIP_ERROR_INVALID_ARGUMENT);
145 // 16 bytes key for AES-CCM-128
146 type = (key_length == 16) ? EVP_aes_128_ccm() : EVP_aes_256_ccm();
148 context = EVP_CIPHER_CTX_new();
149 VerifyOrExit(context != nullptr, error = CHIP_ERROR_INTERNAL);
152 result = EVP_EncryptInit_ex(context, type, nullptr, nullptr, nullptr);
153 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
155 // Pass in IV length. Cast is safe because we checked with CanCastTo.
156 result = EVP_CIPHER_CTX_ctrl(context, EVP_CTRL_CCM_SET_IVLEN, static_cast<int>(iv_length), nullptr);
157 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
159 // Pass in tag length. Cast is safe because we checked _isValidTagLength.
160 result = EVP_CIPHER_CTX_ctrl(context, EVP_CTRL_CCM_SET_TAG, static_cast<int>(tag_length), nullptr);
161 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
164 result = EVP_EncryptInit_ex(context, nullptr, nullptr, Uint8::to_const_uchar(key), Uint8::to_const_uchar(iv));
165 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
167 // Pass in plain text length
168 VerifyOrExit(CanCastTo<int>(plaintext_length), error = CHIP_ERROR_INVALID_ARGUMENT);
169 result = EVP_EncryptUpdate(context, nullptr, &bytesWritten, nullptr, static_cast<int>(plaintext_length));
170 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
173 if (aad_length > 0 && aad != nullptr)
175 VerifyOrExit(CanCastTo<int>(aad_length), error = CHIP_ERROR_INVALID_ARGUMENT);
176 result = EVP_EncryptUpdate(context, nullptr, &bytesWritten, Uint8::to_const_uchar(aad), static_cast<int>(aad_length));
177 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
181 VerifyOrExit(CanCastTo<int>(plaintext_length), error = CHIP_ERROR_INVALID_ARGUMENT);
182 result = EVP_EncryptUpdate(context, Uint8::to_uchar(ciphertext), &bytesWritten, Uint8::to_const_uchar(plaintext),
183 static_cast<int>(plaintext_length));
184 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
185 VerifyOrExit(bytesWritten >= 0, error = CHIP_ERROR_INTERNAL);
186 ciphertext_length = static_cast<unsigned int>(bytesWritten);
188 // Finalize encryption
189 result = EVP_EncryptFinal_ex(context, ciphertext + ciphertext_length, &bytesWritten);
190 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
191 VerifyOrExit(bytesWritten >= 0, error = CHIP_ERROR_INTERNAL);
192 ciphertext_length += static_cast<unsigned int>(bytesWritten);
195 VerifyOrExit(CanCastTo<int>(tag_length), error = CHIP_ERROR_INVALID_ARGUMENT);
196 result = EVP_CIPHER_CTX_ctrl(context, EVP_CTRL_CCM_GET_TAG, static_cast<int>(tag_length), Uint8::to_uchar(tag));
197 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
200 if (context != nullptr)
202 EVP_CIPHER_CTX_free(context);
209 CHIP_ERROR AES_CCM_decrypt(const uint8_t * ciphertext, size_t ciphertext_length, const uint8_t * aad, size_t aad_length,
210 const uint8_t * tag, size_t tag_length, const uint8_t * key, size_t key_length, const uint8_t * iv,
211 size_t iv_length, uint8_t * plaintext)
213 EVP_CIPHER_CTX * context = nullptr;
214 CHIP_ERROR error = CHIP_NO_ERROR;
217 const EVP_CIPHER * type = nullptr;
219 VerifyOrExit(ciphertext != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
220 VerifyOrExit(ciphertext_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
221 VerifyOrExit(tag != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
222 VerifyOrExit(_isValidTagLength(tag_length), error = CHIP_ERROR_INVALID_ARGUMENT);
223 VerifyOrExit(key != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
224 VerifyOrExit(_isValidKeyLength(key_length), error = CHIP_ERROR_INVALID_ARGUMENT);
225 VerifyOrExit(iv != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
226 VerifyOrExit(iv_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
228 // 16 bytes key for AES-CCM-128
229 type = (key_length == 16) ? EVP_aes_128_ccm() : EVP_aes_256_ccm();
231 context = EVP_CIPHER_CTX_new();
232 VerifyOrExit(context != nullptr, error = CHIP_ERROR_INTERNAL);
235 result = EVP_DecryptInit_ex(context, type, nullptr, nullptr, nullptr);
236 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
239 VerifyOrExit(CanCastTo<int>(iv_length), error = CHIP_ERROR_INVALID_ARGUMENT);
240 result = EVP_CIPHER_CTX_ctrl(context, EVP_CTRL_CCM_SET_IVLEN, static_cast<int>(iv_length), nullptr);
241 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
243 // Pass in expected tag
244 // Removing "const" from |tag| here should hopefully be safe as
245 // we're writing the tag, not reading.
246 VerifyOrExit(CanCastTo<int>(tag_length), error = CHIP_ERROR_INVALID_ARGUMENT);
247 result = EVP_CIPHER_CTX_ctrl(context, EVP_CTRL_CCM_SET_TAG, static_cast<int>(tag_length),
248 const_cast<void *>(static_cast<const void *>(tag)));
249 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
252 result = EVP_DecryptInit_ex(context, nullptr, nullptr, Uint8::to_const_uchar(key), Uint8::to_const_uchar(iv));
253 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
255 // Pass in cipher text length
256 VerifyOrExit(CanCastTo<int>(ciphertext_length), error = CHIP_ERROR_INVALID_ARGUMENT);
257 result = EVP_DecryptUpdate(context, nullptr, &bytesOutput, nullptr, static_cast<int>(ciphertext_length));
258 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
261 if (aad_length > 0 && aad != nullptr)
263 VerifyOrExit(CanCastTo<int>(aad_length), error = CHIP_ERROR_INVALID_ARGUMENT);
264 result = EVP_DecryptUpdate(context, nullptr, &bytesOutput, Uint8::to_const_uchar(aad), static_cast<int>(aad_length));
265 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
268 // Pass in ciphertext. We wont get anything if validation fails.
269 VerifyOrExit(CanCastTo<int>(ciphertext_length), error = CHIP_ERROR_INVALID_ARGUMENT);
270 result = EVP_DecryptUpdate(context, Uint8::to_uchar(plaintext), &bytesOutput, Uint8::to_const_uchar(ciphertext),
271 static_cast<int>(ciphertext_length));
272 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
275 if (context != nullptr)
277 EVP_CIPHER_CTX_free(context);
284 CHIP_ERROR Hash_SHA256(const uint8_t * data, const size_t data_length, uint8_t * out_buffer)
286 CHIP_ERROR error = CHIP_NO_ERROR;
288 // zero data length hash is supported.
290 VerifyOrExit(out_buffer != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
292 SHA256(data, data_length, Uint8::to_uchar(out_buffer));
298 Hash_SHA256_stream::Hash_SHA256_stream() {}
300 Hash_SHA256_stream::~Hash_SHA256_stream() {}
302 static inline SHA256_CTX * to_inner_hash_sha256_context(HashSHA256OpaqueContext * context)
304 return SafePointerCast<SHA256_CTX *>(context);
307 CHIP_ERROR Hash_SHA256_stream::Begin()
309 CHIP_ERROR error = CHIP_NO_ERROR;
312 SHA256_CTX * context = to_inner_hash_sha256_context(&mContext);
314 result = SHA256_Init(context);
315 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
321 CHIP_ERROR Hash_SHA256_stream::AddData(const uint8_t * data, const size_t data_length)
323 CHIP_ERROR error = CHIP_NO_ERROR;
326 SHA256_CTX * context = to_inner_hash_sha256_context(&mContext);
328 result = SHA256_Update(context, Uint8::to_const_uchar(data), data_length);
329 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
335 CHIP_ERROR Hash_SHA256_stream::Finish(uint8_t * out_buffer)
337 CHIP_ERROR error = CHIP_NO_ERROR;
340 SHA256_CTX * context = to_inner_hash_sha256_context(&mContext);
342 result = SHA256_Final(Uint8::to_uchar(out_buffer), context);
343 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
349 void Hash_SHA256_stream::Clear()
351 memset(this, 0, sizeof(*this));
354 CHIP_ERROR HKDF_SHA256(const uint8_t * secret, const size_t secret_length, const uint8_t * salt, const size_t salt_length,
355 const uint8_t * info, const size_t info_length, uint8_t * out_buffer, size_t out_length)
357 EVP_PKEY_CTX * context;
358 CHIP_ERROR error = CHIP_NO_ERROR;
361 context = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, nullptr);
362 VerifyOrExit(context != nullptr, error = CHIP_ERROR_INTERNAL);
364 VerifyOrExit(secret != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
365 VerifyOrExit(secret_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
370 VerifyOrExit(salt != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
373 VerifyOrExit(info_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
374 VerifyOrExit(info != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
375 VerifyOrExit(out_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
376 VerifyOrExit(out_buffer != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
378 result = EVP_PKEY_derive_init(context);
379 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
381 result = EVP_PKEY_CTX_set_hkdf_md(context, EVP_sha256());
382 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
384 VerifyOrExit(CanCastTo<int>(secret_length), error = CHIP_ERROR_INVALID_ARGUMENT);
385 result = EVP_PKEY_CTX_set1_hkdf_key(context, Uint8::to_const_uchar(secret), static_cast<int>(secret_length));
386 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
388 if (salt_length > 0 && salt != nullptr)
390 VerifyOrExit(CanCastTo<int>(salt_length), error = CHIP_ERROR_INVALID_ARGUMENT);
391 result = EVP_PKEY_CTX_set1_hkdf_salt(context, Uint8::to_const_uchar(salt), static_cast<int>(salt_length));
392 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
395 VerifyOrExit(CanCastTo<int>(info_length), error = CHIP_ERROR_INVALID_ARGUMENT);
396 result = EVP_PKEY_CTX_add1_hkdf_info(context, Uint8::to_const_uchar(info), static_cast<int>(info_length));
397 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
399 result = EVP_PKEY_CTX_hkdf_mode(context, EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND);
400 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
402 // Get the OKM (Output Key Material)
403 result = EVP_PKEY_derive(context, Uint8::to_uchar(out_buffer), &out_length);
404 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
407 if (context != nullptr)
409 EVP_PKEY_CTX_free(context);
414 CHIP_ERROR pbkdf2_sha256(const uint8_t * password, size_t plen, const uint8_t * salt, size_t slen, unsigned int iteration_count,
415 uint32_t key_length, uint8_t * output)
417 CHIP_ERROR error = CHIP_NO_ERROR;
419 const EVP_MD * md = nullptr;
421 VerifyOrExit(password != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
422 VerifyOrExit(plen > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
423 VerifyOrExit(salt != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
424 VerifyOrExit(slen >= kMin_Salt_Length, error = CHIP_ERROR_INVALID_ARGUMENT);
425 VerifyOrExit(slen <= kMax_Salt_Length, error = CHIP_ERROR_INVALID_ARGUMENT);
426 VerifyOrExit(key_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
427 VerifyOrExit(output != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
429 md = _digestForType(DigestType::SHA256);
430 VerifyOrExit(md != nullptr, error = CHIP_ERROR_INTERNAL);
432 VerifyOrExit(CanCastTo<int>(plen), error = CHIP_ERROR_INVALID_ARGUMENT);
433 VerifyOrExit(CanCastTo<int>(slen), error = CHIP_ERROR_INVALID_ARGUMENT);
434 VerifyOrExit(CanCastTo<int>(iteration_count), error = CHIP_ERROR_INVALID_ARGUMENT);
435 VerifyOrExit(CanCastTo<int>(key_length), error = CHIP_ERROR_INVALID_ARGUMENT);
436 result = PKCS5_PBKDF2_HMAC(Uint8::to_const_char(password), static_cast<int>(plen), Uint8::to_const_uchar(salt),
437 static_cast<int>(slen), static_cast<int>(iteration_count), md, static_cast<int>(key_length),
438 Uint8::to_uchar(output));
440 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
443 if (error != CHIP_NO_ERROR)
451 CHIP_ERROR add_entropy_source(entropy_source fn_source, void * p_source, size_t threshold)
453 return CHIP_NO_ERROR;
456 CHIP_ERROR DRBG_get_bytes(uint8_t * out_buffer, const size_t out_length)
458 CHIP_ERROR error = CHIP_NO_ERROR;
461 VerifyOrExit(out_buffer != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
462 VerifyOrExit(out_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
464 VerifyOrExit(CanCastTo<int>(out_length), error = CHIP_ERROR_INVALID_ARGUMENT);
465 result = RAND_priv_bytes(Uint8::to_uchar(out_buffer), static_cast<int>(out_length));
466 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
472 ECName MapECName(SupportedECPKeyTypes keyType)
476 case SupportedECPKeyTypes::ECP256R1:
477 return ECName::P256v1;
483 static inline void from_EC_KEY(EC_KEY * key, P256KeypairContext * context)
485 *SafePointerCast<EC_KEY **>(context) = key;
488 static inline EC_KEY * to_EC_KEY(P256KeypairContext * context)
490 return *SafePointerCast<EC_KEY **>(context);
493 static inline const EC_KEY * to_const_EC_KEY(const P256KeypairContext * context)
495 return *SafePointerCast<const EC_KEY * const *>(context);
498 CHIP_ERROR P256Keypair::ECDSA_sign_msg(const uint8_t * msg, const size_t msg_length, P256ECDSASignature & out_signature)
502 CHIP_ERROR error = CHIP_NO_ERROR;
504 EVP_MD_CTX * context = nullptr;
506 EC_KEY * ec_key = nullptr;
507 EVP_PKEY * signing_key = nullptr;
508 const EVP_MD * md = nullptr;
509 DigestType digest = DigestType::SHA256;
510 size_t out_length = 0;
512 VerifyOrExit(mInitialized, error = CHIP_ERROR_INCORRECT_STATE);
513 VerifyOrExit(msg != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
514 VerifyOrExit(msg_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
515 nid = _nidForCurve(MapECName(mPublicKey.Type()));
516 VerifyOrExit(nid != NID_undef, error = CHIP_ERROR_INVALID_ARGUMENT);
517 md = _digestForType(digest);
518 VerifyOrExit(md != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
520 ec_key = to_EC_KEY(&mKeypair);
521 VerifyOrExit(ec_key != nullptr, error = CHIP_ERROR_INTERNAL);
523 signing_key = EVP_PKEY_new();
524 VerifyOrExit(signing_key != nullptr, error = CHIP_ERROR_INTERNAL);
526 result = EVP_PKEY_set1_EC_KEY(signing_key, ec_key);
527 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
529 context = EVP_MD_CTX_create();
530 VerifyOrExit(context != nullptr, error = CHIP_ERROR_INTERNAL);
532 result = EVP_DigestSignInit(context, nullptr, md, nullptr, signing_key);
533 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
535 result = EVP_DigestSignUpdate(context, Uint8::to_const_uchar(msg), msg_length);
536 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
538 // Call the EVP_DigestSignFinal with a nullptr param to get length of the signature.
540 result = EVP_DigestSignFinal(context, nullptr, &out_length);
541 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
542 VerifyOrExit(out_signature.Capacity() >= out_length, error = CHIP_ERROR_INVALID_ARGUMENT);
544 result = EVP_DigestSignFinal(context, Uint8::to_uchar(out_signature), &out_length);
545 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
546 // This should not happen due to the check above. But check this nonetheless
547 SuccessOrExit(out_signature.SetLength(out_length));
552 if (context != nullptr)
554 EVP_MD_CTX_destroy(context);
557 if (signing_key != nullptr)
559 EVP_PKEY_free(signing_key);
560 signing_key = nullptr;
563 if (error != CHIP_NO_ERROR)
571 CHIP_ERROR P256Keypair::ECDSA_sign_hash(const uint8_t * hash, const size_t hash_length, P256ECDSASignature & out_signature)
575 CHIP_ERROR error = CHIP_NO_ERROR;
578 EC_KEY * ec_key = nullptr;
581 VerifyOrExit(mInitialized, error = CHIP_ERROR_INCORRECT_STATE);
582 VerifyOrExit(hash != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
583 VerifyOrExit(hash_length == kSHA256_Hash_Length, error = CHIP_ERROR_INVALID_ARGUMENT);
584 nid = _nidForCurve(MapECName(mPublicKey.Type()));
585 VerifyOrExit(nid != NID_undef, error = CHIP_ERROR_INVALID_ARGUMENT);
587 ec_key = to_EC_KEY(&mKeypair);
588 VerifyOrExit(ec_key != nullptr, error = CHIP_ERROR_INTERNAL);
590 result = ECDSA_sign(0, hash, static_cast<int>(hash_length), Uint8::to_uchar(out_signature), &out_length, ec_key);
591 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
592 // This should not happen due to the check above. But check this nonetheless
593 SuccessOrExit(out_signature.SetLength(out_length));
596 if (error != CHIP_NO_ERROR)
604 CHIP_ERROR P256PublicKey::ECDSA_validate_msg_signature(const uint8_t * msg, const size_t msg_length,
605 const P256ECDSASignature & signature) const
608 CHIP_ERROR error = CHIP_ERROR_INTERNAL;
610 const EVP_MD * md = nullptr;
611 EC_KEY * ec_key = nullptr;
612 EVP_PKEY * verification_key = nullptr;
613 EC_POINT * key_point = nullptr;
614 EC_GROUP * ec_group = nullptr;
616 EVP_MD_CTX * md_context = nullptr;
617 DigestType digest = DigestType::SHA256;
619 VerifyOrExit(msg != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
620 VerifyOrExit(msg_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
621 nid = _nidForCurve(MapECName(Type()));
622 VerifyOrExit(nid != NID_undef, error = CHIP_ERROR_INVALID_ARGUMENT);
624 md = _digestForType(digest);
625 VerifyOrExit(md != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
627 ec_group = EC_GROUP_new_by_curve_name(nid);
628 VerifyOrExit(ec_group != nullptr, error = CHIP_ERROR_INTERNAL);
630 key_point = EC_POINT_new(ec_group);
631 VerifyOrExit(key_point != nullptr, error = CHIP_ERROR_INTERNAL);
633 result = EC_POINT_oct2point(ec_group, key_point, Uint8::to_const_uchar(*this), Length(), nullptr);
634 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
636 ec_key = EC_KEY_new_by_curve_name(nid);
637 VerifyOrExit(ec_key != nullptr, error = CHIP_ERROR_INTERNAL);
639 result = EC_KEY_set_public_key(ec_key, key_point);
640 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
642 result = EC_KEY_check_key(ec_key);
643 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
645 verification_key = EVP_PKEY_new();
646 VerifyOrExit(verification_key != nullptr, error = CHIP_ERROR_INTERNAL);
648 result = EVP_PKEY_set1_EC_KEY(verification_key, ec_key);
649 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
651 md_context = EVP_MD_CTX_create();
652 VerifyOrExit(md_context != nullptr, error = CHIP_ERROR_INTERNAL);
654 result = EVP_DigestVerifyInit(md_context, nullptr, md, nullptr, verification_key);
655 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
657 result = EVP_DigestVerifyUpdate(md_context, Uint8::to_const_uchar(msg), msg_length);
658 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
660 result = EVP_DigestVerifyFinal(md_context, Uint8::to_const_uchar(signature), signature.Length());
661 VerifyOrExit(result == 1, error = CHIP_ERROR_INVALID_SIGNATURE);
662 error = CHIP_NO_ERROR;
666 if (ec_group != nullptr)
668 EC_GROUP_free(ec_group);
671 if (key_point != nullptr)
673 EC_POINT_clear_free(key_point);
678 EVP_MD_CTX_destroy(md_context);
679 md_context = nullptr;
681 if (ec_key != nullptr)
686 if (verification_key != nullptr)
688 EVP_PKEY_free(verification_key);
689 verification_key = nullptr;
694 CHIP_ERROR P256PublicKey::ECDSA_validate_hash_signature(const uint8_t * hash, const size_t hash_length,
695 const P256ECDSASignature & signature) const
698 CHIP_ERROR error = CHIP_ERROR_INTERNAL;
700 EC_KEY * ec_key = nullptr;
701 EC_POINT * key_point = nullptr;
702 EC_GROUP * ec_group = nullptr;
705 VerifyOrExit(hash != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
706 VerifyOrExit(hash_length == kSHA256_Hash_Length, error = CHIP_ERROR_INVALID_ARGUMENT);
707 nid = _nidForCurve(MapECName(Type()));
708 VerifyOrExit(nid != NID_undef, error = CHIP_ERROR_INVALID_ARGUMENT);
710 ec_group = EC_GROUP_new_by_curve_name(nid);
711 VerifyOrExit(ec_group != nullptr, error = CHIP_ERROR_INTERNAL);
713 key_point = EC_POINT_new(ec_group);
714 VerifyOrExit(key_point != nullptr, error = CHIP_ERROR_INTERNAL);
716 result = EC_POINT_oct2point(ec_group, key_point, Uint8::to_const_uchar(*this), Length(), nullptr);
717 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
719 ec_key = EC_KEY_new_by_curve_name(nid);
720 VerifyOrExit(ec_key != nullptr, error = CHIP_ERROR_INTERNAL);
722 result = EC_KEY_set_public_key(ec_key, key_point);
723 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
725 result = EC_KEY_check_key(ec_key);
726 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
728 // The cast for length arguments is safe because values are small enough to fit.
729 result = ECDSA_verify(0, hash, static_cast<int>(hash_length), Uint8::to_const_uchar(signature),
730 static_cast<int>(signature.Length()), ec_key);
731 VerifyOrExit(result == 1, error = CHIP_ERROR_INVALID_SIGNATURE);
732 error = CHIP_NO_ERROR;
736 if (ec_group != nullptr)
738 EC_GROUP_free(ec_group);
741 if (key_point != nullptr)
743 EC_POINT_clear_free(key_point);
746 if (ec_key != nullptr)
754 // helper function to populate octet key into EVP_PKEY out_evp_pkey. Caller must free out_evp_pkey
755 static CHIP_ERROR _create_evp_key_from_binary_p256_key(const P256PublicKey & key, EVP_PKEY ** out_evp_pkey)
758 CHIP_ERROR error = CHIP_NO_ERROR;
759 EC_KEY * ec_key = nullptr;
761 EC_POINT * point = nullptr;
762 EC_GROUP * group = nullptr;
765 VerifyOrExit(*out_evp_pkey == nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
767 nid = _nidForCurve(MapECName(key.Type()));
768 VerifyOrExit(nid != NID_undef, error = CHIP_ERROR_INTERNAL);
770 ec_key = EC_KEY_new_by_curve_name(nid);
771 VerifyOrExit(ec_key != nullptr, error = CHIP_ERROR_INTERNAL);
773 group = EC_GROUP_new_by_curve_name(nid);
774 VerifyOrExit(group != nullptr, error = CHIP_ERROR_INTERNAL);
776 point = EC_POINT_new(group);
777 VerifyOrExit(point != nullptr, error = CHIP_ERROR_INTERNAL);
779 result = EC_POINT_oct2point(group, point, Uint8::to_const_uchar(key), key.Length(), nullptr);
780 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
782 result = EC_KEY_set_public_key(ec_key, point);
784 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
786 *out_evp_pkey = EVP_PKEY_new();
787 VerifyOrExit(*out_evp_pkey != nullptr, error = CHIP_ERROR_INTERNAL);
789 result = EVP_PKEY_set1_EC_KEY(*out_evp_pkey, ec_key);
790 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
793 if (ec_key != nullptr)
799 if (error != CHIP_NO_ERROR && *out_evp_pkey)
801 EVP_PKEY_free(*out_evp_pkey);
802 out_evp_pkey = nullptr;
805 if (point != nullptr)
807 EC_POINT_free(point);
811 if (group != nullptr)
813 EC_GROUP_free(group);
820 CHIP_ERROR P256Keypair::ECDH_derive_secret(const P256PublicKey & remote_public_key, P256ECDHDerivedSecret & out_secret) const
823 CHIP_ERROR error = CHIP_NO_ERROR;
825 EVP_PKEY * local_key = nullptr;
826 EVP_PKEY * remote_key = nullptr;
828 EVP_PKEY_CTX * context = nullptr;
829 size_t out_buf_length = 0;
831 EC_KEY * ec_key = EC_KEY_dup(to_const_EC_KEY(&mKeypair));
832 VerifyOrExit(ec_key != nullptr, error = CHIP_ERROR_INTERNAL);
834 VerifyOrExit(mInitialized, error = CHIP_ERROR_INCORRECT_STATE);
836 local_key = EVP_PKEY_new();
837 VerifyOrExit(local_key != nullptr, error = CHIP_ERROR_INTERNAL);
839 result = EVP_PKEY_set1_EC_KEY(local_key, ec_key);
840 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
842 error = _create_evp_key_from_binary_p256_key(remote_public_key, &remote_key);
843 SuccessOrExit(error);
845 context = EVP_PKEY_CTX_new(local_key, nullptr);
846 VerifyOrExit(context != nullptr, error = CHIP_ERROR_INTERNAL);
848 result = EVP_PKEY_derive_init(context);
849 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
851 result = EVP_PKEY_derive_set_peer(context, remote_key);
852 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
854 out_buf_length = (out_secret.Length() == 0) ? out_secret.Capacity() : out_secret.Length();
855 result = EVP_PKEY_derive(context, Uint8::to_uchar(out_secret), &out_buf_length);
856 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
857 SuccessOrExit(out_secret.SetLength(out_buf_length));
860 if (ec_key != nullptr)
866 if (local_key != nullptr)
868 EVP_PKEY_free(local_key);
872 if (remote_key != nullptr)
874 EVP_PKEY_free(remote_key);
875 remote_key = nullptr;
878 if (context != nullptr)
880 EVP_PKEY_CTX_free(context);
888 void ClearSecretData(uint8_t * buf, uint32_t len)
893 CHIP_ERROR P256Keypair::Initialize()
896 CHIP_ERROR error = CHIP_NO_ERROR;
899 EC_KEY * ec_key = nullptr;
900 EC_GROUP * group = nullptr;
901 ECName curve = MapECName(mPublicKey.Type());
903 VerifyOrExit(curve == MapECName(mPublicKey.Type()), error = CHIP_ERROR_INVALID_ARGUMENT);
905 nid = _nidForCurve(curve);
906 VerifyOrExit(nid != NID_undef, error = CHIP_ERROR_INVALID_ARGUMENT);
908 ec_key = EC_KEY_new_by_curve_name(nid);
909 VerifyOrExit(ec_key != nullptr, error = CHIP_ERROR_INTERNAL);
911 group = EC_GROUP_new_by_curve_name(nid);
912 VerifyOrExit(group != nullptr, error = CHIP_ERROR_INTERNAL);
914 result = EC_KEY_generate_key(ec_key);
915 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
918 size_t pubkey_size = 0;
919 const EC_POINT * pubkey_ecp = EC_KEY_get0_public_key(ec_key);
920 VerifyOrExit(pubkey_ecp != nullptr, error = CHIP_ERROR_INTERNAL);
922 pubkey_size = EC_POINT_point2oct(group, pubkey_ecp, POINT_CONVERSION_UNCOMPRESSED, Uint8::to_uchar(mPublicKey),
923 mPublicKey.Length(), nullptr);
924 pubkey_ecp = nullptr;
926 VerifyOrExit(pubkey_size == mPublicKey.Length(), error = CHIP_ERROR_INTERNAL);
929 from_EC_KEY(ec_key, &mKeypair);
934 if (ec_key != nullptr)
940 if (group != nullptr)
942 EC_GROUP_free(group);
950 CHIP_ERROR P256Keypair::Serialize(P256SerializedKeypair & output)
952 CHIP_ERROR error = CHIP_NO_ERROR;
954 const EC_KEY * ec_key = to_const_EC_KEY(&mKeypair);
955 uint8_t privkey[kP256_PrivateKey_Length];
957 int privkey_size = 0;
958 const BIGNUM * privkey_bn = EC_KEY_get0_private_key(ec_key);
959 VerifyOrExit(privkey_bn != nullptr, error = CHIP_ERROR_INTERNAL);
961 privkey_size = BN_bn2binpad(privkey_bn, privkey, sizeof(privkey));
962 privkey_bn = nullptr;
964 VerifyOrExit(privkey_size > 0, error = CHIP_ERROR_INTERNAL);
965 VerifyOrExit((size_t) privkey_size == sizeof(privkey), error = CHIP_ERROR_INTERNAL);
968 size_t len = output.Length() == 0 ? output.Capacity() : output.Length();
969 Encoding::BufferWriter bbuf(output, len);
970 bbuf.Put(mPublicKey, mPublicKey.Length());
971 bbuf.Put(privkey, sizeof(privkey));
972 VerifyOrExit(bbuf.Fit(), error = CHIP_ERROR_NO_MEMORY);
973 output.SetLength(bbuf.Needed());
977 memset(privkey, 0, sizeof(privkey));
982 CHIP_ERROR P256Keypair::Deserialize(P256SerializedKeypair & input)
984 Encoding::BufferWriter bbuf(mPublicKey, mPublicKey.Length());
986 BIGNUM * pvt_key = nullptr;
987 EC_GROUP * group = nullptr;
988 EC_POINT * key_point = nullptr;
990 EC_KEY * ec_key = nullptr;
991 ECName curve = MapECName(mPublicKey.Type());
994 CHIP_ERROR error = CHIP_NO_ERROR;
998 const uint8_t * privkey = Uint8::to_const_uchar(input) + mPublicKey.Length();
1000 VerifyOrExit(input.Length() == mPublicKey.Length() + kP256_PrivateKey_Length, error = CHIP_ERROR_INVALID_ARGUMENT);
1001 bbuf.Put(input, mPublicKey.Length());
1002 VerifyOrExit(bbuf.Fit(), error = CHIP_ERROR_NO_MEMORY);
1004 nid = _nidForCurve(curve);
1005 VerifyOrExit(nid != NID_undef, error = CHIP_ERROR_INVALID_ARGUMENT);
1007 group = EC_GROUP_new_by_curve_name(nid);
1008 VerifyOrExit(group != nullptr, error = CHIP_ERROR_INTERNAL);
1010 key_point = EC_POINT_new(group);
1011 VerifyOrExit(key_point != nullptr, error = CHIP_ERROR_INTERNAL);
1013 result = EC_POINT_oct2point(group, key_point, Uint8::to_const_uchar(mPublicKey), mPublicKey.Length(), nullptr);
1014 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
1016 ec_key = EC_KEY_new_by_curve_name(nid);
1017 VerifyOrExit(ec_key != nullptr, error = CHIP_ERROR_INTERNAL);
1019 result = EC_KEY_set_public_key(ec_key, key_point);
1020 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
1022 pvt_key = BN_bin2bn(privkey, kP256_PrivateKey_Length, nullptr);
1023 VerifyOrExit(pvt_key != nullptr, error = CHIP_ERROR_INTERNAL);
1025 result = EC_KEY_set_private_key(ec_key, pvt_key);
1026 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
1028 from_EC_KEY(ec_key, &mKeypair);
1029 mInitialized = true;
1034 if (ec_key != nullptr)
1036 EC_KEY_free(ec_key);
1040 if (group != nullptr)
1042 EC_GROUP_free(group);
1046 if (pvt_key != nullptr)
1052 if (key_point != nullptr)
1054 EC_POINT_free(key_point);
1055 key_point = nullptr;
1061 P256Keypair::~P256Keypair()
1065 EC_KEY * ec_key = to_EC_KEY(&mKeypair);
1066 EC_KEY_free(ec_key);
1070 CHIP_ERROR P256Keypair::NewCertificateSigningRequest(uint8_t * out_csr, size_t & csr_length)
1073 CHIP_ERROR error = CHIP_NO_ERROR;
1076 X509_REQ * x509_req = X509_REQ_new();
1077 EVP_PKEY * evp_pkey = nullptr;
1079 EC_KEY * ec_key = to_EC_KEY(&mKeypair);
1081 BIO * bioMem = nullptr;
1082 BUF_MEM * bptr = nullptr;
1084 VerifyOrExit(mInitialized, error = CHIP_ERROR_INCORRECT_STATE);
1086 result = X509_REQ_set_version(x509_req, 0);
1087 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
1089 result = EC_KEY_check_key(ec_key);
1090 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
1092 evp_pkey = EVP_PKEY_new();
1093 VerifyOrExit(evp_pkey != nullptr, error = CHIP_ERROR_INTERNAL);
1095 result = EVP_PKEY_set1_EC_KEY(evp_pkey, ec_key);
1096 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
1098 result = X509_REQ_set_pubkey(x509_req, evp_pkey);
1099 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
1101 result = X509_REQ_sign(x509_req, evp_pkey, EVP_sha256());
1102 VerifyOrExit(result > 0, error = CHIP_ERROR_INTERNAL);
1104 bioMem = BIO_new(BIO_s_mem());
1105 VerifyOrExit(bioMem != nullptr, error = CHIP_ERROR_INTERNAL);
1107 result = PEM_write_bio_X509_REQ(bioMem, x509_req);
1108 VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
1110 BIO_get_mem_ptr(bioMem, &bptr);
1112 size_t input_length = csr_length;
1113 csr_length = bptr->length;
1114 VerifyOrExit(bptr->length <= input_length, error = CHIP_ERROR_BUFFER_TOO_SMALL);
1115 VerifyOrExit(CanCastTo<int>(bptr->length), error = CHIP_ERROR_INTERNAL);
1116 memset(out_csr, 0, input_length);
1119 BIO_read(bioMem, out_csr, static_cast<int>(bptr->length));
1124 if (evp_pkey != nullptr)
1126 EVP_PKEY_free(evp_pkey);
1130 if (bioMem != nullptr)
1136 X509_REQ_free(x509_req);
1142 #define init_point(_point_) \
1145 _point_ = EC_POINT_new(context->curve); \
1146 VerifyOrExit(_point_ != nullptr, error = CHIP_ERROR_INTERNAL); \
1149 #define init_bn(_bn_) \
1153 VerifyOrExit(_bn_ != nullptr, error = CHIP_ERROR_INTERNAL); \
1156 #define free_point(_point_) \
1159 if (_point_ != nullptr) \
1161 EC_POINT_clear_free(static_cast<EC_POINT *>(_point_)); \
1165 #define free_bn(_bn_) \
1168 if (_bn_ != nullptr) \
1170 BN_clear_free(static_cast<BIGNUM *>(_bn_)); \
1174 typedef struct Spake2p_Context
1178 const EVP_MD * md_info;
1181 static inline Spake2p_Context * to_inner_spake2p_context(Spake2pOpaqueContext * context)
1183 return SafePointerCast<Spake2p_Context *>(context);
1186 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::InitInternal()
1188 CHIP_ERROR error = CHIP_ERROR_INTERNAL;
1189 int error_openssl = 0;
1191 Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
1193 context->curve = nullptr;
1194 context->bn_ctx = nullptr;
1195 context->md_info = nullptr;
1197 context->curve = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
1198 VerifyOrExit(context->curve != nullptr, error = CHIP_ERROR_INTERNAL);
1200 G = EC_GROUP_get0_generator(context->curve);
1201 VerifyOrExit(G != nullptr, error = CHIP_ERROR_INTERNAL);
1203 context->bn_ctx = BN_CTX_secure_new();
1204 VerifyOrExit(context->bn_ctx != nullptr, error = CHIP_ERROR_INTERNAL);
1206 context->md_info = EVP_sha256();
1207 VerifyOrExit(context->md_info != nullptr, error = CHIP_ERROR_INTERNAL);
1222 error_openssl = EC_GROUP_get_order(context->curve, static_cast<BIGNUM *>(order), context->bn_ctx);
1223 VerifyOrExit(error_openssl == 1, error = CHIP_ERROR_INTERNAL);
1225 error = CHIP_NO_ERROR;
1230 void Spake2p_P256_SHA256_HKDF_HMAC::FreeImpl()
1232 Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
1234 if (context->curve != nullptr)
1236 EC_GROUP_clear_free(context->curve);
1239 if (context->bn_ctx != nullptr)
1241 BN_CTX_free(context->bn_ctx);
1258 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::Mac(const uint8_t * key, size_t key_len, const uint8_t * in, size_t in_len, uint8_t * out)
1260 CHIP_ERROR error = CHIP_ERROR_INTERNAL;
1261 int error_openssl = 0;
1262 unsigned int mac_out_len = 0;
1264 Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
1266 HMAC_CTX * mac_ctx = HMAC_CTX_new();
1267 VerifyOrExit(mac_ctx != nullptr, error = CHIP_ERROR_INTERNAL);
1269 VerifyOrExit(CanCastTo<int>(key_len), error = CHIP_ERROR_INTERNAL);
1270 error_openssl = HMAC_Init_ex(mac_ctx, Uint8::to_const_uchar(key), static_cast<int>(key_len), context->md_info, nullptr);
1271 VerifyOrExit(error_openssl == 1, error = CHIP_ERROR_INTERNAL);
1273 error_openssl = HMAC_Update(mac_ctx, Uint8::to_const_uchar(in), in_len);
1274 VerifyOrExit(error_openssl == 1, error = CHIP_ERROR_INTERNAL);
1276 VerifyOrExit(CanCastTo<int>(hash_size), error = CHIP_ERROR_INTERNAL);
1277 mac_out_len = static_cast<unsigned int>(hash_size);
1278 error_openssl = HMAC_Final(mac_ctx, Uint8::to_uchar(out), &mac_out_len);
1279 VerifyOrExit(error_openssl == 1, error = CHIP_ERROR_INTERNAL);
1281 error = CHIP_NO_ERROR;
1283 HMAC_CTX_free(mac_ctx);
1287 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::MacVerify(const uint8_t * key, size_t key_len, const uint8_t * mac, size_t mac_len,
1288 const uint8_t * in, size_t in_len)
1290 CHIP_ERROR error = CHIP_ERROR_INTERNAL;
1291 VerifyOrExit(mac_len == kSHA256_Hash_Length, error = CHIP_ERROR_INVALID_ARGUMENT);
1293 uint8_t computed_mac[kSHA256_Hash_Length];
1294 error = Mac(key, key_len, in, in_len, computed_mac);
1295 VerifyOrExit(error == CHIP_NO_ERROR, error = CHIP_ERROR_INTERNAL);
1297 VerifyOrExit(CRYPTO_memcmp(mac, computed_mac, mac_len) == 0, error = CHIP_ERROR_INTERNAL);
1299 error = CHIP_NO_ERROR;
1304 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::FELoad(const uint8_t * in, size_t in_len, void * fe)
1306 CHIP_ERROR error = CHIP_ERROR_INTERNAL;
1307 int error_openssl = 0;
1308 BIGNUM * bn_fe = static_cast<BIGNUM *>(fe);
1310 Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
1312 VerifyOrExit(CanCastTo<int>(in_len), error = CHIP_ERROR_INTERNAL);
1313 BN_bin2bn(Uint8::to_const_uchar(in), static_cast<int>(in_len), bn_fe);
1314 error_openssl = BN_mod(bn_fe, bn_fe, (BIGNUM *) order, context->bn_ctx);
1315 VerifyOrExit(error_openssl == 1, error = CHIP_ERROR_INTERNAL);
1317 error = CHIP_NO_ERROR;
1322 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::FEWrite(const void * fe, uint8_t * out, size_t out_len)
1324 CHIP_ERROR error = CHIP_ERROR_INTERNAL;
1326 VerifyOrExit(CanCastTo<int>(out_len), error = CHIP_ERROR_INTERNAL);
1327 bn_out_len = BN_bn2binpad(static_cast<const BIGNUM *>(fe), Uint8::to_uchar(out), static_cast<int>(out_len));
1329 VerifyOrExit(bn_out_len == static_cast<int>(out_len), error = CHIP_ERROR_INTERNAL);
1331 error = CHIP_NO_ERROR;
1336 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::FEGenerate(void * fe)
1338 CHIP_ERROR error = CHIP_ERROR_INTERNAL;
1339 int error_openssl = 0;
1341 error_openssl = BN_rand_range(static_cast<BIGNUM *>(fe), static_cast<BIGNUM *>(order));
1342 VerifyOrExit(error_openssl == 1, error = CHIP_ERROR_INTERNAL);
1344 error = CHIP_NO_ERROR;
1349 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::FEMul(void * fer, const void * fe1, const void * fe2)
1351 CHIP_ERROR error = CHIP_ERROR_INTERNAL;
1352 int error_openssl = 0;
1354 Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
1356 error_openssl = BN_mod_mul(static_cast<BIGNUM *>(fer), static_cast<const BIGNUM *>(fe1), static_cast<const BIGNUM *>(fe2),
1357 static_cast<BIGNUM *>(order), context->bn_ctx);
1358 VerifyOrExit(error_openssl == 1, error = CHIP_ERROR_INTERNAL);
1360 error = CHIP_NO_ERROR;
1365 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointLoad(const uint8_t * in, size_t in_len, void * R)
1367 CHIP_ERROR error = CHIP_ERROR_INTERNAL;
1368 int error_openssl = 0;
1370 Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
1373 EC_POINT_oct2point(context->curve, static_cast<EC_POINT *>(R), Uint8::to_const_uchar(in), in_len, context->bn_ctx);
1374 VerifyOrExit(error_openssl == 1, error = CHIP_ERROR_INTERNAL);
1376 error = CHIP_NO_ERROR;
1381 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointWrite(const void * R, uint8_t * out, size_t out_len)
1383 CHIP_ERROR error = CHIP_ERROR_INTERNAL;
1384 Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
1386 size_t ec_out_len = EC_POINT_point2oct(context->curve, static_cast<const EC_POINT *>(R), POINT_CONVERSION_UNCOMPRESSED,
1387 Uint8::to_uchar(out), out_len, context->bn_ctx);
1388 VerifyOrExit(ec_out_len == out_len, error = CHIP_ERROR_INTERNAL);
1390 error = CHIP_NO_ERROR;
1395 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointMul(void * R, const void * P1, const void * fe1)
1397 CHIP_ERROR error = CHIP_ERROR_INTERNAL;
1398 int error_openssl = 0;
1400 Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
1402 error_openssl = EC_POINT_mul(context->curve, static_cast<EC_POINT *>(R), nullptr, static_cast<const EC_POINT *>(P1),
1403 static_cast<const BIGNUM *>(fe1), context->bn_ctx);
1404 VerifyOrExit(error_openssl == 1, error = CHIP_ERROR_INTERNAL);
1406 error = CHIP_NO_ERROR;
1411 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointAddMul(void * R, const void * P1, const void * fe1, const void * P2,
1414 CHIP_ERROR error = CHIP_ERROR_INTERNAL;
1415 int error_openssl = 0;
1416 EC_POINT * scratch = nullptr;
1418 Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
1420 scratch = EC_POINT_new(context->curve);
1421 VerifyOrExit(scratch != nullptr, error = CHIP_ERROR_INTERNAL);
1423 error = PointMul(scratch, P1, fe1);
1424 VerifyOrExit(error == CHIP_NO_ERROR, error = CHIP_ERROR_INTERNAL);
1426 error = PointMul(R, P2, fe2);
1427 VerifyOrExit(error == CHIP_NO_ERROR, error = CHIP_ERROR_INTERNAL);
1429 error_openssl = EC_POINT_add(context->curve, static_cast<EC_POINT *>(R), static_cast<EC_POINT *>(R),
1430 static_cast<const EC_POINT *>(scratch), context->bn_ctx);
1431 VerifyOrExit(error_openssl == 1, error = CHIP_ERROR_INTERNAL);
1433 error = CHIP_NO_ERROR;
1435 EC_POINT_clear_free(scratch);
1439 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointInvert(void * R)
1441 CHIP_ERROR error = CHIP_ERROR_INTERNAL;
1442 int error_openssl = 0;
1444 Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
1446 error_openssl = EC_POINT_invert(context->curve, static_cast<EC_POINT *>(R), context->bn_ctx);
1447 VerifyOrExit(error_openssl == 1, error = CHIP_ERROR_INTERNAL);
1449 error = CHIP_NO_ERROR;
1454 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointCofactorMul(void * R)
1456 // Cofactor on P256 is 1 so this is a NOP
1457 return CHIP_NO_ERROR;
1460 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::ComputeL(uint8_t * Lout, size_t * L_len, const uint8_t * w1in, size_t w1in_len)
1462 CHIP_ERROR error = CHIP_ERROR_INTERNAL;
1463 int error_openssl = 0;
1464 BIGNUM * w1_bn = nullptr;
1465 EC_POINT * Lout_point = nullptr;
1467 Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
1470 VerifyOrExit(w1_bn != nullptr, error = CHIP_ERROR_INTERNAL);
1472 Lout_point = EC_POINT_new(context->curve);
1473 VerifyOrExit(Lout_point != nullptr, error = CHIP_ERROR_INTERNAL);
1475 VerifyOrExit(CanCastTo<int>(w1in_len), error = CHIP_ERROR_INTERNAL);
1476 BN_bin2bn(Uint8::to_const_uchar(w1in), static_cast<int>(w1in_len), w1_bn);
1477 error_openssl = BN_mod(w1_bn, w1_bn, (BIGNUM *) order, context->bn_ctx);
1478 VerifyOrExit(error_openssl == 1, error = CHIP_ERROR_INTERNAL);
1480 error_openssl = EC_POINT_mul(context->curve, Lout_point, w1_bn, nullptr, nullptr, context->bn_ctx);
1481 VerifyOrExit(error_openssl == 1, error = CHIP_ERROR_INTERNAL);
1483 *L_len = EC_POINT_point2oct(context->curve, Lout_point, POINT_CONVERSION_UNCOMPRESSED, Uint8::to_uchar(Lout), *L_len,
1485 VerifyOrExit(*L_len != 0, error = CHIP_ERROR_INTERNAL);
1487 error = CHIP_NO_ERROR;
1489 BN_clear_free(w1_bn);
1490 EC_POINT_clear_free(Lout_point);
1495 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointIsValid(void * R)
1497 CHIP_ERROR error = CHIP_ERROR_INTERNAL;
1498 int error_openssl = 0;
1500 Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
1502 error_openssl = EC_POINT_is_on_curve(context->curve, static_cast<EC_POINT *>(R), context->bn_ctx);
1503 VerifyOrExit(error_openssl == 1, error = CHIP_ERROR_INTERNAL);
1505 error = CHIP_NO_ERROR;
1510 } // namespace Crypto