10#include <mbedtls/ctr_drbg.h>
11#include <mbedtls/ecdsa.h>
12#include <mbedtls/ecp.h>
13#include <mbedtls/entropy.h>
14#include <mbedtls/md.h>
15#include <mbedtls/sha256.h>
17namespace ndn::crypto {
20 if (data ==
nullptr || out ==
nullptr) {
21 return Error::InvalidParam;
24 mbedtls_sha256_context ctx;
25 mbedtls_sha256_init(&ctx);
27 int ret = mbedtls_sha256_starts(&ctx, 0);
29 mbedtls_sha256_free(&ctx);
30 return Error::DecodeFailed;
33 ret = mbedtls_sha256_update(&ctx, data, len);
35 mbedtls_sha256_free(&ctx);
36 return Error::DecodeFailed;
39 ret = mbedtls_sha256_finish(&ctx, out);
40 mbedtls_sha256_free(&ctx);
42 return (ret == 0) ? Error::Success : Error::DecodeFailed;
45Error hmacSha256(
const uint8_t* key,
size_t keyLen,
const uint8_t* data,
size_t dataLen,
47 if (key ==
nullptr || data ==
nullptr || out ==
nullptr) {
48 return Error::InvalidParam;
51 const mbedtls_md_info_t* mdInfo = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
52 if (mdInfo ==
nullptr) {
53 return Error::DecodeFailed;
56 int ret = mbedtls_md_hmac(mdInfo, key, keyLen, data, dataLen, out);
57 return (ret == 0) ? Error::Success : Error::DecodeFailed;
61 if (lhs ==
nullptr || rhs ==
nullptr) {
65 volatile uint8_t result = 0;
66 for (
size_t i = 0; i < len; ++i) {
67 result |= lhs[i] ^ rhs[i];
73 if (privKey ==
nullptr || pubKey ==
nullptr) {
74 return Error::InvalidParam;
77 mbedtls_entropy_context entropy;
78 mbedtls_ctr_drbg_context ctrDrbg;
79 mbedtls_ecdsa_context ecdsa;
81 mbedtls_entropy_init(&entropy);
82 mbedtls_ctr_drbg_init(&ctrDrbg);
83 mbedtls_ecdsa_init(&ecdsa);
85 Error err = Error::Success;
87 const char* pers =
"ndn_ecdsa_keygen";
90 int ret = mbedtls_ctr_drbg_seed(&ctrDrbg, mbedtls_entropy_func, &entropy,
91 reinterpret_cast<const unsigned char*
>(pers), strlen(pers));
93 err = Error::DecodeFailed;
98 ret = mbedtls_ecdsa_genkey(&ecdsa, MBEDTLS_ECP_DP_SECP256R1, mbedtls_ctr_drbg_random, &ctrDrbg);
100 err = Error::DecodeFailed;
107 err = Error::DecodeFailed;
112 ret = mbedtls_ecp_write_public_key(&ecdsa, MBEDTLS_ECP_PF_UNCOMPRESSED, &pubKeyLen, pubKey,
115 err = Error::DecodeFailed;
120 mbedtls_ecdsa_free(&ecdsa);
121 mbedtls_ctr_drbg_free(&ctrDrbg);
122 mbedtls_entropy_free(&entropy);
128 if (privKey ==
nullptr || data ==
nullptr || sig ==
nullptr || sigLen ==
nullptr) {
129 return Error::InvalidParam;
132 mbedtls_entropy_context entropy;
133 mbedtls_ctr_drbg_context ctrDrbg;
134 mbedtls_ecdsa_context ecdsa;
136 mbedtls_entropy_init(&entropy);
137 mbedtls_ctr_drbg_init(&ctrDrbg);
138 mbedtls_ecdsa_init(&ecdsa);
140 Error err = Error::Success;
142 const char* pers =
"ndn_ecdsa_sign";
145 int ret = mbedtls_ctr_drbg_seed(&ctrDrbg, mbedtls_entropy_func, &entropy,
146 reinterpret_cast<const unsigned char*
>(pers), strlen(pers));
148 err = Error::DecodeFailed;
155 err = Error::DecodeFailed;
160 err =
sha256(data, dataLen, hash);
161 if (err != Error::Success) {
166 ret = mbedtls_ecdsa_write_signature(&ecdsa, MBEDTLS_MD_SHA256, hash,
sizeof(hash), sig,
170 err = Error::DecodeFailed;
175 mbedtls_ecdsa_free(&ecdsa);
176 mbedtls_ctr_drbg_free(&ctrDrbg);
177 mbedtls_entropy_free(&entropy);
181bool ecdsaP256Verify(
const uint8_t* pubKey,
const uint8_t* data,
size_t dataLen,
const uint8_t* sig,
183 if (pubKey ==
nullptr || data ==
nullptr || sig ==
nullptr || sigLen == 0) {
187 mbedtls_ecdsa_context ecdsa;
188 mbedtls_ecp_group grp;
191 mbedtls_ecdsa_init(&ecdsa);
192 mbedtls_ecp_group_init(&grp);
193 mbedtls_ecp_point_init(&Q);
199 int ret = mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP256R1);
211 ret = mbedtls_ecp_set_public_key(MBEDTLS_ECP_DP_SECP256R1, &ecdsa, &Q);
217 if (
sha256(data, dataLen, hash) != Error::Success) {
222 ret = mbedtls_ecdsa_read_signature(&ecdsa, hash,
sizeof(hash), sig, sigLen);
226 mbedtls_ecp_point_free(&Q);
227 mbedtls_ecp_group_free(&grp);
228 mbedtls_ecdsa_free(&ecdsa);
NDN cryptographic utilities.
Error ecdsaP256GenerateKeyPair(uint8_t *privKey, uint8_t *pubKey)
Generate an ECDSA P-256 key pair.
Error hmacSha256(const uint8_t *key, size_t keyLen, const uint8_t *data, size_t dataLen, uint8_t *out)
Compute HMAC-SHA256.
bool ecdsaP256Verify(const uint8_t *pubKey, const uint8_t *data, size_t dataLen, const uint8_t *sig, size_t sigLen)
Verify an ECDSA P-256 signature.
bool constantTimeCompare(const uint8_t *lhs, const uint8_t *rhs, size_t len)
Compare two buffers in constant time.
Error ecdsaP256Sign(const uint8_t *privKey, const uint8_t *data, size_t dataLen, uint8_t *sig, size_t *sigLen)
Sign with ECDSA P-256.
Error sha256(const uint8_t *data, size_t len, uint8_t *out)
Compute SHA-256 hash.
NDN signature types and constants.
constexpr size_t ECDSA_P256_PUBKEY_SIZE
ECDSA P-256 public key size (uncompressed form)
constexpr size_t ECDSA_P256_SIG_MAX_SIZE
ECDSA P-256 signature max size (DER format)
constexpr size_t ECDSA_P256_PRIVKEY_SIZE
ECDSA P-256 private key size.
constexpr size_t SHA256_DIGEST_SIZE
SHA-256 digest size (bytes)