Matter SDK Coverage Report
Current view: top level - crypto - P256KeyPairOpenSSL.cpp (source / functions) Coverage Total Hit
Test: SHA:3f9cd168e84cd831b7699126f5296f5c5498690f Lines: 97.7 % 305 298
Test Date: 2026-04-27 19:52:19 Functions: 93.3 % 15 14

            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
        

Generated by: LCOV version 2.0-1