3 * Copyright (c) 2020-2021 Project CHIP Authors
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
20 * mbedTLS based implementation of CHIP crypto primitives
23 #include "CHIPCryptoPAL.h"
25 #include <type_traits>
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>
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>
52 #define MAX_ERROR_STR_LEN 128
53 #define NUM_BYTES_IN_SHA256_HASH 32
59 mbedtls_ctr_drbg_context mDRBGCtxt;
60 mbedtls_entropy_context mEntropy;
63 static EntropyContext gsEntropyContext;
65 static void _log_mbedTLS_error(int error_code)
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);
75 static bool _isValidTagLength(size_t tag_length)
77 if (tag_length == 8 || tag_length == 12 || tag_length == 16)
84 static bool _isValidKeyLength(size_t length)
86 // 16 bytes key for AES-CCM-128, 32 for AES-CCM-256
87 if (length == 16 || length == 32)
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)
98 CHIP_ERROR error = CHIP_NO_ERROR;
101 mbedtls_ccm_context context;
102 mbedtls_ccm_init(&context);
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);
114 VerifyOrExit(aad != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
117 // Size of key = key_length * number of bits in a byte (8)
118 // Cast is safe because we called _isValidKeyLength above.
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);
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);
131 mbedtls_ccm_free(&context);
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)
139 CHIP_ERROR error = CHIP_NO_ERROR;
142 mbedtls_ccm_context context;
143 mbedtls_ccm_init(&context);
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);
155 VerifyOrExit(aad != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
158 // Size of key = key_length * number of bits in a byte (8)
159 // Cast is safe because we called _isValidKeyLength above.
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);
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);
172 mbedtls_ccm_free(&context);
176 CHIP_ERROR Hash_SHA256(const uint8_t * data, const size_t data_length, uint8_t * out_buffer)
178 CHIP_ERROR error = CHIP_NO_ERROR;
181 // zero data length hash is supported.
183 VerifyOrExit(out_buffer != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
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);
192 Hash_SHA256_stream::Hash_SHA256_stream(void) {}
194 Hash_SHA256_stream::~Hash_SHA256_stream(void) {}
196 static inline mbedtls_sha256_context * to_inner_hash_sha256_context(HashSHA256OpaqueContext * context)
198 return SafePointerCast<mbedtls_sha256_context *>(context);
201 CHIP_ERROR Hash_SHA256_stream::Begin(void)
203 CHIP_ERROR error = CHIP_NO_ERROR;
206 mbedtls_sha256_context * context = to_inner_hash_sha256_context(&mContext);
208 result = mbedtls_sha256_starts_ret(context, 0);
209 VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
215 CHIP_ERROR Hash_SHA256_stream::AddData(const uint8_t * data, const size_t data_length)
217 CHIP_ERROR error = CHIP_NO_ERROR;
220 mbedtls_sha256_context * context = to_inner_hash_sha256_context(&mContext);
222 result = mbedtls_sha256_update_ret(context, Uint8::to_const_uchar(data), data_length);
223 VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
229 CHIP_ERROR Hash_SHA256_stream::Finish(uint8_t * out_buffer)
231 CHIP_ERROR error = CHIP_NO_ERROR;
234 mbedtls_sha256_context * context = to_inner_hash_sha256_context(&mContext);
236 result = mbedtls_sha256_finish_ret(context, Uint8::to_uchar(out_buffer));
237 VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
243 void Hash_SHA256_stream::Clear(void)
245 memset(this, 0, sizeof(*this));
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)
251 CHIP_ERROR error = CHIP_NO_ERROR;
253 const mbedtls_md_info_t * md;
255 VerifyOrExit(secret != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
256 VerifyOrExit(secret_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
261 VerifyOrExit(salt != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
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);
269 md = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
270 VerifyOrExit(md != nullptr, error = CHIP_ERROR_INTERNAL);
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);
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)
284 CHIP_ERROR error = CHIP_NO_ERROR;
286 const mbedtls_md_info_t * md_info;
287 mbedtls_md_context_t md_ctxt;
288 constexpr int use_hmac = 1;
290 bool free_md_ctxt = false;
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);
300 md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
301 VerifyOrExit(md_info != nullptr, error = CHIP_ERROR_INTERNAL);
303 mbedtls_md_init(&md_ctxt);
306 result = mbedtls_md_setup(&md_ctxt, md_info, use_hmac);
307 VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
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));
312 VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
315 _log_mbedTLS_error(result);
319 mbedtls_md_free(&md_ctxt);
325 static EntropyContext * get_entropy_context()
327 if (!gsEntropyContext.mInitialized)
329 mbedtls_entropy_init(&gsEntropyContext.mEntropy);
330 mbedtls_ctr_drbg_init(&gsEntropyContext.mDRBGCtxt);
332 gsEntropyContext.mInitialized = true;
335 return &gsEntropyContext;
338 static mbedtls_ctr_drbg_context * get_drbg_context()
340 EntropyContext * context = get_entropy_context();
342 mbedtls_ctr_drbg_context * drbgCtxt = &context->mDRBGCtxt;
344 if (!context->mDRBGSeeded)
346 int status = mbedtls_ctr_drbg_seed(drbgCtxt, mbedtls_entropy_func, &context->mEntropy, nullptr, 0);
347 VerifyOrExit(status == 0, _log_mbedTLS_error(status));
349 context->mDRBGSeeded = true;
358 CHIP_ERROR add_entropy_source(entropy_source fn_source, void * p_source, size_t threshold)
360 CHIP_ERROR error = CHIP_NO_ERROR;
362 EntropyContext * entropy_ctxt = nullptr;
364 VerifyOrExit(fn_source != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
366 entropy_ctxt = get_entropy_context();
367 VerifyOrExit(entropy_ctxt != nullptr, error = CHIP_ERROR_INTERNAL);
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);
375 CHIP_ERROR DRBG_get_bytes(uint8_t * out_buffer, const size_t out_length)
377 CHIP_ERROR error = CHIP_NO_ERROR;
380 mbedtls_ctr_drbg_context * drbg_ctxt = nullptr;
382 VerifyOrExit(out_buffer != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
383 VerifyOrExit(out_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
385 drbg_ctxt = get_drbg_context();
386 VerifyOrExit(drbg_ctxt != nullptr, error = CHIP_ERROR_INTERNAL);
388 result = mbedtls_ctr_drbg_random(drbg_ctxt, Uint8::to_uchar(out_buffer), out_length);
389 VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
395 static int CryptoRNG(void * ctxt, uint8_t * out_buffer, size_t out_length)
397 return (chip::Crypto::DRBG_get_bytes(out_buffer, out_length) == CHIP_NO_ERROR) ? 0 : 1;
400 mbedtls_ecp_group_id MapECPGroupId(SupportedECPKeyTypes keyType)
404 case SupportedECPKeyTypes::ECP256R1:
405 return MBEDTLS_ECP_DP_SECP256R1;
407 return MBEDTLS_ECP_DP_NONE;
411 static inline mbedtls_ecp_keypair * to_keypair(P256KeypairContext * context)
413 return SafePointerCast<mbedtls_ecp_keypair *>(context);
416 static inline const mbedtls_ecp_keypair * to_const_keypair(const P256KeypairContext * context)
418 return SafePointerCast<const mbedtls_ecp_keypair *>(context);
421 CHIP_ERROR P256Keypair::ECDSA_sign_msg(const uint8_t * msg, const size_t msg_length, P256ECDSASignature & out_signature)
423 CHIP_ERROR error = CHIP_NO_ERROR;
425 uint8_t hash[NUM_BYTES_IN_SHA256_HASH];
426 size_t siglen = out_signature.Capacity();
428 const mbedtls_ecp_keypair * keypair = to_const_keypair(&mKeypair);
430 mbedtls_ecdsa_context ecdsa_ctxt;
431 mbedtls_ecdsa_init(&ecdsa_ctxt);
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);
437 result = mbedtls_ecdsa_from_keypair(&ecdsa_ctxt, keypair);
438 VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
440 result = mbedtls_sha256_ret(Uint8::to_const_uchar(msg), msg_length, hash, 0);
441 VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
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);
450 mbedtls_ecdsa_free(&ecdsa_ctxt);
451 _log_mbedTLS_error(result);
455 CHIP_ERROR P256Keypair::ECDSA_sign_hash(const uint8_t * hash, const size_t hash_length, P256ECDSASignature & out_signature)
457 CHIP_ERROR error = CHIP_NO_ERROR;
459 size_t siglen = out_signature.Capacity();
461 const mbedtls_ecp_keypair * keypair = to_const_keypair(&mKeypair);
463 mbedtls_ecdsa_context ecdsa_ctxt;
464 mbedtls_ecdsa_init(&ecdsa_ctxt);
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);
470 result = mbedtls_ecdsa_from_keypair(&ecdsa_ctxt, keypair);
471 VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
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);
480 mbedtls_ecdsa_free(&ecdsa_ctxt);
481 _log_mbedTLS_error(result);
485 CHIP_ERROR P256PublicKey::ECDSA_validate_msg_signature(const uint8_t * msg, const size_t msg_length,
486 const P256ECDSASignature & signature) const
488 CHIP_ERROR error = CHIP_NO_ERROR;
490 uint8_t hash[NUM_BYTES_IN_SHA256_HASH];
492 mbedtls_ecp_keypair keypair;
493 mbedtls_ecp_keypair_init(&keypair);
495 mbedtls_ecdsa_context ecdsa_ctxt;
496 mbedtls_ecdsa_init(&ecdsa_ctxt);
498 VerifyOrExit(msg != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
499 VerifyOrExit(msg_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
501 result = mbedtls_ecp_group_load(&keypair.grp, MapECPGroupId(Type()));
502 VerifyOrExit(result == 0, error = CHIP_ERROR_INVALID_ARGUMENT);
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);
507 result = mbedtls_ecdsa_from_keypair(&ecdsa_ctxt, &keypair);
508 VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
510 result = mbedtls_sha256_ret(Uint8::to_const_uchar(msg), msg_length, hash, 0);
511 VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
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);
517 mbedtls_ecp_keypair_free(&keypair);
518 mbedtls_ecdsa_free(&ecdsa_ctxt);
519 _log_mbedTLS_error(result);
523 CHIP_ERROR P256PublicKey::ECDSA_validate_hash_signature(const uint8_t * hash, const size_t hash_length,
524 const P256ECDSASignature & signature) const
526 CHIP_ERROR error = CHIP_NO_ERROR;
529 mbedtls_ecp_keypair keypair;
530 mbedtls_ecp_keypair_init(&keypair);
532 mbedtls_ecdsa_context ecdsa_ctxt;
533 mbedtls_ecdsa_init(&ecdsa_ctxt);
535 VerifyOrExit(hash != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
536 VerifyOrExit(hash_length == NUM_BYTES_IN_SHA256_HASH, error = CHIP_ERROR_INVALID_ARGUMENT);
538 result = mbedtls_ecp_group_load(&keypair.grp, MapECPGroupId(Type()));
539 VerifyOrExit(result == 0, error = CHIP_ERROR_INVALID_ARGUMENT);
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);
544 result = mbedtls_ecdsa_from_keypair(&ecdsa_ctxt, &keypair);
545 VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
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);
551 mbedtls_ecp_keypair_free(&keypair);
552 mbedtls_ecdsa_free(&ecdsa_ctxt);
553 _log_mbedTLS_error(result);
557 CHIP_ERROR P256Keypair::ECDH_derive_secret(const P256PublicKey & remote_public_key, P256ECDHDerivedSecret & out_secret) const
559 CHIP_ERROR error = CHIP_NO_ERROR;
561 size_t secret_length = (out_secret.Length() == 0) ? out_secret.Capacity() : out_secret.Length();
563 mbedtls_ecp_group ecp_grp;
564 mbedtls_ecp_group_init(&ecp_grp);
566 mbedtls_mpi mpi_secret;
567 mbedtls_mpi_init(&mpi_secret);
569 mbedtls_ecp_point ecp_pubkey;
570 mbedtls_ecp_point_init(&ecp_pubkey);
572 const mbedtls_ecp_keypair * keypair = to_const_keypair(&mKeypair);
574 VerifyOrExit(mInitialized, error = CHIP_ERROR_INCORRECT_STATE);
576 result = mbedtls_ecp_group_load(&ecp_grp, MapECPGroupId(remote_public_key.Type()));
577 VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
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);
583 result = mbedtls_ecdh_compute_shared(&ecp_grp, &mpi_secret, &ecp_pubkey, &keypair->d, CryptoRNG, nullptr);
584 VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
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));
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);
599 void ClearSecretData(uint8_t * buf, uint32_t len)
604 CHIP_ERROR P256Keypair::Initialize()
606 CHIP_ERROR error = CHIP_NO_ERROR;
609 size_t pubkey_size = 0;
611 mbedtls_ecp_group_id group = MapECPGroupId(mPublicKey.Type());
613 mbedtls_ecp_keypair * keypair = to_keypair(&mKeypair);
614 mbedtls_ecp_keypair_init(keypair);
616 result = mbedtls_ecp_gen_key(group, keypair, CryptoRNG, nullptr);
617 VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
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);
628 if (keypair != nullptr)
630 mbedtls_ecp_keypair_free(keypair);
634 _log_mbedTLS_error(result);
638 CHIP_ERROR P256Keypair::Serialize(P256SerializedKeypair & output)
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;
647 bbuf.Put(mPublicKey, mPublicKey.Length());
649 VerifyOrExit(bbuf.Available() == sizeof(privkey), error = CHIP_ERROR_INTERNAL);
650 VerifyOrExit(mbedtls_mpi_size(&keypair->d) <= bbuf.Available(), error = CHIP_ERROR_INTERNAL);
652 result = mbedtls_mpi_write_binary(&keypair->d, Uint8::to_uchar(privkey), sizeof(privkey));
653 VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
655 bbuf.Put(privkey, sizeof(privkey));
656 VerifyOrExit(bbuf.Fit(), error = CHIP_ERROR_BUFFER_TOO_SMALL);
658 output.SetLength(bbuf.Needed());
661 memset(privkey, 0, sizeof(privkey));
662 _log_mbedTLS_error(result);
666 CHIP_ERROR P256Keypair::Deserialize(P256SerializedKeypair & input)
668 Encoding::BufferWriter bbuf(mPublicKey, mPublicKey.Length());
671 CHIP_ERROR error = CHIP_NO_ERROR;
673 mbedtls_ecp_keypair * keypair = to_keypair(&mKeypair);
674 mbedtls_ecp_keypair_init(keypair);
676 result = mbedtls_ecp_group_load(&keypair->grp, MapECPGroupId(mPublicKey.Type()));
677 VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
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);
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);
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);
694 _log_mbedTLS_error(result);
698 P256Keypair::~P256Keypair()
702 mbedtls_ecp_keypair * keypair = to_keypair(&mKeypair);
703 mbedtls_ecp_keypair_free(keypair);
707 CHIP_ERROR P256Keypair::NewCertificateSigningRequest(uint8_t * out_csr, size_t & csr_length)
709 CHIP_ERROR error = CHIP_NO_ERROR;
711 size_t length = csr_length;
713 const mbedtls_ecp_keypair * keypair = to_const_keypair(&mKeypair);
715 mbedtls_x509write_csr csr;
716 mbedtls_x509write_csr_init(&csr);
718 mbedtls_pk_context pk;
719 mbedtls_pk_init(&pk);
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);
724 VerifyOrExit(mInitialized, error = CHIP_ERROR_INCORRECT_STATE);
726 result = mbedtls_pk_setup(&pk, pk_info);
727 VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
729 memcpy(mbedtls_pk_ec(pk), keypair, sizeof(mbedtls_ecp_keypair));
731 mbedtls_x509write_csr_set_key(&csr, &pk);
733 mbedtls_x509write_csr_set_md_alg(&csr, MBEDTLS_MD_SHA256);
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));
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);
748 typedef struct Spake2p_Context
750 mbedtls_ecp_group curve;
751 const mbedtls_md_info_t * md_info;
766 static inline Spake2p_Context * to_inner_spake2p_context(Spake2pOpaqueContext * context)
768 return SafePointerCast<Spake2p_Context *>(context);
771 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::InitInternal(void)
773 CHIP_ERROR error = CHIP_NO_ERROR;
776 Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
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);
783 context->md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
784 VerifyOrExit(context->md_info != nullptr, error = CHIP_ERROR_INTERNAL);
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);
801 mbedtls_mpi_init(&context->w0);
802 mbedtls_mpi_init(&context->w1);
803 mbedtls_mpi_init(&context->xy);
804 mbedtls_mpi_init(&context->tempbn);
808 tempbn = &context->tempbn;
810 G = &context->curve.G;
811 order = &context->curve.N;
816 _log_mbedTLS_error(result);
822 void Spake2p_P256_SHA256_HKDF_HMAC::FreeImpl(void)
824 Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
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);
834 mbedtls_mpi_free(&context->w0);
835 mbedtls_mpi_free(&context->w1);
836 mbedtls_mpi_free(&context->xy);
837 mbedtls_mpi_free(&context->tempbn);
839 mbedtls_ecp_group_free(&context->curve);
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)
844 CHIP_ERROR error = CHIP_NO_ERROR;
847 mbedtls_md_context_t hmac_ctx;
848 mbedtls_md_init(&hmac_ctx);
850 Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
852 result = mbedtls_md_setup(&hmac_ctx, context->md_info, 1);
853 VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
855 result = mbedtls_md_hmac_starts(&hmac_ctx, Uint8::to_const_uchar(key), key_len);
856 VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
858 result = mbedtls_md_hmac_update(&hmac_ctx, Uint8::to_const_uchar(in), in_len);
859 VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
861 result = mbedtls_md_hmac_finish(&hmac_ctx, Uint8::to_uchar(out));
862 VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
867 _log_mbedTLS_error(result);
869 mbedtls_md_free(&hmac_ctx);
874 * This function implements constant time memcmp. It's good practice
875 * to use constant time functions for cryptographic functions.
877 static inline int constant_time_memcmp(const void * a, const void * b, size_t n)
879 const uint8_t * A = (const uint8_t *) a;
880 const uint8_t * B = (const uint8_t *) b;
883 for (size_t i = 0; i < n; i++)
885 diff |= (A[i] ^ B[i]);
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)
894 CHIP_ERROR error = CHIP_NO_ERROR;
897 uint8_t computed_mac[kSHA256_Hash_Length];
899 VerifyOrExit(mac_len == kSHA256_Hash_Length, error = CHIP_ERROR_INVALID_ARGUMENT);
901 error = Mac(key, key_len, in, in_len, computed_mac);
902 SuccessOrExit(error);
904 VerifyOrExit(constant_time_memcmp(mac, computed_mac, kSHA256_Hash_Length) == 0, error = CHIP_ERROR_INTERNAL);
907 _log_mbedTLS_error(result);
911 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::FELoad(const uint8_t * in, size_t in_len, void * fe)
913 CHIP_ERROR error = CHIP_NO_ERROR;
916 result = mbedtls_mpi_read_binary((mbedtls_mpi *) fe, Uint8::to_const_uchar(in), in_len);
917 VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
919 result = mbedtls_mpi_mod_mpi((mbedtls_mpi *) fe, (mbedtls_mpi *) fe, (const mbedtls_mpi *) order);
920 VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
923 _log_mbedTLS_error(result);
927 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::FEWrite(const void * fe, uint8_t * out, size_t out_len)
929 if (mbedtls_mpi_write_binary((const mbedtls_mpi *) fe, Uint8::to_uchar(out), out_len) != 0)
931 return CHIP_ERROR_INTERNAL;
934 return CHIP_NO_ERROR;
937 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::FEGenerate(void * fe)
939 CHIP_ERROR error = CHIP_NO_ERROR;
942 Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
944 result = mbedtls_ecp_gen_privkey(&context->curve, (mbedtls_mpi *) fe, CryptoRNG, nullptr);
945 VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
948 _log_mbedTLS_error(result);
952 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::FEMul(void * fer, const void * fe1, const void * fe2)
954 CHIP_ERROR error = CHIP_NO_ERROR;
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);
960 result = mbedtls_mpi_mod_mpi((mbedtls_mpi *) fer, (mbedtls_mpi *) fer, (const mbedtls_mpi *) order);
961 VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
964 _log_mbedTLS_error(result);
968 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointLoad(const uint8_t * in, size_t in_len, void * R)
970 Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
972 if (mbedtls_ecp_point_read_binary(&context->curve, (mbedtls_ecp_point *) R, Uint8::to_const_uchar(in), in_len) != 0)
974 return CHIP_ERROR_INTERNAL;
977 return CHIP_NO_ERROR;
980 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointWrite(const void * R, uint8_t * out, size_t out_len)
982 memset(out, 0, out_len);
983 size_t mbedtls_out_len = out_len;
985 Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
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)
990 return CHIP_ERROR_INTERNAL;
993 return CHIP_NO_ERROR;
996 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointMul(void * R, const void * P1, const void * fe1)
998 Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
1000 if (mbedtls_ecp_mul(&context->curve, (mbedtls_ecp_point *) R, (const mbedtls_mpi *) fe1, (const mbedtls_ecp_point *) P1,
1001 CryptoRNG, nullptr) != 0)
1003 return CHIP_ERROR_INTERNAL;
1006 return CHIP_NO_ERROR;
1009 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointAddMul(void * R, const void * P1, const void * fe1, const void * P2,
1012 Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
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)
1017 return CHIP_ERROR_INTERNAL;
1020 return CHIP_NO_ERROR;
1023 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointInvert(void * R)
1025 mbedtls_ecp_point * Rp = (mbedtls_ecp_point *) R;
1026 Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
1028 if (mbedtls_mpi_sub_mpi(&Rp->Y, &context->curve.P, &Rp->Y) != 0)
1030 return CHIP_ERROR_INTERNAL;
1033 return CHIP_NO_ERROR;
1036 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointCofactorMul(void * R)
1038 return CHIP_NO_ERROR;
1041 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::ComputeL(uint8_t * Lout, size_t * L_len, const uint8_t * w1in, size_t w1in_len)
1043 CHIP_ERROR error = CHIP_NO_ERROR;
1046 mbedtls_ecp_group curve;
1048 mbedtls_ecp_point Ltemp;
1050 mbedtls_ecp_group_init(&curve);
1051 mbedtls_mpi_init(&w1_bn);
1052 mbedtls_ecp_point_init(&Ltemp);
1054 result = mbedtls_ecp_group_load(&curve, MBEDTLS_ECP_DP_SECP256R1);
1055 VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
1057 result = mbedtls_mpi_read_binary(&w1_bn, Uint8::to_const_uchar(w1in), w1in_len);
1058 VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
1060 result = mbedtls_mpi_mod_mpi(&w1_bn, &w1_bn, &curve.N);
1061 VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
1063 result = mbedtls_ecp_mul(&curve, &Ltemp, &w1_bn, &curve.G, CryptoRNG, nullptr);
1064 VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
1066 memset(Lout, 0, *L_len);
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);
1072 _log_mbedTLS_error(result);
1073 mbedtls_ecp_point_free(&Ltemp);
1074 mbedtls_mpi_free(&w1_bn);
1075 mbedtls_ecp_group_free(&curve);
1080 CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointIsValid(void * R)
1082 Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
1084 if (mbedtls_ecp_check_pubkey(&context->curve, (mbedtls_ecp_point *) R) != 0)
1086 return CHIP_ERROR_INTERNAL;
1089 return CHIP_NO_ERROR;
1092 } // namespace Crypto