Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / crypto / CHIPCryptoPALOpenSSL.cpp
1 /*
2  *
3  *    Copyright (c) 2020-2021 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
25 #include <type_traits>
26
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>
40
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>
47
48 #include <string.h>
49
50 namespace chip {
51 namespace Crypto {
52
53 #define kKeyLengthInBits 256
54
55 enum class DigestType
56 {
57     SHA256
58 };
59
60 enum class ECName
61 {
62     None   = 0,
63     P256v1 = 1,
64 };
65
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");
68
69 static int _nidForCurve(ECName name)
70 {
71     switch (name)
72     {
73     case ECName::P256v1:
74         return EC_curve_nist2nid("P-256");
75         break;
76
77     default:
78         return NID_undef;
79         break;
80     }
81 }
82
83 static bool _isValidTagLength(size_t tag_length)
84 {
85     return tag_length == 8 || tag_length == 12 || tag_length == 16;
86 }
87
88 static bool _isValidKeyLength(size_t length)
89 {
90     // 16 bytes key for AES-CCM-128, 32 for AES-CCM-256
91     return length == 16 || length == 32;
92 }
93
94 static void _logSSLError()
95 {
96     unsigned long ssl_err_code = ERR_get_error();
97     while (ssl_err_code != 0)
98     {
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);
102         if (err_str_lib)
103         {
104             ChipLogError(Crypto, " ssl err  %s %s %s\n", err_str_lib, err_str_routine, err_str_reason);
105         }
106         ssl_err_code = ERR_get_error();
107     }
108 }
109
110 static const EVP_MD * _digestForType(DigestType digestType)
111 {
112     switch (digestType)
113     {
114     case DigestType::SHA256:
115         return EVP_sha256();
116         break;
117
118     default:
119         return nullptr;
120         break;
121     }
122 }
123
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)
127 {
128     EVP_CIPHER_CTX * context = nullptr;
129     int bytesWritten         = 0;
130     size_t ciphertext_length = 0;
131     CHIP_ERROR error         = CHIP_NO_ERROR;
132     int result               = 1;
133     const EVP_CIPHER * type  = nullptr;
134
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);
144
145     // 16 bytes key for AES-CCM-128
146     type = (key_length == 16) ? EVP_aes_128_ccm() : EVP_aes_256_ccm();
147
148     context = EVP_CIPHER_CTX_new();
149     VerifyOrExit(context != nullptr, error = CHIP_ERROR_INTERNAL);
150
151     // Pass in cipher
152     result = EVP_EncryptInit_ex(context, type, nullptr, nullptr, nullptr);
153     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
154
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);
158
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);
162
163     // Pass in key + iv
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);
166
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);
171
172     // Pass in AAD
173     if (aad_length > 0 && aad != nullptr)
174     {
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);
178     }
179
180     // Encrypt
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);
187
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);
193
194     // Get tag
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);
198
199 exit:
200     if (context != nullptr)
201     {
202         EVP_CIPHER_CTX_free(context);
203         context = nullptr;
204     }
205
206     return error;
207 }
208
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)
212 {
213     EVP_CIPHER_CTX * context = nullptr;
214     CHIP_ERROR error         = CHIP_NO_ERROR;
215     int bytesOutput          = 0;
216     int result               = 1;
217     const EVP_CIPHER * type  = nullptr;
218
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);
227
228     // 16 bytes key for AES-CCM-128
229     type = (key_length == 16) ? EVP_aes_128_ccm() : EVP_aes_256_ccm();
230
231     context = EVP_CIPHER_CTX_new();
232     VerifyOrExit(context != nullptr, error = CHIP_ERROR_INTERNAL);
233
234     // Pass in cipher
235     result = EVP_DecryptInit_ex(context, type, nullptr, nullptr, nullptr);
236     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
237
238     // Pass in IV length
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);
242
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);
250
251     // Pass in key + iv
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);
254
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);
259
260     // Pass in aad
261     if (aad_length > 0 && aad != nullptr)
262     {
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);
266     }
267
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);
273
274 exit:
275     if (context != nullptr)
276     {
277         EVP_CIPHER_CTX_free(context);
278         context = nullptr;
279     }
280
281     return error;
282 }
283
284 CHIP_ERROR Hash_SHA256(const uint8_t * data, const size_t data_length, uint8_t * out_buffer)
285 {
286     CHIP_ERROR error = CHIP_NO_ERROR;
287
288     // zero data length hash is supported.
289
290     VerifyOrExit(out_buffer != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
291
292     SHA256(data, data_length, Uint8::to_uchar(out_buffer));
293
294 exit:
295     return error;
296 }
297
298 Hash_SHA256_stream::Hash_SHA256_stream() {}
299
300 Hash_SHA256_stream::~Hash_SHA256_stream() {}
301
302 static inline SHA256_CTX * to_inner_hash_sha256_context(HashSHA256OpaqueContext * context)
303 {
304     return SafePointerCast<SHA256_CTX *>(context);
305 }
306
307 CHIP_ERROR Hash_SHA256_stream::Begin()
308 {
309     CHIP_ERROR error = CHIP_NO_ERROR;
310     int result       = 1;
311
312     SHA256_CTX * context = to_inner_hash_sha256_context(&mContext);
313
314     result = SHA256_Init(context);
315     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
316
317 exit:
318     return error;
319 }
320
321 CHIP_ERROR Hash_SHA256_stream::AddData(const uint8_t * data, const size_t data_length)
322 {
323     CHIP_ERROR error = CHIP_NO_ERROR;
324     int result       = 1;
325
326     SHA256_CTX * context = to_inner_hash_sha256_context(&mContext);
327
328     result = SHA256_Update(context, Uint8::to_const_uchar(data), data_length);
329     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
330
331 exit:
332     return error;
333 }
334
335 CHIP_ERROR Hash_SHA256_stream::Finish(uint8_t * out_buffer)
336 {
337     CHIP_ERROR error = CHIP_NO_ERROR;
338     int result       = 1;
339
340     SHA256_CTX * context = to_inner_hash_sha256_context(&mContext);
341
342     result = SHA256_Final(Uint8::to_uchar(out_buffer), context);
343     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
344
345 exit:
346     return error;
347 }
348
349 void Hash_SHA256_stream::Clear()
350 {
351     memset(this, 0, sizeof(*this));
352 }
353
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)
356 {
357     EVP_PKEY_CTX * context;
358     CHIP_ERROR error = CHIP_NO_ERROR;
359     int result       = 1;
360
361     context = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, nullptr);
362     VerifyOrExit(context != nullptr, error = CHIP_ERROR_INTERNAL);
363
364     VerifyOrExit(secret != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
365     VerifyOrExit(secret_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
366
367     // Salt is optional
368     if (salt_length > 0)
369     {
370         VerifyOrExit(salt != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
371     }
372
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);
377
378     result = EVP_PKEY_derive_init(context);
379     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
380
381     result = EVP_PKEY_CTX_set_hkdf_md(context, EVP_sha256());
382     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
383
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);
387
388     if (salt_length > 0 && salt != nullptr)
389     {
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);
393     }
394
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);
398
399     result = EVP_PKEY_CTX_hkdf_mode(context, EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND);
400     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
401
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);
405
406 exit:
407     if (context != nullptr)
408     {
409         EVP_PKEY_CTX_free(context);
410     }
411     return error;
412 }
413
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)
416 {
417     CHIP_ERROR error  = CHIP_NO_ERROR;
418     int result        = 1;
419     const EVP_MD * md = nullptr;
420
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);
428
429     md = _digestForType(DigestType::SHA256);
430     VerifyOrExit(md != nullptr, error = CHIP_ERROR_INTERNAL);
431
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));
439
440     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
441
442 exit:
443     if (error != CHIP_NO_ERROR)
444     {
445         _logSSLError();
446     }
447
448     return error;
449 }
450
451 CHIP_ERROR add_entropy_source(entropy_source fn_source, void * p_source, size_t threshold)
452 {
453     return CHIP_NO_ERROR;
454 }
455
456 CHIP_ERROR DRBG_get_bytes(uint8_t * out_buffer, const size_t out_length)
457 {
458     CHIP_ERROR error = CHIP_NO_ERROR;
459     int result       = 0;
460
461     VerifyOrExit(out_buffer != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
462     VerifyOrExit(out_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
463
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);
467
468 exit:
469     return error;
470 }
471
472 ECName MapECName(SupportedECPKeyTypes keyType)
473 {
474     switch (keyType)
475     {
476     case SupportedECPKeyTypes::ECP256R1:
477         return ECName::P256v1;
478     default:
479         return ECName::None;
480     }
481 }
482
483 static inline void from_EC_KEY(EC_KEY * key, P256KeypairContext * context)
484 {
485     *SafePointerCast<EC_KEY **>(context) = key;
486 }
487
488 static inline EC_KEY * to_EC_KEY(P256KeypairContext * context)
489 {
490     return *SafePointerCast<EC_KEY **>(context);
491 }
492
493 static inline const EC_KEY * to_const_EC_KEY(const P256KeypairContext * context)
494 {
495     return *SafePointerCast<const EC_KEY * const *>(context);
496 }
497
498 CHIP_ERROR P256Keypair::ECDSA_sign_msg(const uint8_t * msg, const size_t msg_length, P256ECDSASignature & out_signature)
499 {
500     ERR_clear_error();
501
502     CHIP_ERROR error       = CHIP_NO_ERROR;
503     int result             = 0;
504     EVP_MD_CTX * context   = nullptr;
505     int nid                = NID_undef;
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;
511
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);
519
520     ec_key = to_EC_KEY(&mKeypair);
521     VerifyOrExit(ec_key != nullptr, error = CHIP_ERROR_INTERNAL);
522
523     signing_key = EVP_PKEY_new();
524     VerifyOrExit(signing_key != nullptr, error = CHIP_ERROR_INTERNAL);
525
526     result = EVP_PKEY_set1_EC_KEY(signing_key, ec_key);
527     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
528
529     context = EVP_MD_CTX_create();
530     VerifyOrExit(context != nullptr, error = CHIP_ERROR_INTERNAL);
531
532     result = EVP_DigestSignInit(context, nullptr, md, nullptr, signing_key);
533     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
534
535     result = EVP_DigestSignUpdate(context, Uint8::to_const_uchar(msg), msg_length);
536     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
537
538     // Call the EVP_DigestSignFinal with a nullptr param to get length of the signature.
539
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);
543
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));
548
549 exit:
550     ec_key = nullptr;
551
552     if (context != nullptr)
553     {
554         EVP_MD_CTX_destroy(context);
555         context = nullptr;
556     }
557     if (signing_key != nullptr)
558     {
559         EVP_PKEY_free(signing_key);
560         signing_key = nullptr;
561     }
562
563     if (error != CHIP_NO_ERROR)
564     {
565         _logSSLError();
566     }
567
568     return error;
569 }
570
571 CHIP_ERROR P256Keypair::ECDSA_sign_hash(const uint8_t * hash, const size_t hash_length, P256ECDSASignature & out_signature)
572 {
573     ERR_clear_error();
574
575     CHIP_ERROR error = CHIP_NO_ERROR;
576     int result       = 0;
577     int nid          = NID_undef;
578     EC_KEY * ec_key  = nullptr;
579     uint out_length  = 0;
580
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);
586
587     ec_key = to_EC_KEY(&mKeypair);
588     VerifyOrExit(ec_key != nullptr, error = CHIP_ERROR_INTERNAL);
589
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));
594
595 exit:
596     if (error != CHIP_NO_ERROR)
597     {
598         _logSSLError();
599     }
600
601     return error;
602 }
603
604 CHIP_ERROR P256PublicKey::ECDSA_validate_msg_signature(const uint8_t * msg, const size_t msg_length,
605                                                        const P256ECDSASignature & signature) const
606 {
607     ERR_clear_error();
608     CHIP_ERROR error            = CHIP_ERROR_INTERNAL;
609     int nid                     = NID_undef;
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;
615     int result                  = 0;
616     EVP_MD_CTX * md_context     = nullptr;
617     DigestType digest           = DigestType::SHA256;
618
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);
623
624     md = _digestForType(digest);
625     VerifyOrExit(md != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
626
627     ec_group = EC_GROUP_new_by_curve_name(nid);
628     VerifyOrExit(ec_group != nullptr, error = CHIP_ERROR_INTERNAL);
629
630     key_point = EC_POINT_new(ec_group);
631     VerifyOrExit(key_point != nullptr, error = CHIP_ERROR_INTERNAL);
632
633     result = EC_POINT_oct2point(ec_group, key_point, Uint8::to_const_uchar(*this), Length(), nullptr);
634     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
635
636     ec_key = EC_KEY_new_by_curve_name(nid);
637     VerifyOrExit(ec_key != nullptr, error = CHIP_ERROR_INTERNAL);
638
639     result = EC_KEY_set_public_key(ec_key, key_point);
640     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
641
642     result = EC_KEY_check_key(ec_key);
643     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
644
645     verification_key = EVP_PKEY_new();
646     VerifyOrExit(verification_key != nullptr, error = CHIP_ERROR_INTERNAL);
647
648     result = EVP_PKEY_set1_EC_KEY(verification_key, ec_key);
649     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
650
651     md_context = EVP_MD_CTX_create();
652     VerifyOrExit(md_context != nullptr, error = CHIP_ERROR_INTERNAL);
653
654     result = EVP_DigestVerifyInit(md_context, nullptr, md, nullptr, verification_key);
655     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
656
657     result = EVP_DigestVerifyUpdate(md_context, Uint8::to_const_uchar(msg), msg_length);
658     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
659
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;
663
664 exit:
665     _logSSLError();
666     if (ec_group != nullptr)
667     {
668         EC_GROUP_free(ec_group);
669         ec_group = nullptr;
670     }
671     if (key_point != nullptr)
672     {
673         EC_POINT_clear_free(key_point);
674         key_point = nullptr;
675     }
676     if (md_context)
677     {
678         EVP_MD_CTX_destroy(md_context);
679         md_context = nullptr;
680     }
681     if (ec_key != nullptr)
682     {
683         EC_KEY_free(ec_key);
684         ec_key = nullptr;
685     }
686     if (verification_key != nullptr)
687     {
688         EVP_PKEY_free(verification_key);
689         verification_key = nullptr;
690     }
691     return error;
692 }
693
694 CHIP_ERROR P256PublicKey::ECDSA_validate_hash_signature(const uint8_t * hash, const size_t hash_length,
695                                                         const P256ECDSASignature & signature) const
696 {
697     ERR_clear_error();
698     CHIP_ERROR error     = CHIP_ERROR_INTERNAL;
699     int nid              = NID_undef;
700     EC_KEY * ec_key      = nullptr;
701     EC_POINT * key_point = nullptr;
702     EC_GROUP * ec_group  = nullptr;
703     int result           = 0;
704
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);
709
710     ec_group = EC_GROUP_new_by_curve_name(nid);
711     VerifyOrExit(ec_group != nullptr, error = CHIP_ERROR_INTERNAL);
712
713     key_point = EC_POINT_new(ec_group);
714     VerifyOrExit(key_point != nullptr, error = CHIP_ERROR_INTERNAL);
715
716     result = EC_POINT_oct2point(ec_group, key_point, Uint8::to_const_uchar(*this), Length(), nullptr);
717     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
718
719     ec_key = EC_KEY_new_by_curve_name(nid);
720     VerifyOrExit(ec_key != nullptr, error = CHIP_ERROR_INTERNAL);
721
722     result = EC_KEY_set_public_key(ec_key, key_point);
723     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
724
725     result = EC_KEY_check_key(ec_key);
726     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
727
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;
733
734 exit:
735     _logSSLError();
736     if (ec_group != nullptr)
737     {
738         EC_GROUP_free(ec_group);
739         ec_group = nullptr;
740     }
741     if (key_point != nullptr)
742     {
743         EC_POINT_clear_free(key_point);
744         key_point = nullptr;
745     }
746     if (ec_key != nullptr)
747     {
748         EC_KEY_free(ec_key);
749         ec_key = nullptr;
750     }
751     return error;
752 }
753
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)
756 {
757
758     CHIP_ERROR error = CHIP_NO_ERROR;
759     EC_KEY * ec_key  = nullptr;
760     int result       = -1;
761     EC_POINT * point = nullptr;
762     EC_GROUP * group = nullptr;
763     int nid          = NID_undef;
764
765     VerifyOrExit(*out_evp_pkey == nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
766
767     nid = _nidForCurve(MapECName(key.Type()));
768     VerifyOrExit(nid != NID_undef, error = CHIP_ERROR_INTERNAL);
769
770     ec_key = EC_KEY_new_by_curve_name(nid);
771     VerifyOrExit(ec_key != nullptr, error = CHIP_ERROR_INTERNAL);
772
773     group = EC_GROUP_new_by_curve_name(nid);
774     VerifyOrExit(group != nullptr, error = CHIP_ERROR_INTERNAL);
775
776     point = EC_POINT_new(group);
777     VerifyOrExit(point != nullptr, error = CHIP_ERROR_INTERNAL);
778
779     result = EC_POINT_oct2point(group, point, Uint8::to_const_uchar(key), key.Length(), nullptr);
780     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
781
782     result = EC_KEY_set_public_key(ec_key, point);
783
784     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
785
786     *out_evp_pkey = EVP_PKEY_new();
787     VerifyOrExit(*out_evp_pkey != nullptr, error = CHIP_ERROR_INTERNAL);
788
789     result = EVP_PKEY_set1_EC_KEY(*out_evp_pkey, ec_key);
790     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
791
792 exit:
793     if (ec_key != nullptr)
794     {
795         EC_KEY_free(ec_key);
796         ec_key = nullptr;
797     }
798
799     if (error != CHIP_NO_ERROR && *out_evp_pkey)
800     {
801         EVP_PKEY_free(*out_evp_pkey);
802         out_evp_pkey = nullptr;
803     }
804
805     if (point != nullptr)
806     {
807         EC_POINT_free(point);
808         point = nullptr;
809     }
810
811     if (group != nullptr)
812     {
813         EC_GROUP_free(group);
814         group = nullptr;
815     }
816
817     return error;
818 }
819
820 CHIP_ERROR P256Keypair::ECDH_derive_secret(const P256PublicKey & remote_public_key, P256ECDHDerivedSecret & out_secret) const
821 {
822     ERR_clear_error();
823     CHIP_ERROR error      = CHIP_NO_ERROR;
824     int result            = -1;
825     EVP_PKEY * local_key  = nullptr;
826     EVP_PKEY * remote_key = nullptr;
827
828     EVP_PKEY_CTX * context = nullptr;
829     size_t out_buf_length  = 0;
830
831     EC_KEY * ec_key = EC_KEY_dup(to_const_EC_KEY(&mKeypair));
832     VerifyOrExit(ec_key != nullptr, error = CHIP_ERROR_INTERNAL);
833
834     VerifyOrExit(mInitialized, error = CHIP_ERROR_INCORRECT_STATE);
835
836     local_key = EVP_PKEY_new();
837     VerifyOrExit(local_key != nullptr, error = CHIP_ERROR_INTERNAL);
838
839     result = EVP_PKEY_set1_EC_KEY(local_key, ec_key);
840     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
841
842     error = _create_evp_key_from_binary_p256_key(remote_public_key, &remote_key);
843     SuccessOrExit(error);
844
845     context = EVP_PKEY_CTX_new(local_key, nullptr);
846     VerifyOrExit(context != nullptr, error = CHIP_ERROR_INTERNAL);
847
848     result = EVP_PKEY_derive_init(context);
849     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
850
851     result = EVP_PKEY_derive_set_peer(context, remote_key);
852     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
853
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));
858
859 exit:
860     if (ec_key != nullptr)
861     {
862         EC_KEY_free(ec_key);
863         ec_key = nullptr;
864     }
865
866     if (local_key != nullptr)
867     {
868         EVP_PKEY_free(local_key);
869         local_key = nullptr;
870     }
871
872     if (remote_key != nullptr)
873     {
874         EVP_PKEY_free(remote_key);
875         remote_key = nullptr;
876     }
877
878     if (context != nullptr)
879     {
880         EVP_PKEY_CTX_free(context);
881         context = nullptr;
882     }
883
884     _logSSLError();
885     return error;
886 }
887
888 void ClearSecretData(uint8_t * buf, uint32_t len)
889 {
890     memset(buf, 0, len);
891 }
892
893 CHIP_ERROR P256Keypair::Initialize()
894 {
895     ERR_clear_error();
896     CHIP_ERROR error = CHIP_NO_ERROR;
897     int result       = 0;
898     int nid          = NID_undef;
899     EC_KEY * ec_key  = nullptr;
900     EC_GROUP * group = nullptr;
901     ECName curve     = MapECName(mPublicKey.Type());
902
903     VerifyOrExit(curve == MapECName(mPublicKey.Type()), error = CHIP_ERROR_INVALID_ARGUMENT);
904
905     nid = _nidForCurve(curve);
906     VerifyOrExit(nid != NID_undef, error = CHIP_ERROR_INVALID_ARGUMENT);
907
908     ec_key = EC_KEY_new_by_curve_name(nid);
909     VerifyOrExit(ec_key != nullptr, error = CHIP_ERROR_INTERNAL);
910
911     group = EC_GROUP_new_by_curve_name(nid);
912     VerifyOrExit(group != nullptr, error = CHIP_ERROR_INTERNAL);
913
914     result = EC_KEY_generate_key(ec_key);
915     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
916
917     {
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);
921
922         pubkey_size = EC_POINT_point2oct(group, pubkey_ecp, POINT_CONVERSION_UNCOMPRESSED, Uint8::to_uchar(mPublicKey),
923                                          mPublicKey.Length(), nullptr);
924         pubkey_ecp  = nullptr;
925
926         VerifyOrExit(pubkey_size == mPublicKey.Length(), error = CHIP_ERROR_INTERNAL);
927     }
928
929     from_EC_KEY(ec_key, &mKeypair);
930     mInitialized = true;
931     ec_key       = nullptr;
932
933 exit:
934     if (ec_key != nullptr)
935     {
936         EC_KEY_free(ec_key);
937         ec_key = nullptr;
938     }
939
940     if (group != nullptr)
941     {
942         EC_GROUP_free(group);
943         group = nullptr;
944     }
945
946     _logSSLError();
947     return error;
948 }
949
950 CHIP_ERROR P256Keypair::Serialize(P256SerializedKeypair & output)
951 {
952     CHIP_ERROR error = CHIP_NO_ERROR;
953
954     const EC_KEY * ec_key = to_const_EC_KEY(&mKeypair);
955     uint8_t privkey[kP256_PrivateKey_Length];
956
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);
960
961     privkey_size = BN_bn2binpad(privkey_bn, privkey, sizeof(privkey));
962     privkey_bn   = nullptr;
963
964     VerifyOrExit(privkey_size > 0, error = CHIP_ERROR_INTERNAL);
965     VerifyOrExit((size_t) privkey_size == sizeof(privkey), error = CHIP_ERROR_INTERNAL);
966
967     {
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());
974     }
975
976 exit:
977     memset(privkey, 0, sizeof(privkey));
978     _logSSLError();
979     return error;
980 }
981
982 CHIP_ERROR P256Keypair::Deserialize(P256SerializedKeypair & input)
983 {
984     Encoding::BufferWriter bbuf(mPublicKey, mPublicKey.Length());
985
986     BIGNUM * pvt_key     = nullptr;
987     EC_GROUP * group     = nullptr;
988     EC_POINT * key_point = nullptr;
989
990     EC_KEY * ec_key = nullptr;
991     ECName curve    = MapECName(mPublicKey.Type());
992
993     ERR_clear_error();
994     CHIP_ERROR error = CHIP_NO_ERROR;
995     int result       = 0;
996     int nid          = NID_undef;
997
998     const uint8_t * privkey = Uint8::to_const_uchar(input) + mPublicKey.Length();
999
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);
1003
1004     nid = _nidForCurve(curve);
1005     VerifyOrExit(nid != NID_undef, error = CHIP_ERROR_INVALID_ARGUMENT);
1006
1007     group = EC_GROUP_new_by_curve_name(nid);
1008     VerifyOrExit(group != nullptr, error = CHIP_ERROR_INTERNAL);
1009
1010     key_point = EC_POINT_new(group);
1011     VerifyOrExit(key_point != nullptr, error = CHIP_ERROR_INTERNAL);
1012
1013     result = EC_POINT_oct2point(group, key_point, Uint8::to_const_uchar(mPublicKey), mPublicKey.Length(), nullptr);
1014     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
1015
1016     ec_key = EC_KEY_new_by_curve_name(nid);
1017     VerifyOrExit(ec_key != nullptr, error = CHIP_ERROR_INTERNAL);
1018
1019     result = EC_KEY_set_public_key(ec_key, key_point);
1020     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
1021
1022     pvt_key = BN_bin2bn(privkey, kP256_PrivateKey_Length, nullptr);
1023     VerifyOrExit(pvt_key != nullptr, error = CHIP_ERROR_INTERNAL);
1024
1025     result = EC_KEY_set_private_key(ec_key, pvt_key);
1026     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
1027
1028     from_EC_KEY(ec_key, &mKeypair);
1029     mInitialized = true;
1030     ec_key       = nullptr;
1031
1032 exit:
1033
1034     if (ec_key != nullptr)
1035     {
1036         EC_KEY_free(ec_key);
1037         ec_key = nullptr;
1038     }
1039
1040     if (group != nullptr)
1041     {
1042         EC_GROUP_free(group);
1043         group = nullptr;
1044     }
1045
1046     if (pvt_key != nullptr)
1047     {
1048         BN_free(pvt_key);
1049         pvt_key = nullptr;
1050     }
1051
1052     if (key_point != nullptr)
1053     {
1054         EC_POINT_free(key_point);
1055         key_point = nullptr;
1056     }
1057     _logSSLError();
1058     return error;
1059 }
1060
1061 P256Keypair::~P256Keypair()
1062 {
1063     if (mInitialized)
1064     {
1065         EC_KEY * ec_key = to_EC_KEY(&mKeypair);
1066         EC_KEY_free(ec_key);
1067     }
1068 }
1069
1070 CHIP_ERROR P256Keypair::NewCertificateSigningRequest(uint8_t * out_csr, size_t & csr_length)
1071 {
1072     ERR_clear_error();
1073     CHIP_ERROR error = CHIP_NO_ERROR;
1074     int result       = 0;
1075
1076     X509_REQ * x509_req = X509_REQ_new();
1077     EVP_PKEY * evp_pkey = nullptr;
1078
1079     EC_KEY * ec_key = to_EC_KEY(&mKeypair);
1080
1081     BIO * bioMem   = nullptr;
1082     BUF_MEM * bptr = nullptr;
1083
1084     VerifyOrExit(mInitialized, error = CHIP_ERROR_INCORRECT_STATE);
1085
1086     result = X509_REQ_set_version(x509_req, 0);
1087     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
1088
1089     result = EC_KEY_check_key(ec_key);
1090     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
1091
1092     evp_pkey = EVP_PKEY_new();
1093     VerifyOrExit(evp_pkey != nullptr, error = CHIP_ERROR_INTERNAL);
1094
1095     result = EVP_PKEY_set1_EC_KEY(evp_pkey, ec_key);
1096     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
1097
1098     result = X509_REQ_set_pubkey(x509_req, evp_pkey);
1099     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
1100
1101     result = X509_REQ_sign(x509_req, evp_pkey, EVP_sha256());
1102     VerifyOrExit(result > 0, error = CHIP_ERROR_INTERNAL);
1103
1104     bioMem = BIO_new(BIO_s_mem());
1105     VerifyOrExit(bioMem != nullptr, error = CHIP_ERROR_INTERNAL);
1106
1107     result = PEM_write_bio_X509_REQ(bioMem, x509_req);
1108     VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
1109
1110     BIO_get_mem_ptr(bioMem, &bptr);
1111     {
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);
1117     }
1118
1119     BIO_read(bioMem, out_csr, static_cast<int>(bptr->length));
1120
1121 exit:
1122     ec_key = nullptr;
1123
1124     if (evp_pkey != nullptr)
1125     {
1126         EVP_PKEY_free(evp_pkey);
1127         evp_pkey = nullptr;
1128     }
1129
1130     if (bioMem != nullptr)
1131     {
1132         BIO_free(bioMem);
1133         bioMem = nullptr;
1134     }
1135
1136     X509_REQ_free(x509_req);
1137
1138     _logSSLError();
1139     return error;
1140 }
1141
1142 #define init_point(_point_)                                                                                                        \
1143     do                                                                                                                             \
1144     {                                                                                                                              \
1145         _point_ = EC_POINT_new(context->curve);                                                                                    \
1146         VerifyOrExit(_point_ != nullptr, error = CHIP_ERROR_INTERNAL);                                                             \
1147     } while (0)
1148
1149 #define init_bn(_bn_)                                                                                                              \
1150     do                                                                                                                             \
1151     {                                                                                                                              \
1152         _bn_ = BN_new();                                                                                                           \
1153         VerifyOrExit(_bn_ != nullptr, error = CHIP_ERROR_INTERNAL);                                                                \
1154     } while (0)
1155
1156 #define free_point(_point_)                                                                                                        \
1157     do                                                                                                                             \
1158     {                                                                                                                              \
1159         if (_point_ != nullptr)                                                                                                    \
1160         {                                                                                                                          \
1161             EC_POINT_clear_free(static_cast<EC_POINT *>(_point_));                                                                 \
1162         }                                                                                                                          \
1163     } while (0)
1164
1165 #define free_bn(_bn_)                                                                                                              \
1166     do                                                                                                                             \
1167     {                                                                                                                              \
1168         if (_bn_ != nullptr)                                                                                                       \
1169         {                                                                                                                          \
1170             BN_clear_free(static_cast<BIGNUM *>(_bn_));                                                                            \
1171         }                                                                                                                          \
1172     } while (0)
1173
1174 typedef struct Spake2p_Context
1175 {
1176     EC_GROUP * curve;
1177     BN_CTX * bn_ctx;
1178     const EVP_MD * md_info;
1179 } Spake2p_Context;
1180
1181 static inline Spake2p_Context * to_inner_spake2p_context(Spake2pOpaqueContext * context)
1182 {
1183     return SafePointerCast<Spake2p_Context *>(context);
1184 }
1185
1186 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::InitInternal()
1187 {
1188     CHIP_ERROR error  = CHIP_ERROR_INTERNAL;
1189     int error_openssl = 0;
1190
1191     Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
1192
1193     context->curve   = nullptr;
1194     context->bn_ctx  = nullptr;
1195     context->md_info = nullptr;
1196
1197     context->curve = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
1198     VerifyOrExit(context->curve != nullptr, error = CHIP_ERROR_INTERNAL);
1199
1200     G = EC_GROUP_get0_generator(context->curve);
1201     VerifyOrExit(G != nullptr, error = CHIP_ERROR_INTERNAL);
1202
1203     context->bn_ctx = BN_CTX_secure_new();
1204     VerifyOrExit(context->bn_ctx != nullptr, error = CHIP_ERROR_INTERNAL);
1205
1206     context->md_info = EVP_sha256();
1207     VerifyOrExit(context->md_info != nullptr, error = CHIP_ERROR_INTERNAL);
1208
1209     init_point(M);
1210     init_point(N);
1211     init_point(X);
1212     init_point(Y);
1213     init_point(L);
1214     init_point(V);
1215     init_point(Z);
1216     init_bn(w0);
1217     init_bn(w1);
1218     init_bn(xy);
1219     init_bn(tempbn);
1220     init_bn(order);
1221
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);
1224
1225     error = CHIP_NO_ERROR;
1226 exit:
1227     return error;
1228 }
1229
1230 void Spake2p_P256_SHA256_HKDF_HMAC::FreeImpl()
1231 {
1232     Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
1233
1234     if (context->curve != nullptr)
1235     {
1236         EC_GROUP_clear_free(context->curve);
1237     }
1238
1239     if (context->bn_ctx != nullptr)
1240     {
1241         BN_CTX_free(context->bn_ctx);
1242     }
1243
1244     free_point(M);
1245     free_point(N);
1246     free_point(X);
1247     free_point(Y);
1248     free_point(L);
1249     free_point(V);
1250     free_point(Z);
1251     free_bn(w0);
1252     free_bn(w1);
1253     free_bn(xy);
1254     free_bn(tempbn);
1255     free_bn(order);
1256 }
1257
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)
1259 {
1260     CHIP_ERROR error         = CHIP_ERROR_INTERNAL;
1261     int error_openssl        = 0;
1262     unsigned int mac_out_len = 0;
1263
1264     Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
1265
1266     HMAC_CTX * mac_ctx = HMAC_CTX_new();
1267     VerifyOrExit(mac_ctx != nullptr, error = CHIP_ERROR_INTERNAL);
1268
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);
1272
1273     error_openssl = HMAC_Update(mac_ctx, Uint8::to_const_uchar(in), in_len);
1274     VerifyOrExit(error_openssl == 1, error = CHIP_ERROR_INTERNAL);
1275
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);
1280
1281     error = CHIP_NO_ERROR;
1282 exit:
1283     HMAC_CTX_free(mac_ctx);
1284     return error;
1285 }
1286
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)
1289 {
1290     CHIP_ERROR error = CHIP_ERROR_INTERNAL;
1291     VerifyOrExit(mac_len == kSHA256_Hash_Length, error = CHIP_ERROR_INVALID_ARGUMENT);
1292
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);
1296
1297     VerifyOrExit(CRYPTO_memcmp(mac, computed_mac, mac_len) == 0, error = CHIP_ERROR_INTERNAL);
1298
1299     error = CHIP_NO_ERROR;
1300 exit:
1301     return error;
1302 }
1303
1304 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::FELoad(const uint8_t * in, size_t in_len, void * fe)
1305 {
1306     CHIP_ERROR error  = CHIP_ERROR_INTERNAL;
1307     int error_openssl = 0;
1308     BIGNUM * bn_fe    = static_cast<BIGNUM *>(fe);
1309
1310     Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
1311
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);
1316
1317     error = CHIP_NO_ERROR;
1318 exit:
1319     return error;
1320 }
1321
1322 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::FEWrite(const void * fe, uint8_t * out, size_t out_len)
1323 {
1324     CHIP_ERROR error = CHIP_ERROR_INTERNAL;
1325     int bn_out_len;
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));
1328
1329     VerifyOrExit(bn_out_len == static_cast<int>(out_len), error = CHIP_ERROR_INTERNAL);
1330
1331     error = CHIP_NO_ERROR;
1332 exit:
1333     return error;
1334 }
1335
1336 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::FEGenerate(void * fe)
1337 {
1338     CHIP_ERROR error  = CHIP_ERROR_INTERNAL;
1339     int error_openssl = 0;
1340
1341     error_openssl = BN_rand_range(static_cast<BIGNUM *>(fe), static_cast<BIGNUM *>(order));
1342     VerifyOrExit(error_openssl == 1, error = CHIP_ERROR_INTERNAL);
1343
1344     error = CHIP_NO_ERROR;
1345 exit:
1346     return error;
1347 }
1348
1349 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::FEMul(void * fer, const void * fe1, const void * fe2)
1350 {
1351     CHIP_ERROR error  = CHIP_ERROR_INTERNAL;
1352     int error_openssl = 0;
1353
1354     Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
1355
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);
1359
1360     error = CHIP_NO_ERROR;
1361 exit:
1362     return error;
1363 }
1364
1365 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointLoad(const uint8_t * in, size_t in_len, void * R)
1366 {
1367     CHIP_ERROR error  = CHIP_ERROR_INTERNAL;
1368     int error_openssl = 0;
1369
1370     Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
1371
1372     error_openssl =
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);
1375
1376     error = CHIP_NO_ERROR;
1377 exit:
1378     return error;
1379 }
1380
1381 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointWrite(const void * R, uint8_t * out, size_t out_len)
1382 {
1383     CHIP_ERROR error          = CHIP_ERROR_INTERNAL;
1384     Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
1385
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);
1389
1390     error = CHIP_NO_ERROR;
1391 exit:
1392     return error;
1393 }
1394
1395 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointMul(void * R, const void * P1, const void * fe1)
1396 {
1397     CHIP_ERROR error  = CHIP_ERROR_INTERNAL;
1398     int error_openssl = 0;
1399
1400     Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
1401
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);
1405
1406     error = CHIP_NO_ERROR;
1407 exit:
1408     return error;
1409 }
1410
1411 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointAddMul(void * R, const void * P1, const void * fe1, const void * P2,
1412                                                       const void * fe2)
1413 {
1414     CHIP_ERROR error   = CHIP_ERROR_INTERNAL;
1415     int error_openssl  = 0;
1416     EC_POINT * scratch = nullptr;
1417
1418     Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
1419
1420     scratch = EC_POINT_new(context->curve);
1421     VerifyOrExit(scratch != nullptr, error = CHIP_ERROR_INTERNAL);
1422
1423     error = PointMul(scratch, P1, fe1);
1424     VerifyOrExit(error == CHIP_NO_ERROR, error = CHIP_ERROR_INTERNAL);
1425
1426     error = PointMul(R, P2, fe2);
1427     VerifyOrExit(error == CHIP_NO_ERROR, error = CHIP_ERROR_INTERNAL);
1428
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);
1432
1433     error = CHIP_NO_ERROR;
1434 exit:
1435     EC_POINT_clear_free(scratch);
1436     return error;
1437 }
1438
1439 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointInvert(void * R)
1440 {
1441     CHIP_ERROR error  = CHIP_ERROR_INTERNAL;
1442     int error_openssl = 0;
1443
1444     Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
1445
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);
1448
1449     error = CHIP_NO_ERROR;
1450 exit:
1451     return error;
1452 }
1453
1454 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointCofactorMul(void * R)
1455 {
1456     // Cofactor on P256 is 1 so this is a NOP
1457     return CHIP_NO_ERROR;
1458 }
1459
1460 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::ComputeL(uint8_t * Lout, size_t * L_len, const uint8_t * w1in, size_t w1in_len)
1461 {
1462     CHIP_ERROR error      = CHIP_ERROR_INTERNAL;
1463     int error_openssl     = 0;
1464     BIGNUM * w1_bn        = nullptr;
1465     EC_POINT * Lout_point = nullptr;
1466
1467     Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
1468
1469     w1_bn = BN_new();
1470     VerifyOrExit(w1_bn != nullptr, error = CHIP_ERROR_INTERNAL);
1471
1472     Lout_point = EC_POINT_new(context->curve);
1473     VerifyOrExit(Lout_point != nullptr, error = CHIP_ERROR_INTERNAL);
1474
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);
1479
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);
1482
1483     *L_len = EC_POINT_point2oct(context->curve, Lout_point, POINT_CONVERSION_UNCOMPRESSED, Uint8::to_uchar(Lout), *L_len,
1484                                 context->bn_ctx);
1485     VerifyOrExit(*L_len != 0, error = CHIP_ERROR_INTERNAL);
1486
1487     error = CHIP_NO_ERROR;
1488 exit:
1489     BN_clear_free(w1_bn);
1490     EC_POINT_clear_free(Lout_point);
1491
1492     return error;
1493 }
1494
1495 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointIsValid(void * R)
1496 {
1497     CHIP_ERROR error  = CHIP_ERROR_INTERNAL;
1498     int error_openssl = 0;
1499
1500     Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
1501
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);
1504
1505     error = CHIP_NO_ERROR;
1506 exit:
1507     return error;
1508 }
1509
1510 } // namespace Crypto
1511 } // namespace chip