Matter SDK Coverage Report
Current view: top level - crypto - P256KeyPairOpenSSL.cpp (source / functions) Coverage Total Hit
Test: SHA:2a48c1efeab1c0f76f3adb3a0940b0f7de706453 Lines: 97.3 % 263 256
Test Date: 2026-01-31 08:14:20 Functions: 92.3 % 13 12

            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 <type_traits>
      27              : 
      28              : #if CHIP_CRYPTO_BORINGSSL
      29              : #include <openssl/aead.h>
      30              : #endif // CHIP_CRYPTO_BORINGSSL
      31              : 
      32              : #include <openssl/err.h>
      33              : #include <openssl/evp.h>
      34              : 
      35              : #include <lib/core/CHIPSafeCasts.h>
      36              : #include <lib/support/BufferWriter.h>
      37              : #include <lib/support/BytesToHex.h>
      38              : #include <lib/support/CodeUtils.h>
      39              : #include <lib/support/SafeInt.h>
      40              : 
      41              : namespace chip {
      42              : namespace Crypto {
      43              : 
      44         2258 : static inline void from_EC_KEY(EC_KEY * key, P256KeypairContext * context)
      45              : {
      46         2258 :     *SafePointerCast<EC_KEY **>(context) = key;
      47         2258 : }
      48              : 
      49         2819 : static inline EC_KEY * to_EC_KEY(P256KeypairContext * context)
      50              : {
      51         2819 :     return *SafePointerCast<EC_KEY **>(context);
      52              : }
      53              : 
      54          914 : static inline const EC_KEY * to_const_EC_KEY(const P256KeypairContext * context)
      55              : {
      56          914 :     return *SafePointerCast<const EC_KEY * const *>(context);
      57              : }
      58              : 
      59              : // helper function to populate octet key into EVP_PKEY out_evp_pkey. Caller must free out_evp_pkey
      60           26 : static CHIP_ERROR _create_evp_key_from_binary_p256_key(const P256PublicKey & key, EVP_PKEY ** out_evp_pkey)
      61              : {
      62              : 
      63           26 :     CHIP_ERROR error = CHIP_NO_ERROR;
      64           26 :     EC_KEY * ec_key  = nullptr;
      65           26 :     int result       = -1;
      66           26 :     EC_POINT * point = nullptr;
      67           26 :     EC_GROUP * group = nullptr;
      68           26 :     int nid          = NID_undef;
      69              : 
      70           26 :     VerifyOrExit(*out_evp_pkey == nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
      71              : 
      72           26 :     nid = GetNidForCurve(MapECName(key.Type()));
      73           26 :     VerifyOrExit(nid != NID_undef, error = CHIP_ERROR_INTERNAL);
      74              : 
      75           26 :     ec_key = EC_KEY_new_by_curve_name(nid);
      76           26 :     VerifyOrExit(ec_key != nullptr, error = CHIP_ERROR_INTERNAL);
      77              : 
      78           26 :     group = EC_GROUP_new_by_curve_name(nid);
      79           26 :     VerifyOrExit(group != nullptr, error = CHIP_ERROR_INTERNAL);
      80              : 
      81           26 :     point = EC_POINT_new(group);
      82           26 :     VerifyOrExit(point != nullptr, error = CHIP_ERROR_INTERNAL);
      83              : 
      84           26 :     result = EC_POINT_oct2point(group, point, Uint8::to_const_uchar(key), key.Length(), nullptr);
      85           26 :     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
      86              : 
      87           26 :     result = EC_KEY_set_public_key(ec_key, point);
      88              : 
      89           26 :     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
      90              : 
      91           26 :     *out_evp_pkey = EVP_PKEY_new();
      92           26 :     VerifyOrExit(*out_evp_pkey != nullptr, error = CHIP_ERROR_INTERNAL);
      93              : 
      94           26 :     result = EVP_PKEY_set1_EC_KEY(*out_evp_pkey, ec_key);
      95           26 :     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
      96              : 
      97           26 : exit:
      98           26 :     if (ec_key != nullptr)
      99              :     {
     100           26 :         EC_KEY_free(ec_key);
     101           26 :         ec_key = nullptr;
     102              :     }
     103              : 
     104           52 :     if (error != CHIP_NO_ERROR && *out_evp_pkey)
     105              :     {
     106            0 :         EVP_PKEY_free(*out_evp_pkey);
     107            0 :         out_evp_pkey = nullptr;
     108              :     }
     109              : 
     110           26 :     if (point != nullptr)
     111              :     {
     112           26 :         EC_POINT_free(point);
     113           26 :         point = nullptr;
     114              :     }
     115              : 
     116           26 :     if (group != nullptr)
     117              :     {
     118           26 :         EC_GROUP_free(group);
     119           26 :         group = nullptr;
     120              :     }
     121              : 
     122           26 :     return error;
     123              : }
     124              : 
     125          523 : CHIP_ERROR P256Keypair::ECDSA_sign_msg(const uint8_t * msg, const size_t msg_length, P256ECDSASignature & out_signature) const
     126              : {
     127          523 :     CHIP_ERROR error = CHIP_NO_ERROR;
     128          523 :     int nid          = NID_undef;
     129          523 :     EC_KEY * ec_key  = nullptr;
     130          523 :     ECDSA_SIG * sig  = nullptr;
     131          523 :     const BIGNUM * r = nullptr;
     132          523 :     const BIGNUM * s = nullptr;
     133              : 
     134          523 :     VerifyOrReturnError((msg != nullptr) && (msg_length > 0), CHIP_ERROR_INVALID_ARGUMENT);
     135              : 
     136              :     uint8_t digest[kSHA256_Hash_Length];
     137          521 :     memset(&digest[0], 0, sizeof(digest));
     138              : 
     139          521 :     ReturnErrorOnFailure(Hash_SHA256(msg, msg_length, &digest[0]));
     140              : 
     141          521 :     ERR_clear_error();
     142              : 
     143              :     static_assert(P256ECDSASignature::Capacity() >= kP256_ECDSA_Signature_Length_Raw, "P256ECDSASignature must be large enough");
     144          521 :     VerifyOrExit(mInitialized, error = CHIP_ERROR_UNINITIALIZED);
     145          521 :     nid = GetNidForCurve(MapECName(mPublicKey.Type()));
     146          521 :     VerifyOrExit(nid != NID_undef, error = CHIP_ERROR_INVALID_ARGUMENT);
     147              : 
     148          521 :     ec_key = to_EC_KEY(&mKeypair);
     149          521 :     VerifyOrExit(ec_key != nullptr, error = CHIP_ERROR_INTERNAL);
     150              : 
     151          521 :     sig = ECDSA_do_sign(Uint8::to_const_uchar(&digest[0]), static_cast<boringssl_size_t_openssl_int>(sizeof(digest)), ec_key);
     152          521 :     VerifyOrExit(sig != nullptr, error = CHIP_ERROR_INTERNAL);
     153          521 :     ECDSA_SIG_get0(sig, &r, &s);
     154          521 :     VerifyOrExit((r != nullptr) && (s != nullptr), error = CHIP_ERROR_INTERNAL);
     155          521 :     VerifyOrExit(CanCastTo<size_t>(BN_num_bytes(r)) && CanCastTo<size_t>(BN_num_bytes(s)), error = CHIP_ERROR_INTERNAL);
     156          521 :     VerifyOrExit((static_cast<size_t>(BN_num_bytes(r)) <= kP256_FE_Length) &&
     157              :                      (static_cast<size_t>(BN_num_bytes(s)) <= kP256_FE_Length),
     158              :                  error = CHIP_ERROR_INTERNAL);
     159              : 
     160              :     // Concatenate r and s to output. Sizes were checked above.
     161         1042 :     VerifyOrExit(out_signature.SetLength(kP256_ECDSA_Signature_Length_Raw) == CHIP_NO_ERROR, error = CHIP_ERROR_INTERNAL);
     162          521 :     VerifyOrExit(BN_bn2binpad(r, out_signature.Bytes() + 0u, kP256_FE_Length) == kP256_FE_Length, error = CHIP_ERROR_INTERNAL);
     163          521 :     VerifyOrExit(BN_bn2binpad(s, out_signature.Bytes() + kP256_FE_Length, kP256_FE_Length) == kP256_FE_Length,
     164              :                  error = CHIP_ERROR_INTERNAL);
     165              : 
     166          521 : exit:
     167          521 :     if (sig != nullptr)
     168              :     {
     169              :         // SIG owns the memory of r, s
     170          521 :         ECDSA_SIG_free(sig);
     171              :     }
     172              : 
     173         1042 :     if (error != CHIP_NO_ERROR)
     174              :     {
     175            0 :         SSLErrorLog();
     176              :     }
     177              : 
     178          521 :     return error;
     179              : }
     180              : 
     181           26 : CHIP_ERROR P256Keypair::ECDH_derive_secret(const P256PublicKey & remote_public_key, P256ECDHDerivedSecret & out_secret) const
     182              : {
     183           26 :     ERR_clear_error();
     184           26 :     CHIP_ERROR error      = CHIP_NO_ERROR;
     185           26 :     int result            = -1;
     186           26 :     EVP_PKEY * local_key  = nullptr;
     187           26 :     EVP_PKEY * remote_key = nullptr;
     188              : 
     189           26 :     EVP_PKEY_CTX * context = nullptr;
     190           26 :     size_t out_buf_length  = 0;
     191              : 
     192           26 :     EC_KEY * ec_key = EC_KEY_dup(to_const_EC_KEY(&mKeypair));
     193           26 :     VerifyOrExit(ec_key != nullptr, error = CHIP_ERROR_INTERNAL);
     194              : 
     195           26 :     VerifyOrExit(mInitialized, error = CHIP_ERROR_UNINITIALIZED);
     196              : 
     197           26 :     local_key = EVP_PKEY_new();
     198           26 :     VerifyOrExit(local_key != nullptr, error = CHIP_ERROR_INTERNAL);
     199              : 
     200           26 :     result = EVP_PKEY_set1_EC_KEY(local_key, ec_key);
     201           26 :     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
     202              : 
     203           26 :     error = _create_evp_key_from_binary_p256_key(remote_public_key, &remote_key);
     204           26 :     SuccessOrExit(error);
     205              : 
     206           26 :     context = EVP_PKEY_CTX_new(local_key, nullptr);
     207           26 :     VerifyOrExit(context != nullptr, error = CHIP_ERROR_INTERNAL);
     208              : 
     209           26 :     result = EVP_PKEY_derive_init(context);
     210           26 :     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
     211              : 
     212           26 :     result = EVP_PKEY_derive_set_peer(context, remote_key);
     213           26 :     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
     214              : 
     215           26 :     out_buf_length = (out_secret.Length() == 0) ? out_secret.Capacity() : out_secret.Length();
     216           26 :     result         = EVP_PKEY_derive(context, out_secret.Bytes(), &out_buf_length);
     217           26 :     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
     218           26 :     SuccessOrExit(error = out_secret.SetLength(out_buf_length));
     219              : 
     220           26 : exit:
     221           26 :     if (ec_key != nullptr)
     222              :     {
     223           26 :         EC_KEY_free(ec_key);
     224           26 :         ec_key = nullptr;
     225              :     }
     226              : 
     227           26 :     if (local_key != nullptr)
     228              :     {
     229           26 :         EVP_PKEY_free(local_key);
     230           26 :         local_key = nullptr;
     231              :     }
     232              : 
     233           26 :     if (remote_key != nullptr)
     234              :     {
     235           26 :         EVP_PKEY_free(remote_key);
     236           26 :         remote_key = nullptr;
     237              :     }
     238              : 
     239           26 :     if (context != nullptr)
     240              :     {
     241           26 :         EVP_PKEY_CTX_free(context);
     242           26 :         context = nullptr;
     243              :     }
     244              : 
     245           26 :     SSLErrorLog();
     246           26 :     return error;
     247              : }
     248              : 
     249          191 : CHIP_ERROR P256Keypair::Initialize(ECPKeyTarget key_target)
     250              : {
     251          191 :     ERR_clear_error();
     252              : 
     253          191 :     Clear();
     254              : 
     255          191 :     CHIP_ERROR error = CHIP_NO_ERROR;
     256          191 :     int result       = 0;
     257          191 :     EC_KEY * ec_key  = nullptr;
     258          191 :     ECName curve     = MapECName(mPublicKey.Type());
     259              : 
     260          191 :     int nid = GetNidForCurve(curve);
     261          191 :     VerifyOrExit(nid != NID_undef, error = CHIP_ERROR_INVALID_ARGUMENT);
     262              : 
     263          191 :     ec_key = EC_KEY_new_by_curve_name(nid);
     264          191 :     VerifyOrExit(ec_key != nullptr, error = CHIP_ERROR_INTERNAL);
     265              : 
     266          191 :     result = EC_KEY_generate_key(ec_key);
     267          191 :     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
     268              : 
     269          191 :     error = P256PublicKeyFromECKey(ec_key, mPublicKey);
     270          191 :     SuccessOrExit(error);
     271              : 
     272          191 :     from_EC_KEY(ec_key, &mKeypair);
     273          191 :     mInitialized = true;
     274          191 :     ec_key       = nullptr;
     275              : 
     276          191 : exit:
     277          191 :     if (ec_key != nullptr)
     278              :     {
     279            0 :         EC_KEY_free(ec_key);
     280            0 :         ec_key = nullptr;
     281              :     }
     282              : 
     283          191 :     SSLErrorLog();
     284          191 :     return error;
     285              : }
     286              : 
     287          888 : CHIP_ERROR P256Keypair::Serialize(P256SerializedKeypair & output) const
     288              : {
     289          888 :     CHIP_ERROR error = CHIP_NO_ERROR;
     290              : 
     291          888 :     const EC_KEY * ec_key = to_const_EC_KEY(&mKeypair);
     292              :     uint8_t privkey[kP256_PrivateKey_Length];
     293              : 
     294          888 :     int privkey_size          = 0;
     295          888 :     const BIGNUM * privkey_bn = EC_KEY_get0_private_key(ec_key);
     296          888 :     VerifyOrExit(privkey_bn != nullptr, error = CHIP_ERROR_INTERNAL);
     297              : 
     298          888 :     privkey_size = BN_bn2binpad(privkey_bn, privkey, sizeof(privkey));
     299          888 :     privkey_bn   = nullptr;
     300              : 
     301          888 :     VerifyOrExit(privkey_size > 0, error = CHIP_ERROR_INTERNAL);
     302          888 :     VerifyOrExit((size_t) privkey_size == sizeof(privkey), error = CHIP_ERROR_INTERNAL);
     303              : 
     304              :     {
     305          888 :         size_t len = output.Length() == 0 ? output.Capacity() : output.Length();
     306          888 :         Encoding::BufferWriter bbuf(output.Bytes(), len);
     307          888 :         bbuf.Put(mPublicKey, mPublicKey.Length());
     308          888 :         bbuf.Put(privkey, sizeof(privkey));
     309          888 :         VerifyOrExit(bbuf.Fit(), error = CHIP_ERROR_NO_MEMORY);
     310          888 :         TEMPORARY_RETURN_IGNORED output.SetLength(bbuf.Needed());
     311              :     }
     312              : 
     313          888 : exit:
     314          888 :     ClearSecretData(privkey, sizeof(privkey));
     315          888 :     SSLErrorLog();
     316          888 :     return error;
     317              : }
     318              : 
     319         2068 : CHIP_ERROR P256Keypair::Deserialize(P256SerializedKeypair & input)
     320              : {
     321         2068 :     Encoding::BufferWriter bbuf(mPublicKey, mPublicKey.Length());
     322              : 
     323         2068 :     Clear();
     324              : 
     325         2068 :     BIGNUM * pvt_key     = nullptr;
     326         2068 :     EC_GROUP * group     = nullptr;
     327         2068 :     EC_POINT * key_point = nullptr;
     328              : 
     329         2068 :     EC_KEY * ec_key = nullptr;
     330         2068 :     ECName curve    = MapECName(mPublicKey.Type());
     331              : 
     332         2068 :     ERR_clear_error();
     333         2068 :     CHIP_ERROR error = CHIP_NO_ERROR;
     334         2068 :     int result       = 0;
     335         2068 :     int nid          = NID_undef;
     336              : 
     337         2068 :     const uint8_t * privkey = input.ConstBytes() + mPublicKey.Length();
     338              : 
     339         2068 :     VerifyOrExit(input.Length() == mPublicKey.Length() + kP256_PrivateKey_Length, error = CHIP_ERROR_INVALID_ARGUMENT);
     340         2067 :     bbuf.Put(input.ConstBytes(), mPublicKey.Length());
     341         2067 :     VerifyOrExit(bbuf.Fit(), error = CHIP_ERROR_NO_MEMORY);
     342              : 
     343         2067 :     nid = GetNidForCurve(curve);
     344         2067 :     VerifyOrExit(nid != NID_undef, error = CHIP_ERROR_INVALID_ARGUMENT);
     345              : 
     346         2067 :     group = EC_GROUP_new_by_curve_name(nid);
     347         2067 :     VerifyOrExit(group != nullptr, error = CHIP_ERROR_INTERNAL);
     348              : 
     349         2067 :     key_point = EC_POINT_new(group);
     350         2067 :     VerifyOrExit(key_point != nullptr, error = CHIP_ERROR_INTERNAL);
     351              : 
     352         2067 :     result = EC_POINT_oct2point(group, key_point, Uint8::to_const_uchar(mPublicKey), mPublicKey.Length(), nullptr);
     353         2067 :     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
     354              : 
     355         2067 :     ec_key = EC_KEY_new_by_curve_name(nid);
     356         2067 :     VerifyOrExit(ec_key != nullptr, error = CHIP_ERROR_INTERNAL);
     357              : 
     358         2067 :     result = EC_KEY_set_public_key(ec_key, key_point);
     359         2067 :     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
     360              : 
     361         2067 :     pvt_key = BN_bin2bn(privkey, kP256_PrivateKey_Length, nullptr);
     362         2067 :     VerifyOrExit(pvt_key != nullptr, error = CHIP_ERROR_INTERNAL);
     363              : 
     364         2067 :     result = EC_KEY_set_private_key(ec_key, pvt_key);
     365         2067 :     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
     366              : 
     367         2067 :     from_EC_KEY(ec_key, &mKeypair);
     368         2067 :     mInitialized = true;
     369         2067 :     ec_key       = nullptr;
     370              : 
     371         2068 : exit:
     372         2068 :     if (ec_key != nullptr)
     373              :     {
     374            0 :         EC_KEY_free(ec_key);
     375            0 :         ec_key = nullptr;
     376              :     }
     377              : 
     378         2068 :     if (group != nullptr)
     379              :     {
     380         2067 :         EC_GROUP_free(group);
     381         2067 :         group = nullptr;
     382              :     }
     383              : 
     384         2068 :     if (pvt_key != nullptr)
     385              :     {
     386         2067 :         BN_free(pvt_key);
     387         2067 :         pvt_key = nullptr;
     388              :     }
     389              : 
     390         2068 :     if (key_point != nullptr)
     391              :     {
     392         2067 :         EC_POINT_free(key_point);
     393         2067 :         key_point = nullptr;
     394              :     }
     395         2068 :     SSLErrorLog();
     396         2068 :     return error;
     397              : }
     398              : 
     399         4499 : void P256Keypair::Clear()
     400              : {
     401         4499 :     if (mInitialized)
     402              :     {
     403         2258 :         EC_KEY * ec_key = to_EC_KEY(&mKeypair);
     404         2258 :         EC_KEY_free(ec_key);
     405         2258 :         mInitialized = false;
     406              :     }
     407         4499 : }
     408              : 
     409         2240 : P256Keypair::~P256Keypair()
     410              : {
     411         2240 :     Clear();
     412         2240 : }
     413              : 
     414           40 : CHIP_ERROR P256Keypair::NewCertificateSigningRequest(uint8_t * out_csr, size_t & csr_length) const
     415              : {
     416           40 :     ERR_clear_error();
     417           40 :     CHIP_ERROR error     = CHIP_NO_ERROR;
     418           40 :     int result           = 0;
     419           40 :     int csr_length_local = 0;
     420              : 
     421           40 :     X509_REQ * x509_req = X509_REQ_new();
     422           40 :     EVP_PKEY * evp_pkey = nullptr;
     423              : 
     424           40 :     EC_KEY * ec_key = to_EC_KEY(&mKeypair);
     425              : 
     426           40 :     X509_NAME * subject = X509_NAME_new();
     427           40 :     VerifyOrExit(subject != nullptr, error = CHIP_ERROR_INTERNAL);
     428              : 
     429           40 :     VerifyOrExit(mInitialized, error = CHIP_ERROR_UNINITIALIZED);
     430              : 
     431           40 :     result = X509_REQ_set_version(x509_req, 0);
     432           40 :     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
     433              : 
     434           40 :     result = EC_KEY_check_key(ec_key);
     435           40 :     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
     436              : 
     437           40 :     evp_pkey = EVP_PKEY_new();
     438           40 :     VerifyOrExit(evp_pkey != nullptr, error = CHIP_ERROR_INTERNAL);
     439              : 
     440           40 :     result = EVP_PKEY_set1_EC_KEY(evp_pkey, ec_key);
     441           40 :     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
     442              : 
     443           40 :     result = X509_REQ_set_pubkey(x509_req, evp_pkey);
     444           40 :     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
     445              : 
     446              :     // TODO: mbedTLS CSR parser fails if the subject name is not set (or if empty).
     447              :     //       CHIP Spec doesn't specify the subject name that can be used.
     448              :     //       Figure out the correct value and update this code.
     449           40 :     result = X509_NAME_add_entry_by_txt(subject, "O", MBSTRING_ASC, Uint8::from_const_char("CSR"), -1, -1, 0);
     450           40 :     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
     451              : 
     452           40 :     result = X509_REQ_set_subject_name(x509_req, subject);
     453           40 :     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
     454              : 
     455           40 :     result = X509_REQ_sign(x509_req, evp_pkey, EVP_sha256());
     456           40 :     VerifyOrExit(result > 0, error = CHIP_ERROR_INTERNAL);
     457              : 
     458           40 :     csr_length_local = i2d_X509_REQ(x509_req, nullptr);
     459           40 :     VerifyOrExit(csr_length_local >= 0, error = CHIP_ERROR_INTERNAL);
     460           40 :     VerifyOrExit(CanCastTo<size_t>(csr_length_local), error = CHIP_ERROR_BUFFER_TOO_SMALL);
     461           40 :     VerifyOrExit(static_cast<size_t>(csr_length_local) <= csr_length, error = CHIP_ERROR_BUFFER_TOO_SMALL);
     462           40 :     csr_length = static_cast<size_t>(i2d_X509_REQ(x509_req, &out_csr));
     463              : 
     464           40 : exit:
     465           40 :     ec_key = nullptr;
     466              : 
     467           40 :     if (evp_pkey != nullptr)
     468              :     {
     469           40 :         EVP_PKEY_free(evp_pkey);
     470           40 :         evp_pkey = nullptr;
     471              :     }
     472              : 
     473           40 :     X509_NAME_free(subject);
     474           40 :     subject = nullptr;
     475              : 
     476           40 :     X509_REQ_free(x509_req);
     477              : 
     478           40 :     SSLErrorLog();
     479           40 :     return error;
     480              : }
     481              : 
     482              : } // namespace Crypto
     483              : } // namespace chip
        

Generated by: LCOV version 2.0-1