File
Blob: firmware/platform/crypto_aes.c
| 1 | #include <string.h> |
| 2 | #include "radio_bridge.h" |
| 3 | #include "esp_err.h" |
| 4 | #include "mbedtls/aes.h" |
| 5 | #include "mbedtls/gcm.h" |
| 6 | #include "mbedtls/platform_util.h" |
| 7 | |
| 8 | static int valid_key(size_t length) |
| 9 | { |
| 10 | return length == 16 || length == 32; |
| 11 | } |
| 12 | |
| 13 | int32_t radio_crypto_aes_ctr(const uint8_t *key, size_t key_length, const uint8_t iv[16], |
| 14 | const uint8_t *input, size_t length, uint8_t *output, size_t capacity) |
| 15 | { |
| 16 | if (!valid_key(key_length) || capacity < length) |
| 17 | return ESP_ERR_INVALID_ARG; |
| 18 | mbedtls_aes_context context; |
| 19 | mbedtls_aes_init(&context); |
| 20 | uint8_t counter[16], stream[16] = {0}; |
| 21 | size_t offset = 0; |
| 22 | memcpy(counter, iv, sizeof(counter)); |
| 23 | int result = mbedtls_aes_setkey_enc(&context, key, key_length * 8); |
| 24 | if (!result) |
| 25 | result = mbedtls_aes_crypt_ctr(&context, length, &offset, counter, stream, input, output); |
| 26 | mbedtls_aes_free(&context); |
| 27 | mbedtls_platform_zeroize(stream, sizeof(stream)); |
| 28 | return result; |
| 29 | } |
| 30 | |
| 31 | int32_t radio_crypto_aes_ecb(const uint8_t *key, size_t key_length, const uint8_t input[16], |
| 32 | uint8_t output[16]) |
| 33 | { |
| 34 | if (!valid_key(key_length)) |
| 35 | return ESP_ERR_INVALID_ARG; |
| 36 | mbedtls_aes_context context; |
| 37 | mbedtls_aes_init(&context); |
| 38 | int result = mbedtls_aes_setkey_enc(&context, key, key_length * 8); |
| 39 | if (!result) |
| 40 | result = mbedtls_aes_crypt_ecb(&context, MBEDTLS_AES_ENCRYPT, input, output); |
| 41 | mbedtls_aes_free(&context); |
| 42 | return result; |
| 43 | } |
| 44 | |
| 45 | int32_t radio_crypto_aes_gcm(int32_t decrypt, const uint8_t *key, size_t key_length, |
| 46 | const uint8_t iv[12], const uint8_t *aad, size_t aad_length, |
| 47 | const uint8_t *input, size_t length, uint8_t *output, size_t capacity) |
| 48 | { |
| 49 | if (!valid_key(key_length) || (decrypt && length < 16)) |
| 50 | return ESP_ERR_INVALID_ARG; |
| 51 | size_t clear_length = decrypt ? length - 16 : length; |
| 52 | if (clear_length > 16384 || aad_length > 65536 || capacity < clear_length + (decrypt ? 0 : 16)) |
| 53 | return ESP_ERR_INVALID_SIZE; |
| 54 | mbedtls_gcm_context context; |
| 55 | mbedtls_gcm_init(&context); |
| 56 | int result = mbedtls_gcm_setkey(&context, MBEDTLS_CIPHER_ID_AES, key, key_length * 8); |
| 57 | if (!result && decrypt) |
| 58 | result = mbedtls_gcm_auth_decrypt(&context, clear_length, iv, 12, aad, aad_length, |
| 59 | input + clear_length, 16, input, output); |
| 60 | else if (!result) |
| 61 | result = mbedtls_gcm_crypt_and_tag(&context, MBEDTLS_GCM_ENCRYPT, clear_length, iv, 12, aad, |
| 62 | aad_length, input, output, 16, output + clear_length); |
| 63 | mbedtls_gcm_free(&context); |
| 64 | if (result && decrypt) |
| 65 | mbedtls_platform_zeroize(output, clear_length); |
| 66 | return result; |
| 67 | } |