1 #ifndef NDNPH_PORT_MBED_COMMON_HPP
2 #define NDNPH_PORT_MBED_COMMON_HPP
5 #include "../keychain/iv.hpp"
7 #include <mbedtls/bignum.h>
8 #include <mbedtls/ecdh.h>
9 #include <mbedtls/ecp.h>
10 #include <mbedtls/gcm.h>
11 #include <mbedtls/md.h>
12 #include <mbedtls/sha256.h>
14 #ifndef MBEDTLS_ECDSA_DETERMINISTIC
15 #error MBEDTLS_ECDSA_DETERMINISTIC must be declared
18 #if MBEDTLS_VERSION_MAJOR >= 3
19 #define NDNPH_MBEDTLS_RET2(func) func
21 #define NDNPH_MBEDTLS_RET2(func) func##_ret
39 mbedtls_sha256_init(&m_ctx);
44 mbedtls_sha256_free(&m_ctx);
47 void update(
const uint8_t* chunk,
size_t size) {
57 mbedtls_sha256_context m_ctx;
66 template<mbedtls_md_type_t mdType,
size_t mdSize>
70 explicit Hmac(
const uint8_t* key,
size_t keyLen) {
71 mbedtls_md_init(&m_ctx);
72 m_ok = mbedtls_md_setup(&m_ctx, mbedtls_md_info_from_type(mdType), 1) == 0 &&
73 mbedtls_md_hmac_starts(&m_ctx, key, keyLen) == 0;
77 mbedtls_md_free(&m_ctx);
81 void update(
const uint8_t* chunk,
size_t size) {
82 m_ok = m_ok && mbedtls_md_hmac_update(&m_ctx, chunk, size) == 0;
90 bool final(uint8_t result[mdSize]) {
92 m_ok && mbedtls_md_hmac_finish(&m_ctx, result) == 0 && mbedtls_md_hmac_reset(&m_ctx) == 0;
97 mbedtls_md_context_t m_ctx;
106 mbedtls_mpi_init(&m_value);
110 explicit Mpi(
const mbedtls_mpi* src)
112 mbedtls_mpi_copy(&m_value, src);
116 explicit Mpi(mbedtls_mpi_sint src)
118 mbedtls_mpi_lset(&m_value, src);
122 mbedtls_mpi_free(&m_value);
125 operator mbedtls_mpi*() {
129 operator const mbedtls_mpi*()
const {
141 mbedtls_mpi_swap(&m_value, &y.m_value);
154 mbedtls_ecp_point_init(&m_value);
161 mbedtls_ecp_copy(&m_value, q);
166 mbedtls_ecp_point_free(&m_value);
169 operator mbedtls_ecp_point*() {
173 operator const mbedtls_ecp_point*()
const {
180 bool writeBinary(mbedtls_ecp_group* group, uint8_t* room,
size_t length)
const {
181 size_t actualLength = 0;
182 return mbedtls_ecp_point_write_binary(group, *
this, MBEDTLS_ECP_PF_UNCOMPRESSED, &actualLength,
183 room, length) == 0 &&
184 actualLength == length;
189 if (room ==
nullptr) {
198 bool readBinary(mbedtls_ecp_group* group,
const uint8_t* value,
size_t length) {
199 return mbedtls_ecp_point_read_binary(group, *
this, value, length) == 0 &&
200 mbedtls_ecp_check_pubkey(group, *
this) == 0;
208 mbedtls_ecp_point m_value;
212 template<
typename Curve>
235 using PvtLen = std::integral_constant<size_t, 32>;
236 using PubLen = std::integral_constant<size_t, 65>;
243 int res = mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP256R1);
246 mbedtls_ecp_group grp;
255 static bool ecdh(
const mbedtls_mpi* pvt,
const mbedtls_ecp_point* pub,
SharedSecret& shared) {
257 return mbedtls_ecdh_compute_shared(
group(), z, pub, pvt,
rng,
nullptr) == 0 &&
258 mbedtls_mpi_write_binary(z, shared.data(), shared.size()) == 0;
269 template<
int keyBits>
272 static_assert(keyBits == 128 || keyBits == 256,
"");
273 using Key = std::array<uint8_t, keyBits / 8>;
275 using TagLen = std::integral_constant<size_t, 16>;
278 mbedtls_gcm_init(&m_ctx);
282 mbedtls_gcm_free(&m_ctx);
292 bool import(
const Key& key) {
293 m_ok = mbedtls_gcm_setkey(&m_ctx, MBEDTLS_CIPHER_ID_AES, key.data(), keyBits) == 0 &&
308 template<
typename Encrypted>
311 checkEncryptedMessage<Encrypted>();
313 auto place = Encrypted::prependInPlace(encoder, plaintext.
size());
316 bool ok = m_ok && !!encoder && m_ivEncrypt.
write(place.iv) &&
317 mbedtls_gcm_crypt_and_tag(&m_ctx, MBEDTLS_GCM_ENCRYPT, plaintext.
size(), place.iv,
318 IvLen::value, aad, aadLen, plaintext.
begin(),
319 place.ciphertext, TagLen::value, place.tag) == 0 &&
343 template<
typename Encrypted>
346 checkEncryptedMessage<Encrypted>();
347 uint8_t* plaintext = region.
alloc(encrypted.ciphertext.size());
349 m_ok && m_ivDecrypt.
check(encrypted.iv.data(), encrypted.ciphertext.size()) &&
350 plaintext !=
nullptr &&
351 mbedtls_gcm_auth_decrypt(&m_ctx, encrypted.ciphertext.size(), encrypted.iv.data(),
352 encrypted.iv.size(), aad, aadLen, encrypted.tag.data(),
353 encrypted.tag.size(), encrypted.ciphertext.begin(), plaintext) == 0;
355 region.
free(plaintext, encrypted.ciphertext.size());
358 return tlv::Value(plaintext, encrypted.ciphertext.size());
366 template<
typename Encrypted>
367 static void checkEncryptedMessage() {
368 static_assert(Encrypted::IvLen::value == IvLen::value,
"");
369 static_assert(Encrypted::TagLen::value == TagLen::value,
"");
373 mbedtls_gcm_context m_ctx;
static bool generate(uint8_t *output, size_t count)
AES-GCM Initialization Vector generator and checker.
Definition: iv.hpp:18
bool check(const uint8_t *iv, size_t size)
Check received IV.
Definition: iv.hpp:59
std::integral_constant< size_t, 12 > IvLen
IV length.
Definition: iv.hpp:21
bool write(uint8_t room[12])
Write IV to room .
Definition: iv.hpp:33
bool randomize()
Randomize the random number portion.
Definition: iv.hpp:27
bool advance(size_t size)
Advance the counter portion.
Definition: iv.hpp:43
Decoded TLV.
Definition: decoder.hpp:13
size_t length
Definition: decoder.hpp:39
const uint8_t * value
Definition: decoder.hpp:40
TLV encoder that accepts items in reverse order.
Definition: encoder.hpp:10
void trim() const
Release unused space to the Region.
Definition: encoder.hpp:58
void discard()
Release all space to the Region.
Definition: encoder.hpp:72
uint8_t * prependRoom(size_t size)
Make room to prepend an object.
Definition: encoder.hpp:90
void setError()
Indicate an error has occurred.
Definition: encoder.hpp:166
Region-based memory allocator thats owns memory of NDNph objects.
Definition: region.hpp:9
uint8_t * alloc(size_t size)
Allocate a buffer with no alignment requirement.
Definition: region.hpp:27
bool free(const uint8_t *first, const uint8_t *last)
Deallocate (part of) last allocated buffer.
Definition: region.hpp:51
AES-GCM secret key.
Definition: mbed-common.hpp:270
AesGcm & operator=(const AesGcm &)=delete
tlv::Value encrypt(Region ®ion, tlv::Value plaintext, const uint8_t *aad=nullptr, size_t aadLen=0)
Encrypt to encrypted-message.
Definition: mbed-common.hpp:309
AesGcm()
Definition: mbed-common.hpp:277
~AesGcm()
Definition: mbed-common.hpp:281
tlv::Value decrypt(Region ®ion, const Encrypted &encrypted, const uint8_t *aad=nullptr, size_t aadLen=0)
Decrypt from encrypted-message.
Definition: mbed-common.hpp:344
AesGcm(const AesGcm &)=delete
std::integral_constant< size_t, 16 > TagLen
Definition: mbed-common.hpp:275
std::array< uint8_t, keyBits/8 > Key
Definition: mbed-common.hpp:273
void clearDecryptIvChecker()
Definition: mbed-common.hpp:361
AesGcmIvHelper::IvLen IvLen
Definition: mbed-common.hpp:274
EC point associated with a curve.
Definition: mbed-common.hpp:213
bool readBinary(const uint8_t *value, size_t length)
Definition: mbed-common.hpp:223
bool decodeFrom(const Decoder::Tlv &d)
Definition: mbed-common.hpp:227
void encodeTo(Encoder &encoder) const
Definition: mbed-common.hpp:219
bool writeBinary(uint8_t room[Curve::PubLen::value]) const
Definition: mbed-common.hpp:215
EC point.
Definition: mbed-common.hpp:150
~EcPoint()
Definition: mbed-common.hpp:165
EcPoint(const mbedtls_ecp_point *q)
Construct from EC point.
Definition: mbed-common.hpp:158
EcPoint & operator=(const EcPoint &)=delete
Copy assignment is disallowed due to lack of error handling.
void encodeTo(mbedtls_ecp_group *group, Encoder &encoder, size_t length) const
Definition: mbed-common.hpp:187
bool decodeFrom(mbedtls_ecp_group *group, const Decoder::Tlv &d)
Definition: mbed-common.hpp:203
bool readBinary(mbedtls_ecp_group *group, const uint8_t *value, size_t length)
Definition: mbed-common.hpp:198
EcPoint()
Construct zero.
Definition: mbed-common.hpp:153
bool writeBinary(mbedtls_ecp_group *group, uint8_t *room, size_t length) const
Definition: mbed-common.hpp:180
HMAC algorithm.
Definition: mbed-common.hpp:67
~Hmac()
Definition: mbed-common.hpp:76
void update(const uint8_t *chunk, size_t size)
Append bytes into hash state.
Definition: mbed-common.hpp:81
Hmac(const uint8_t *key, size_t keyLen)
Start HMAC operation and set key.
Definition: mbed-common.hpp:70
Multi-Precision Integer.
Definition: mbed-common.hpp:102
Mpi()
Construct zero.
Definition: mbed-common.hpp:105
Mpi & operator=(const Mpi &)=delete
Copy assignment is disallowed due to lack of error handling.
Mpi(const mbedtls_mpi *src)
Construct from MPI.
Definition: mbed-common.hpp:110
Mpi & operator=(Mpi &&y)
Move assignment.
Definition: mbed-common.hpp:140
Mpi(mbedtls_mpi_sint src)
Construct from integer.
Definition: mbed-common.hpp:116
~Mpi()
Definition: mbed-common.hpp:121
EC curve P256.
Definition: mbed-common.hpp:233
static mbedtls_ecp_group * group()
Definition: mbed-common.hpp:240
std::integral_constant< size_t, 74 > MaxSigLen
Definition: mbed-common.hpp:237
std::array< uint8_t, PvtLen::value > SharedSecret
ECDH shared secret buffer.
Definition: mbed-common.hpp:252
static bool ecdh(const mbedtls_mpi *pvt, const mbedtls_ecp_point *pub, SharedSecret &shared)
Compute ECDH shared secret.
Definition: mbed-common.hpp:255
std::integral_constant< size_t, 65 > PubLen
Definition: mbed-common.hpp:236
std::integral_constant< size_t, 32 > PvtLen
Definition: mbed-common.hpp:235
SHA256 hash function.
Definition: mbed-common.hpp:36
Sha256()
Definition: mbed-common.hpp:38
~Sha256()
Definition: mbed-common.hpp:43
void update(const uint8_t *chunk, size_t size)
Definition: mbed-common.hpp:47
A sequence of bytes, usually TLV-VALUE.
Definition: value.hpp:11
const uint8_t * begin() const
Definition: value.hpp:38
size_t size() const
Definition: value.hpp:46
#define NDNPH_ASSERT(x)
Definition: common.hpp:30
#define NDNPH_SHA256_LEN
SHA256 digest length.
Definition: common.hpp:34
#define NDNPH_MBEDTLS_RET2(func)
Definition: mbed-common.hpp:21
void output(const Encodable &packet, std::ostream &os=std::cout)
Write an Encodable to output stream.
Definition: io.hpp:33
int rng(void *, uint8_t *output, size_t count)
Random number generator for various Mbed TLS library functions.
Definition: mbed-common.hpp:30