From 89a8042634f88a390bf16adb95418dd9e4511516 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Thu, 19 Mar 2026 18:11:53 +0100 Subject: [PATCH] Added v2 for encryption utilities. Version 1 derives an encryption key without dependence on OTP. Version 2 derives an encryption key with dependence on OTP. Signed-off-by: Pol Henarejos --- src/crypto_utils.c | 24 ++++++++++++++++++++---- src/crypto_utils.h | 5 +++-- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/crypto_utils.c b/src/crypto_utils.c index 84a3213..cdc2b44 100644 --- a/src/crypto_utils.c +++ b/src/crypto_utils.c @@ -80,11 +80,19 @@ void pin_derive_kenc(const uint8_t pin_token[32], uint8_t kenc[32]) { mbedtls_hkdf(SHA256(), pico_serial_hash, sizeof(pico_serial_hash), pin_token, 32, (const uint8_t *)"PIN/ENC", 7, kenc, 32); } +void pin_derive_kenc2(const uint8_t pin_token[32], uint8_t kenc[32]) { + uint8_t kbase[64]; + derive_kbase(kbase); + memcpy(kbase + 32, pin_token, 32); + mbedtls_hkdf(SHA256(), pico_serial_hash, sizeof(pico_serial_hash), kbase, 64, (const uint8_t *)"PIN/ENC2", 8, kenc, 32); + mbedtls_platform_zeroize(kbase, sizeof(kbase)); +} + // ------------------------------------------------------------------ // Encrypt 32-byte device key using AES-256-GCM // Output: [nonce|ciphertext|tag] = 12 + in_len + 16 = 60 bytes // ------------------------------------------------------------------ -int encrypt_with_aad(const uint8_t key[32], const uint8_t *in_buf, size_t in_len, uint8_t *out_buf) { +int encrypt_with_aad(const uint8_t key[32], const uint8_t *in_buf, size_t in_len, uint8_t version, uint8_t *out_buf) { uint8_t *nonce = out_buf; uint8_t *ct = out_buf + 12; uint8_t *tag = out_buf + 12 + in_len; @@ -94,7 +102,11 @@ int encrypt_with_aad(const uint8_t key[32], const uint8_t *in_buf, size_t in_len mbedtls_gcm_context gcm; mbedtls_gcm_init(&gcm); uint8_t kenc[32]; - pin_derive_kenc(key, kenc); + if (version == 2) { + pin_derive_kenc2(key, kenc); + } else { + pin_derive_kenc(key, kenc); + } int rc = mbedtls_gcm_setkey(&gcm, MBEDTLS_CIPHER_ID_AES, kenc, 256); mbedtls_platform_zeroize(kenc, sizeof(kenc)); if (rc != 0) { @@ -111,7 +123,7 @@ int encrypt_with_aad(const uint8_t key[32], const uint8_t *in_buf, size_t in_len // Input: [nonce|ciphertext|tag] = in_len bytes // Output: decrypted = in_len - 12 - 16 bytes // ------------------------------------------------------------------ -int decrypt_with_aad(const uint8_t key[32], const uint8_t *in_buf, size_t in_len, uint8_t *out_buf) { +int decrypt_with_aad(const uint8_t key[32], const uint8_t *in_buf, size_t in_len, uint8_t version, uint8_t *out_buf) { const uint8_t *nonce = in_buf; const uint8_t *ct = in_buf + 12; const uint8_t *tag = in_buf + in_len - 16; @@ -119,7 +131,11 @@ int decrypt_with_aad(const uint8_t key[32], const uint8_t *in_buf, size_t in_len mbedtls_gcm_context gcm; mbedtls_gcm_init(&gcm); uint8_t kenc[32]; - pin_derive_kenc(key, kenc); + if (version == 2) { + pin_derive_kenc2(key, kenc); + } else { + pin_derive_kenc(key, kenc); + } int rc = mbedtls_gcm_setkey(&gcm, MBEDTLS_CIPHER_ID_AES, kenc, 256); mbedtls_platform_zeroize(kenc, sizeof(kenc)); if (rc != 0) { diff --git a/src/crypto_utils.h b/src/crypto_utils.h index c2952b9..8975bb0 100644 --- a/src/crypto_utils.h +++ b/src/crypto_utils.h @@ -43,10 +43,11 @@ extern int ct_memcmp(const void *a, const void *b, size_t n); extern void derive_kbase(uint8_t kbase[32]); extern void derive_kver(const uint8_t *pin, size_t pin_len, uint8_t kver[32]); extern void pin_derive_kenc(const uint8_t pin_token[32], uint8_t kenc[32]); +extern void pin_derive_kenc2(const uint8_t pin_token[32], uint8_t kenc[32]); extern void pin_derive_session(const uint8_t *pin, size_t pin_len, uint8_t pin_token[32]); extern void pin_derive_verifier(const uint8_t *pin, size_t pin_len, uint8_t verifier[32]); -extern int encrypt_with_aad(const uint8_t key[32], const uint8_t *in_buf, size_t in_len, uint8_t *out_buf); -extern int decrypt_with_aad(const uint8_t key[32], const uint8_t *in_buf, size_t in_len, uint8_t *out_buf); +extern int encrypt_with_aad(const uint8_t key[32], const uint8_t *in_buf, size_t in_len, uint8_t version, uint8_t *out_buf); +extern int decrypt_with_aad(const uint8_t key[32], const uint8_t *in_buf, size_t in_len, uint8_t version, uint8_t *out_buf); extern void double_hash_pin(const uint8_t *pin, uint16_t len, uint8_t output[32]); extern void hash_multi(const uint8_t *input, uint16_t len, uint8_t output[32]); extern void hash256(const uint8_t *input, size_t len, uint8_t output[32]);