Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / crypto / CHIPCryptoPALmbedTLS.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  *      mbedTLS based implementation of CHIP crypto primitives
21  */
22
23 #include "CHIPCryptoPAL.h"
24
25 #include <type_traits>
26
27 #include <mbedtls/bignum.h>
28 #include <mbedtls/ccm.h>
29 #include <mbedtls/ctr_drbg.h>
30 #include <mbedtls/ecdh.h>
31 #include <mbedtls/ecdsa.h>
32 #include <mbedtls/ecp.h>
33 #include <mbedtls/entropy.h>
34 #include <mbedtls/error.h>
35 #include <mbedtls/hkdf.h>
36 #include <mbedtls/md.h>
37 #include <mbedtls/pkcs5.h>
38 #include <mbedtls/sha256.h>
39 #include <mbedtls/x509_csr.h>
40
41 #include <core/CHIPSafeCasts.h>
42 #include <support/BufferWriter.h>
43 #include <support/CodeUtils.h>
44 #include <support/SafePointerCast.h>
45 #include <support/logging/CHIPLogging.h>
46
47 #include <string.h>
48
49 namespace chip {
50 namespace Crypto {
51
52 #define MAX_ERROR_STR_LEN 128
53 #define NUM_BYTES_IN_SHA256_HASH 32
54
55 typedef struct
56 {
57     bool mInitialized;
58     bool mDRBGSeeded;
59     mbedtls_ctr_drbg_context mDRBGCtxt;
60     mbedtls_entropy_context mEntropy;
61 } EntropyContext;
62
63 static EntropyContext gsEntropyContext;
64
65 static void _log_mbedTLS_error(int error_code)
66 {
67     if (error_code != 0)
68     {
69         char error_str[MAX_ERROR_STR_LEN];
70         mbedtls_strerror(error_code, error_str, sizeof(error_str));
71         ChipLogError(Crypto, "mbedTLS error: %s\n", error_str);
72     }
73 }
74
75 static bool _isValidTagLength(size_t tag_length)
76 {
77     if (tag_length == 8 || tag_length == 12 || tag_length == 16)
78     {
79         return true;
80     }
81     return false;
82 }
83
84 static bool _isValidKeyLength(size_t length)
85 {
86     // 16 bytes key for AES-CCM-128, 32 for AES-CCM-256
87     if (length == 16 || length == 32)
88     {
89         return true;
90     }
91     return false;
92 }
93
94 CHIP_ERROR AES_CCM_encrypt(const uint8_t * plaintext, size_t plaintext_length, const uint8_t * aad, size_t aad_length,
95                            const uint8_t * key, size_t key_length, const uint8_t * iv, size_t iv_length, uint8_t * ciphertext,
96                            uint8_t * tag, size_t tag_length)
97 {
98     CHIP_ERROR error = CHIP_NO_ERROR;
99     int result       = 1;
100
101     mbedtls_ccm_context context;
102     mbedtls_ccm_init(&context);
103
104     VerifyOrExit(plaintext != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
105     VerifyOrExit(plaintext_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
106     VerifyOrExit(key != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
107     VerifyOrExit(_isValidKeyLength(key_length), error = CHIP_ERROR_UNSUPPORTED_ENCRYPTION_TYPE);
108     VerifyOrExit(iv != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
109     VerifyOrExit(iv_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
110     VerifyOrExit(tag != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
111     VerifyOrExit(_isValidTagLength(tag_length), error = CHIP_ERROR_INVALID_ARGUMENT);
112     if (aad_length > 0)
113     {
114         VerifyOrExit(aad != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
115     }
116
117     // Size of key = key_length * number of bits in a byte (8)
118     // Cast is safe because we called _isValidKeyLength above.
119     result =
120         mbedtls_ccm_setkey(&context, MBEDTLS_CIPHER_ID_AES, Uint8::to_const_uchar(key), static_cast<unsigned int>(key_length * 8));
121     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
122
123     // Encrypt
124     result = mbedtls_ccm_encrypt_and_tag(&context, plaintext_length, Uint8::to_const_uchar(iv), iv_length,
125                                          Uint8::to_const_uchar(aad), aad_length, Uint8::to_const_uchar(plaintext),
126                                          Uint8::to_uchar(ciphertext), Uint8::to_uchar(tag), tag_length);
127     _log_mbedTLS_error(result);
128     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
129
130 exit:
131     mbedtls_ccm_free(&context);
132     return error;
133 }
134
135 CHIP_ERROR AES_CCM_decrypt(const uint8_t * ciphertext, size_t ciphertext_len, const uint8_t * aad, size_t aad_len,
136                            const uint8_t * tag, size_t tag_length, const uint8_t * key, size_t key_length, const uint8_t * iv,
137                            size_t iv_length, uint8_t * plaintext)
138 {
139     CHIP_ERROR error = CHIP_NO_ERROR;
140     int result       = 1;
141
142     mbedtls_ccm_context context;
143     mbedtls_ccm_init(&context);
144
145     VerifyOrExit(ciphertext != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
146     VerifyOrExit(ciphertext_len > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
147     VerifyOrExit(tag != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
148     VerifyOrExit(_isValidTagLength(tag_length), error = CHIP_ERROR_INVALID_ARGUMENT);
149     VerifyOrExit(key != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
150     VerifyOrExit(_isValidKeyLength(key_length), error = CHIP_ERROR_UNSUPPORTED_ENCRYPTION_TYPE);
151     VerifyOrExit(iv != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
152     VerifyOrExit(iv_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
153     if (aad_len > 0)
154     {
155         VerifyOrExit(aad != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
156     }
157
158     // Size of key = key_length * number of bits in a byte (8)
159     // Cast is safe because we called _isValidKeyLength above.
160     result =
161         mbedtls_ccm_setkey(&context, MBEDTLS_CIPHER_ID_AES, Uint8::to_const_uchar(key), static_cast<unsigned int>(key_length * 8));
162     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
163
164     // Decrypt
165     result = mbedtls_ccm_auth_decrypt(&context, ciphertext_len, Uint8::to_const_uchar(iv), iv_length, Uint8::to_const_uchar(aad),
166                                       aad_len, Uint8::to_const_uchar(ciphertext), Uint8::to_uchar(plaintext),
167                                       Uint8::to_const_uchar(tag), tag_length);
168     _log_mbedTLS_error(result);
169     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
170
171 exit:
172     mbedtls_ccm_free(&context);
173     return error;
174 }
175
176 CHIP_ERROR Hash_SHA256(const uint8_t * data, const size_t data_length, uint8_t * out_buffer)
177 {
178     CHIP_ERROR error = CHIP_NO_ERROR;
179     int result       = 0;
180
181     // zero data length hash is supported.
182
183     VerifyOrExit(out_buffer != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
184
185     result = mbedtls_sha256_ret(Uint8::to_const_uchar(data), data_length, Uint8::to_uchar(out_buffer), 0);
186     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
187
188 exit:
189     return error;
190 }
191
192 Hash_SHA256_stream::Hash_SHA256_stream(void) {}
193
194 Hash_SHA256_stream::~Hash_SHA256_stream(void) {}
195
196 static inline mbedtls_sha256_context * to_inner_hash_sha256_context(HashSHA256OpaqueContext * context)
197 {
198     return SafePointerCast<mbedtls_sha256_context *>(context);
199 }
200
201 CHIP_ERROR Hash_SHA256_stream::Begin(void)
202 {
203     CHIP_ERROR error = CHIP_NO_ERROR;
204     int result       = 0;
205
206     mbedtls_sha256_context * context = to_inner_hash_sha256_context(&mContext);
207
208     result = mbedtls_sha256_starts_ret(context, 0);
209     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
210
211 exit:
212     return error;
213 }
214
215 CHIP_ERROR Hash_SHA256_stream::AddData(const uint8_t * data, const size_t data_length)
216 {
217     CHIP_ERROR error = CHIP_NO_ERROR;
218     int result       = 0;
219
220     mbedtls_sha256_context * context = to_inner_hash_sha256_context(&mContext);
221
222     result = mbedtls_sha256_update_ret(context, Uint8::to_const_uchar(data), data_length);
223     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
224
225 exit:
226     return error;
227 }
228
229 CHIP_ERROR Hash_SHA256_stream::Finish(uint8_t * out_buffer)
230 {
231     CHIP_ERROR error = CHIP_NO_ERROR;
232     int result       = 0;
233
234     mbedtls_sha256_context * context = to_inner_hash_sha256_context(&mContext);
235
236     result = mbedtls_sha256_finish_ret(context, Uint8::to_uchar(out_buffer));
237     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
238
239 exit:
240     return error;
241 }
242
243 void Hash_SHA256_stream::Clear(void)
244 {
245     memset(this, 0, sizeof(*this));
246 }
247
248 CHIP_ERROR HKDF_SHA256(const uint8_t * secret, const size_t secret_length, const uint8_t * salt, const size_t salt_length,
249                        const uint8_t * info, const size_t info_length, uint8_t * out_buffer, size_t out_length)
250 {
251     CHIP_ERROR error = CHIP_NO_ERROR;
252     int result       = 1;
253     const mbedtls_md_info_t * md;
254
255     VerifyOrExit(secret != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
256     VerifyOrExit(secret_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
257
258     // Salt is optional
259     if (salt_length > 0)
260     {
261         VerifyOrExit(salt != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
262     }
263
264     VerifyOrExit(info_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
265     VerifyOrExit(info != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
266     VerifyOrExit(out_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
267     VerifyOrExit(out_buffer != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
268
269     md = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
270     VerifyOrExit(md != nullptr, error = CHIP_ERROR_INTERNAL);
271
272     result = mbedtls_hkdf(md, Uint8::to_const_uchar(salt), salt_length, Uint8::to_const_uchar(secret), secret_length,
273                           Uint8::to_const_uchar(info), info_length, Uint8::to_uchar(out_buffer), out_length);
274     _log_mbedTLS_error(result);
275     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
276
277 exit:
278     return error;
279 }
280
281 CHIP_ERROR pbkdf2_sha256(const uint8_t * password, size_t plen, const uint8_t * salt, size_t slen, unsigned int iteration_count,
282                          uint32_t key_length, uint8_t * output)
283 {
284     CHIP_ERROR error = CHIP_NO_ERROR;
285     int result       = 0;
286     const mbedtls_md_info_t * md_info;
287     mbedtls_md_context_t md_ctxt;
288     constexpr int use_hmac = 1;
289
290     bool free_md_ctxt = false;
291
292     VerifyOrExit(password != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
293     VerifyOrExit(plen > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
294     VerifyOrExit(salt != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
295     VerifyOrExit(slen >= kMin_Salt_Length, error = CHIP_ERROR_INVALID_ARGUMENT);
296     VerifyOrExit(slen <= kMax_Salt_Length, error = CHIP_ERROR_INVALID_ARGUMENT);
297     VerifyOrExit(key_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
298     VerifyOrExit(output != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
299
300     md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
301     VerifyOrExit(md_info != nullptr, error = CHIP_ERROR_INTERNAL);
302
303     mbedtls_md_init(&md_ctxt);
304     free_md_ctxt = true;
305
306     result = mbedtls_md_setup(&md_ctxt, md_info, use_hmac);
307     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
308
309     result = mbedtls_pkcs5_pbkdf2_hmac(&md_ctxt, Uint8::to_const_uchar(password), plen, Uint8::to_const_uchar(salt), slen,
310                                        iteration_count, key_length, Uint8::to_uchar(output));
311
312     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
313
314 exit:
315     _log_mbedTLS_error(result);
316
317     if (free_md_ctxt)
318     {
319         mbedtls_md_free(&md_ctxt);
320     }
321
322     return error;
323 }
324
325 static EntropyContext * get_entropy_context()
326 {
327     if (!gsEntropyContext.mInitialized)
328     {
329         mbedtls_entropy_init(&gsEntropyContext.mEntropy);
330         mbedtls_ctr_drbg_init(&gsEntropyContext.mDRBGCtxt);
331
332         gsEntropyContext.mInitialized = true;
333     }
334
335     return &gsEntropyContext;
336 }
337
338 static mbedtls_ctr_drbg_context * get_drbg_context()
339 {
340     EntropyContext * context = get_entropy_context();
341
342     mbedtls_ctr_drbg_context * drbgCtxt = &context->mDRBGCtxt;
343
344     if (!context->mDRBGSeeded)
345     {
346         int status = mbedtls_ctr_drbg_seed(drbgCtxt, mbedtls_entropy_func, &context->mEntropy, nullptr, 0);
347         VerifyOrExit(status == 0, _log_mbedTLS_error(status));
348
349         context->mDRBGSeeded = true;
350     }
351
352     return drbgCtxt;
353
354 exit:
355     return nullptr;
356 }
357
358 CHIP_ERROR add_entropy_source(entropy_source fn_source, void * p_source, size_t threshold)
359 {
360     CHIP_ERROR error              = CHIP_NO_ERROR;
361     int result                    = 0;
362     EntropyContext * entropy_ctxt = nullptr;
363
364     VerifyOrExit(fn_source != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
365
366     entropy_ctxt = get_entropy_context();
367     VerifyOrExit(entropy_ctxt != nullptr, error = CHIP_ERROR_INTERNAL);
368
369     result = mbedtls_entropy_add_source(&entropy_ctxt->mEntropy, fn_source, p_source, threshold, MBEDTLS_ENTROPY_SOURCE_STRONG);
370     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
371 exit:
372     return error;
373 }
374
375 CHIP_ERROR DRBG_get_bytes(uint8_t * out_buffer, const size_t out_length)
376 {
377     CHIP_ERROR error = CHIP_NO_ERROR;
378     int result       = 0;
379
380     mbedtls_ctr_drbg_context * drbg_ctxt = nullptr;
381
382     VerifyOrExit(out_buffer != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
383     VerifyOrExit(out_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
384
385     drbg_ctxt = get_drbg_context();
386     VerifyOrExit(drbg_ctxt != nullptr, error = CHIP_ERROR_INTERNAL);
387
388     result = mbedtls_ctr_drbg_random(drbg_ctxt, Uint8::to_uchar(out_buffer), out_length);
389     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
390
391 exit:
392     return error;
393 }
394
395 static int CryptoRNG(void * ctxt, uint8_t * out_buffer, size_t out_length)
396 {
397     return (chip::Crypto::DRBG_get_bytes(out_buffer, out_length) == CHIP_NO_ERROR) ? 0 : 1;
398 }
399
400 mbedtls_ecp_group_id MapECPGroupId(SupportedECPKeyTypes keyType)
401 {
402     switch (keyType)
403     {
404     case SupportedECPKeyTypes::ECP256R1:
405         return MBEDTLS_ECP_DP_SECP256R1;
406     default:
407         return MBEDTLS_ECP_DP_NONE;
408     }
409 }
410
411 static inline mbedtls_ecp_keypair * to_keypair(P256KeypairContext * context)
412 {
413     return SafePointerCast<mbedtls_ecp_keypair *>(context);
414 }
415
416 static inline const mbedtls_ecp_keypair * to_const_keypair(const P256KeypairContext * context)
417 {
418     return SafePointerCast<const mbedtls_ecp_keypair *>(context);
419 }
420
421 CHIP_ERROR P256Keypair::ECDSA_sign_msg(const uint8_t * msg, const size_t msg_length, P256ECDSASignature & out_signature)
422 {
423     CHIP_ERROR error = CHIP_NO_ERROR;
424     int result       = 0;
425     uint8_t hash[NUM_BYTES_IN_SHA256_HASH];
426     size_t siglen = out_signature.Capacity();
427
428     const mbedtls_ecp_keypair * keypair = to_const_keypair(&mKeypair);
429
430     mbedtls_ecdsa_context ecdsa_ctxt;
431     mbedtls_ecdsa_init(&ecdsa_ctxt);
432
433     VerifyOrExit(mInitialized, error = CHIP_ERROR_INCORRECT_STATE);
434     VerifyOrExit(msg != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
435     VerifyOrExit(msg_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
436
437     result = mbedtls_ecdsa_from_keypair(&ecdsa_ctxt, keypair);
438     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
439
440     result = mbedtls_sha256_ret(Uint8::to_const_uchar(msg), msg_length, hash, 0);
441     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
442
443     result = mbedtls_ecdsa_write_signature(&ecdsa_ctxt, MBEDTLS_MD_SHA256, hash, sizeof(hash), Uint8::to_uchar(out_signature),
444                                            &siglen, CryptoRNG, nullptr);
445     SuccessOrExit(out_signature.SetLength(siglen));
446     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
447
448 exit:
449     keypair = nullptr;
450     mbedtls_ecdsa_free(&ecdsa_ctxt);
451     _log_mbedTLS_error(result);
452     return error;
453 }
454
455 CHIP_ERROR P256Keypair::ECDSA_sign_hash(const uint8_t * hash, const size_t hash_length, P256ECDSASignature & out_signature)
456 {
457     CHIP_ERROR error = CHIP_NO_ERROR;
458     int result       = 0;
459     size_t siglen    = out_signature.Capacity();
460
461     const mbedtls_ecp_keypair * keypair = to_const_keypair(&mKeypair);
462
463     mbedtls_ecdsa_context ecdsa_ctxt;
464     mbedtls_ecdsa_init(&ecdsa_ctxt);
465
466     VerifyOrExit(mInitialized, error = CHIP_ERROR_INCORRECT_STATE);
467     VerifyOrExit(hash != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
468     VerifyOrExit(hash_length == NUM_BYTES_IN_SHA256_HASH, error = CHIP_ERROR_INVALID_ARGUMENT);
469
470     result = mbedtls_ecdsa_from_keypair(&ecdsa_ctxt, keypair);
471     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
472
473     result = mbedtls_ecdsa_write_signature(&ecdsa_ctxt, MBEDTLS_MD_SHA256, hash, hash_length, Uint8::to_uchar(out_signature),
474                                            &siglen, CryptoRNG, nullptr);
475     SuccessOrExit(out_signature.SetLength(siglen));
476     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
477
478 exit:
479     keypair = nullptr;
480     mbedtls_ecdsa_free(&ecdsa_ctxt);
481     _log_mbedTLS_error(result);
482     return error;
483 }
484
485 CHIP_ERROR P256PublicKey::ECDSA_validate_msg_signature(const uint8_t * msg, const size_t msg_length,
486                                                        const P256ECDSASignature & signature) const
487 {
488     CHIP_ERROR error = CHIP_NO_ERROR;
489     int result       = 0;
490     uint8_t hash[NUM_BYTES_IN_SHA256_HASH];
491
492     mbedtls_ecp_keypair keypair;
493     mbedtls_ecp_keypair_init(&keypair);
494
495     mbedtls_ecdsa_context ecdsa_ctxt;
496     mbedtls_ecdsa_init(&ecdsa_ctxt);
497
498     VerifyOrExit(msg != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
499     VerifyOrExit(msg_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
500
501     result = mbedtls_ecp_group_load(&keypair.grp, MapECPGroupId(Type()));
502     VerifyOrExit(result == 0, error = CHIP_ERROR_INVALID_ARGUMENT);
503
504     result = mbedtls_ecp_point_read_binary(&keypair.grp, &keypair.Q, Uint8::to_const_uchar(*this), Length());
505     VerifyOrExit(result == 0, error = CHIP_ERROR_INVALID_ARGUMENT);
506
507     result = mbedtls_ecdsa_from_keypair(&ecdsa_ctxt, &keypair);
508     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
509
510     result = mbedtls_sha256_ret(Uint8::to_const_uchar(msg), msg_length, hash, 0);
511     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
512
513     result = mbedtls_ecdsa_read_signature(&ecdsa_ctxt, hash, sizeof(hash), Uint8::to_const_uchar(signature), signature.Length());
514     VerifyOrExit(result == 0, error = CHIP_ERROR_INVALID_SIGNATURE);
515
516 exit:
517     mbedtls_ecp_keypair_free(&keypair);
518     mbedtls_ecdsa_free(&ecdsa_ctxt);
519     _log_mbedTLS_error(result);
520     return error;
521 }
522
523 CHIP_ERROR P256PublicKey::ECDSA_validate_hash_signature(const uint8_t * hash, const size_t hash_length,
524                                                         const P256ECDSASignature & signature) const
525 {
526     CHIP_ERROR error = CHIP_NO_ERROR;
527     int result       = 0;
528
529     mbedtls_ecp_keypair keypair;
530     mbedtls_ecp_keypair_init(&keypair);
531
532     mbedtls_ecdsa_context ecdsa_ctxt;
533     mbedtls_ecdsa_init(&ecdsa_ctxt);
534
535     VerifyOrExit(hash != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
536     VerifyOrExit(hash_length == NUM_BYTES_IN_SHA256_HASH, error = CHIP_ERROR_INVALID_ARGUMENT);
537
538     result = mbedtls_ecp_group_load(&keypair.grp, MapECPGroupId(Type()));
539     VerifyOrExit(result == 0, error = CHIP_ERROR_INVALID_ARGUMENT);
540
541     result = mbedtls_ecp_point_read_binary(&keypair.grp, &keypair.Q, Uint8::to_const_uchar(*this), Length());
542     VerifyOrExit(result == 0, error = CHIP_ERROR_INVALID_ARGUMENT);
543
544     result = mbedtls_ecdsa_from_keypair(&ecdsa_ctxt, &keypair);
545     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
546
547     result = mbedtls_ecdsa_read_signature(&ecdsa_ctxt, hash, hash_length, Uint8::to_const_uchar(signature), signature.Length());
548     VerifyOrExit(result == 0, error = CHIP_ERROR_INVALID_SIGNATURE);
549
550 exit:
551     mbedtls_ecp_keypair_free(&keypair);
552     mbedtls_ecdsa_free(&ecdsa_ctxt);
553     _log_mbedTLS_error(result);
554     return error;
555 }
556
557 CHIP_ERROR P256Keypair::ECDH_derive_secret(const P256PublicKey & remote_public_key, P256ECDHDerivedSecret & out_secret) const
558 {
559     CHIP_ERROR error     = CHIP_NO_ERROR;
560     int result           = 0;
561     size_t secret_length = (out_secret.Length() == 0) ? out_secret.Capacity() : out_secret.Length();
562
563     mbedtls_ecp_group ecp_grp;
564     mbedtls_ecp_group_init(&ecp_grp);
565
566     mbedtls_mpi mpi_secret;
567     mbedtls_mpi_init(&mpi_secret);
568
569     mbedtls_ecp_point ecp_pubkey;
570     mbedtls_ecp_point_init(&ecp_pubkey);
571
572     const mbedtls_ecp_keypair * keypair = to_const_keypair(&mKeypair);
573
574     VerifyOrExit(mInitialized, error = CHIP_ERROR_INCORRECT_STATE);
575
576     result = mbedtls_ecp_group_load(&ecp_grp, MapECPGroupId(remote_public_key.Type()));
577     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
578
579     result =
580         mbedtls_ecp_point_read_binary(&ecp_grp, &ecp_pubkey, Uint8::to_const_uchar(remote_public_key), remote_public_key.Length());
581     VerifyOrExit(result == 0, error = CHIP_ERROR_INVALID_ARGUMENT);
582
583     result = mbedtls_ecdh_compute_shared(&ecp_grp, &mpi_secret, &ecp_pubkey, &keypair->d, CryptoRNG, nullptr);
584     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
585
586     result = mbedtls_mpi_write_binary(&mpi_secret, Uint8::to_uchar(out_secret), secret_length);
587     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
588     SuccessOrExit(out_secret.SetLength(secret_length));
589
590 exit:
591     keypair = nullptr;
592     mbedtls_ecp_group_free(&ecp_grp);
593     mbedtls_mpi_free(&mpi_secret);
594     mbedtls_ecp_point_free(&ecp_pubkey);
595     _log_mbedTLS_error(result);
596     return error;
597 }
598
599 void ClearSecretData(uint8_t * buf, uint32_t len)
600 {
601     memset(buf, 0, len);
602 }
603
604 CHIP_ERROR P256Keypair::Initialize()
605 {
606     CHIP_ERROR error = CHIP_NO_ERROR;
607     int result       = 0;
608
609     size_t pubkey_size = 0;
610
611     mbedtls_ecp_group_id group = MapECPGroupId(mPublicKey.Type());
612
613     mbedtls_ecp_keypair * keypair = to_keypair(&mKeypair);
614     mbedtls_ecp_keypair_init(keypair);
615
616     result = mbedtls_ecp_gen_key(group, keypair, CryptoRNG, nullptr);
617     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
618
619     result = mbedtls_ecp_point_write_binary(&keypair->grp, &keypair->Q, MBEDTLS_ECP_PF_UNCOMPRESSED, &pubkey_size,
620                                             Uint8::to_uchar(mPublicKey), mPublicKey.Length());
621     VerifyOrExit(result == 0, error = CHIP_ERROR_INVALID_ARGUMENT);
622     VerifyOrExit(pubkey_size == mPublicKey.Length(), error = CHIP_ERROR_INVALID_ARGUMENT);
623
624     keypair      = nullptr;
625     mInitialized = true;
626
627 exit:
628     if (keypair != nullptr)
629     {
630         mbedtls_ecp_keypair_free(keypair);
631         keypair = nullptr;
632     }
633
634     _log_mbedTLS_error(result);
635     return error;
636 }
637
638 CHIP_ERROR P256Keypair::Serialize(P256SerializedKeypair & output)
639 {
640     const mbedtls_ecp_keypair * keypair = to_const_keypair(&mKeypair);
641     size_t len                          = output.Length() == 0 ? output.Capacity() : output.Length();
642     Encoding::BufferWriter bbuf(output, len);
643     uint8_t privkey[kP256_PrivateKey_Length];
644     CHIP_ERROR error = CHIP_NO_ERROR;
645     int result       = 0;
646
647     bbuf.Put(mPublicKey, mPublicKey.Length());
648
649     VerifyOrExit(bbuf.Available() == sizeof(privkey), error = CHIP_ERROR_INTERNAL);
650     VerifyOrExit(mbedtls_mpi_size(&keypair->d) <= bbuf.Available(), error = CHIP_ERROR_INTERNAL);
651
652     result = mbedtls_mpi_write_binary(&keypair->d, Uint8::to_uchar(privkey), sizeof(privkey));
653     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
654
655     bbuf.Put(privkey, sizeof(privkey));
656     VerifyOrExit(bbuf.Fit(), error = CHIP_ERROR_BUFFER_TOO_SMALL);
657
658     output.SetLength(bbuf.Needed());
659
660 exit:
661     memset(privkey, 0, sizeof(privkey));
662     _log_mbedTLS_error(result);
663     return error;
664 }
665
666 CHIP_ERROR P256Keypair::Deserialize(P256SerializedKeypair & input)
667 {
668     Encoding::BufferWriter bbuf(mPublicKey, mPublicKey.Length());
669
670     int result       = 0;
671     CHIP_ERROR error = CHIP_NO_ERROR;
672
673     mbedtls_ecp_keypair * keypair = to_keypair(&mKeypair);
674     mbedtls_ecp_keypair_init(keypair);
675
676     result = mbedtls_ecp_group_load(&keypair->grp, MapECPGroupId(mPublicKey.Type()));
677     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
678
679     VerifyOrExit(input.Length() == mPublicKey.Length() + kP256_PrivateKey_Length, error = CHIP_ERROR_INVALID_ARGUMENT);
680     bbuf.Put((const uint8_t *) input, mPublicKey.Length());
681     VerifyOrExit(bbuf.Fit(), error = CHIP_ERROR_NO_MEMORY);
682
683     result = mbedtls_ecp_point_read_binary(&keypair->grp, &keypair->Q, Uint8::to_const_uchar(mPublicKey), mPublicKey.Length());
684     VerifyOrExit(result == 0, error = CHIP_ERROR_INVALID_ARGUMENT);
685
686     {
687         const uint8_t * privkey = Uint8::to_const_uchar(input) + mPublicKey.Length();
688         result                  = mbedtls_mpi_read_binary(&keypair->d, privkey, kP256_PrivateKey_Length);
689         VerifyOrExit(result == 0, error = CHIP_ERROR_INVALID_ARGUMENT);
690     }
691     mInitialized = true;
692
693 exit:
694     _log_mbedTLS_error(result);
695     return error;
696 }
697
698 P256Keypair::~P256Keypair()
699 {
700     if (mInitialized)
701     {
702         mbedtls_ecp_keypair * keypair = to_keypair(&mKeypair);
703         mbedtls_ecp_keypair_free(keypair);
704     }
705 }
706
707 CHIP_ERROR P256Keypair::NewCertificateSigningRequest(uint8_t * out_csr, size_t & csr_length)
708 {
709     CHIP_ERROR error = CHIP_NO_ERROR;
710     int result       = 0;
711     size_t length    = csr_length;
712
713     const mbedtls_ecp_keypair * keypair = to_const_keypair(&mKeypair);
714
715     mbedtls_x509write_csr csr;
716     mbedtls_x509write_csr_init(&csr);
717
718     mbedtls_pk_context pk;
719     mbedtls_pk_init(&pk);
720
721     const mbedtls_pk_info_t * pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY);
722     VerifyOrExit(pk_info != nullptr, error = CHIP_ERROR_INTERNAL);
723
724     VerifyOrExit(mInitialized, error = CHIP_ERROR_INCORRECT_STATE);
725
726     result = mbedtls_pk_setup(&pk, pk_info);
727     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
728
729     memcpy(mbedtls_pk_ec(pk), keypair, sizeof(mbedtls_ecp_keypair));
730
731     mbedtls_x509write_csr_set_key(&csr, &pk);
732
733     mbedtls_x509write_csr_set_md_alg(&csr, MBEDTLS_MD_SHA256);
734
735     result = mbedtls_x509write_csr_pem(&csr, out_csr, length, CryptoRNG, nullptr);
736     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
737     csr_length = strlen(Uint8::to_const_char(out_csr));
738
739 exit:
740     keypair = nullptr;
741     mbedtls_x509write_csr_free(&csr);
742     mbedtls_ecp_keypair_init(mbedtls_pk_ec(pk));
743     mbedtls_pk_free(&pk);
744     _log_mbedTLS_error(result);
745     return error;
746 }
747
748 typedef struct Spake2p_Context
749 {
750     mbedtls_ecp_group curve;
751     const mbedtls_md_info_t * md_info;
752     mbedtls_ecp_point M;
753     mbedtls_ecp_point N;
754     mbedtls_ecp_point X;
755     mbedtls_ecp_point Y;
756     mbedtls_ecp_point L;
757     mbedtls_ecp_point Z;
758     mbedtls_ecp_point V;
759
760     mbedtls_mpi w0;
761     mbedtls_mpi w1;
762     mbedtls_mpi xy;
763     mbedtls_mpi tempbn;
764 } Spake2p_Context;
765
766 static inline Spake2p_Context * to_inner_spake2p_context(Spake2pOpaqueContext * context)
767 {
768     return SafePointerCast<Spake2p_Context *>(context);
769 }
770
771 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::InitInternal(void)
772 {
773     CHIP_ERROR error = CHIP_NO_ERROR;
774     int result       = 0;
775
776     Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
777
778     memset(context, 0, sizeof(Spake2p_Context));
779     mbedtls_ecp_group_init(&context->curve);
780     result = mbedtls_ecp_group_load(&context->curve, MBEDTLS_ECP_DP_SECP256R1);
781     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
782
783     context->md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
784     VerifyOrExit(context->md_info != nullptr, error = CHIP_ERROR_INTERNAL);
785
786     mbedtls_ecp_point_init(&context->M);
787     mbedtls_ecp_point_init(&context->N);
788     mbedtls_ecp_point_init(&context->X);
789     mbedtls_ecp_point_init(&context->Y);
790     mbedtls_ecp_point_init(&context->L);
791     mbedtls_ecp_point_init(&context->V);
792     mbedtls_ecp_point_init(&context->Z);
793     M = &context->M;
794     N = &context->N;
795     X = &context->X;
796     Y = &context->Y;
797     L = &context->L;
798     V = &context->V;
799     Z = &context->Z;
800
801     mbedtls_mpi_init(&context->w0);
802     mbedtls_mpi_init(&context->w1);
803     mbedtls_mpi_init(&context->xy);
804     mbedtls_mpi_init(&context->tempbn);
805     w0     = &context->w0;
806     w1     = &context->w1;
807     xy     = &context->xy;
808     tempbn = &context->tempbn;
809
810     G     = &context->curve.G;
811     order = &context->curve.N;
812
813     return error;
814
815 exit:
816     _log_mbedTLS_error(result);
817
818     FreeImpl();
819     return error;
820 }
821
822 void Spake2p_P256_SHA256_HKDF_HMAC::FreeImpl(void)
823 {
824     Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
825
826     mbedtls_ecp_point_free(&context->M);
827     mbedtls_ecp_point_free(&context->N);
828     mbedtls_ecp_point_free(&context->X);
829     mbedtls_ecp_point_free(&context->Y);
830     mbedtls_ecp_point_free(&context->L);
831     mbedtls_ecp_point_free(&context->Z);
832     mbedtls_ecp_point_free(&context->V);
833
834     mbedtls_mpi_free(&context->w0);
835     mbedtls_mpi_free(&context->w1);
836     mbedtls_mpi_free(&context->xy);
837     mbedtls_mpi_free(&context->tempbn);
838
839     mbedtls_ecp_group_free(&context->curve);
840 }
841
842 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)
843 {
844     CHIP_ERROR error = CHIP_NO_ERROR;
845     int result       = 0;
846
847     mbedtls_md_context_t hmac_ctx;
848     mbedtls_md_init(&hmac_ctx);
849
850     Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
851
852     result = mbedtls_md_setup(&hmac_ctx, context->md_info, 1);
853     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
854
855     result = mbedtls_md_hmac_starts(&hmac_ctx, Uint8::to_const_uchar(key), key_len);
856     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
857
858     result = mbedtls_md_hmac_update(&hmac_ctx, Uint8::to_const_uchar(in), in_len);
859     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
860
861     result = mbedtls_md_hmac_finish(&hmac_ctx, Uint8::to_uchar(out));
862     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
863
864     return error;
865
866 exit:
867     _log_mbedTLS_error(result);
868
869     mbedtls_md_free(&hmac_ctx);
870     return error;
871 }
872
873 /**
874  * This function implements constant time memcmp. It's good practice
875  * to use constant time functions for cryptographic functions.
876  */
877 static inline int constant_time_memcmp(const void * a, const void * b, size_t n)
878 {
879     const uint8_t * A = (const uint8_t *) a;
880     const uint8_t * B = (const uint8_t *) b;
881     uint8_t diff      = 0;
882
883     for (size_t i = 0; i < n; i++)
884     {
885         diff |= (A[i] ^ B[i]);
886     }
887
888     return diff;
889 }
890
891 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::MacVerify(const uint8_t * key, size_t key_len, const uint8_t * mac, size_t mac_len,
892                                                     const uint8_t * in, size_t in_len)
893 {
894     CHIP_ERROR error = CHIP_NO_ERROR;
895     int result       = 0;
896
897     uint8_t computed_mac[kSHA256_Hash_Length];
898
899     VerifyOrExit(mac_len == kSHA256_Hash_Length, error = CHIP_ERROR_INVALID_ARGUMENT);
900
901     error = Mac(key, key_len, in, in_len, computed_mac);
902     SuccessOrExit(error);
903
904     VerifyOrExit(constant_time_memcmp(mac, computed_mac, kSHA256_Hash_Length) == 0, error = CHIP_ERROR_INTERNAL);
905
906 exit:
907     _log_mbedTLS_error(result);
908     return error;
909 }
910
911 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::FELoad(const uint8_t * in, size_t in_len, void * fe)
912 {
913     CHIP_ERROR error = CHIP_NO_ERROR;
914     int result       = 0;
915
916     result = mbedtls_mpi_read_binary((mbedtls_mpi *) fe, Uint8::to_const_uchar(in), in_len);
917     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
918
919     result = mbedtls_mpi_mod_mpi((mbedtls_mpi *) fe, (mbedtls_mpi *) fe, (const mbedtls_mpi *) order);
920     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
921
922 exit:
923     _log_mbedTLS_error(result);
924     return error;
925 }
926
927 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::FEWrite(const void * fe, uint8_t * out, size_t out_len)
928 {
929     if (mbedtls_mpi_write_binary((const mbedtls_mpi *) fe, Uint8::to_uchar(out), out_len) != 0)
930     {
931         return CHIP_ERROR_INTERNAL;
932     }
933
934     return CHIP_NO_ERROR;
935 }
936
937 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::FEGenerate(void * fe)
938 {
939     CHIP_ERROR error = CHIP_NO_ERROR;
940     int result       = 0;
941
942     Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
943
944     result = mbedtls_ecp_gen_privkey(&context->curve, (mbedtls_mpi *) fe, CryptoRNG, nullptr);
945     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
946
947 exit:
948     _log_mbedTLS_error(result);
949     return error;
950 }
951
952 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::FEMul(void * fer, const void * fe1, const void * fe2)
953 {
954     CHIP_ERROR error = CHIP_NO_ERROR;
955     int result       = 0;
956
957     result = mbedtls_mpi_mul_mpi((mbedtls_mpi *) fer, (const mbedtls_mpi *) fe1, (const mbedtls_mpi *) fe2);
958     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
959
960     result = mbedtls_mpi_mod_mpi((mbedtls_mpi *) fer, (mbedtls_mpi *) fer, (const mbedtls_mpi *) order);
961     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
962
963 exit:
964     _log_mbedTLS_error(result);
965     return error;
966 }
967
968 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointLoad(const uint8_t * in, size_t in_len, void * R)
969 {
970     Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
971
972     if (mbedtls_ecp_point_read_binary(&context->curve, (mbedtls_ecp_point *) R, Uint8::to_const_uchar(in), in_len) != 0)
973     {
974         return CHIP_ERROR_INTERNAL;
975     }
976
977     return CHIP_NO_ERROR;
978 }
979
980 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointWrite(const void * R, uint8_t * out, size_t out_len)
981 {
982     memset(out, 0, out_len);
983     size_t mbedtls_out_len = out_len;
984
985     Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
986
987     if (mbedtls_ecp_point_write_binary(&context->curve, (const mbedtls_ecp_point *) R, MBEDTLS_ECP_PF_UNCOMPRESSED,
988                                        &mbedtls_out_len, Uint8::to_uchar(out), out_len) != 0)
989     {
990         return CHIP_ERROR_INTERNAL;
991     }
992
993     return CHIP_NO_ERROR;
994 }
995
996 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointMul(void * R, const void * P1, const void * fe1)
997 {
998     Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
999
1000     if (mbedtls_ecp_mul(&context->curve, (mbedtls_ecp_point *) R, (const mbedtls_mpi *) fe1, (const mbedtls_ecp_point *) P1,
1001                         CryptoRNG, nullptr) != 0)
1002     {
1003         return CHIP_ERROR_INTERNAL;
1004     }
1005
1006     return CHIP_NO_ERROR;
1007 }
1008
1009 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointAddMul(void * R, const void * P1, const void * fe1, const void * P2,
1010                                                       const void * fe2)
1011 {
1012     Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
1013
1014     if (mbedtls_ecp_muladd(&context->curve, (mbedtls_ecp_point *) R, (const mbedtls_mpi *) fe1, (const mbedtls_ecp_point *) P1,
1015                            (const mbedtls_mpi *) fe2, (const mbedtls_ecp_point *) P2) != 0)
1016     {
1017         return CHIP_ERROR_INTERNAL;
1018     }
1019
1020     return CHIP_NO_ERROR;
1021 }
1022
1023 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointInvert(void * R)
1024 {
1025     mbedtls_ecp_point * Rp    = (mbedtls_ecp_point *) R;
1026     Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
1027
1028     if (mbedtls_mpi_sub_mpi(&Rp->Y, &context->curve.P, &Rp->Y) != 0)
1029     {
1030         return CHIP_ERROR_INTERNAL;
1031     }
1032
1033     return CHIP_NO_ERROR;
1034 }
1035
1036 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointCofactorMul(void * R)
1037 {
1038     return CHIP_NO_ERROR;
1039 }
1040
1041 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::ComputeL(uint8_t * Lout, size_t * L_len, const uint8_t * w1in, size_t w1in_len)
1042 {
1043     CHIP_ERROR error = CHIP_NO_ERROR;
1044     int result       = 0;
1045
1046     mbedtls_ecp_group curve;
1047     mbedtls_mpi w1_bn;
1048     mbedtls_ecp_point Ltemp;
1049
1050     mbedtls_ecp_group_init(&curve);
1051     mbedtls_mpi_init(&w1_bn);
1052     mbedtls_ecp_point_init(&Ltemp);
1053
1054     result = mbedtls_ecp_group_load(&curve, MBEDTLS_ECP_DP_SECP256R1);
1055     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
1056
1057     result = mbedtls_mpi_read_binary(&w1_bn, Uint8::to_const_uchar(w1in), w1in_len);
1058     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
1059
1060     result = mbedtls_mpi_mod_mpi(&w1_bn, &w1_bn, &curve.N);
1061     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
1062
1063     result = mbedtls_ecp_mul(&curve, &Ltemp, &w1_bn, &curve.G, CryptoRNG, nullptr);
1064     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
1065
1066     memset(Lout, 0, *L_len);
1067
1068     result = mbedtls_ecp_point_write_binary(&curve, &Ltemp, MBEDTLS_ECP_PF_UNCOMPRESSED, L_len, Uint8::to_uchar(Lout), *L_len);
1069     VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
1070
1071 exit:
1072     _log_mbedTLS_error(result);
1073     mbedtls_ecp_point_free(&Ltemp);
1074     mbedtls_mpi_free(&w1_bn);
1075     mbedtls_ecp_group_free(&curve);
1076
1077     return error;
1078 }
1079
1080 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointIsValid(void * R)
1081 {
1082     Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
1083
1084     if (mbedtls_ecp_check_pubkey(&context->curve, (mbedtls_ecp_point *) R) != 0)
1085     {
1086         return CHIP_ERROR_INTERNAL;
1087     }
1088
1089     return CHIP_NO_ERROR;
1090 }
1091
1092 } // namespace Crypto
1093 } // namespace chip