From e4d8213842b29fe089d688874ca2bc049da9209f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Tue, 19 Mar 2019 23:04:37 +0100 Subject: [PATCH] Add basic GMAC implementation --- lib/include/chiaki/gkcrypt.h | 2 ++ lib/src/gkcrypt.c | 39 ++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/lib/include/chiaki/gkcrypt.h b/lib/include/chiaki/gkcrypt.h index d64c7c7..be5b1d1 100644 --- a/lib/include/chiaki/gkcrypt.h +++ b/lib/include/chiaki/gkcrypt.h @@ -29,6 +29,7 @@ extern "C" { #endif #define CHIAKI_GKCRYPT_BLOCK_SIZE 0x10 +#define CHIAKI_GKCRYPT_GMAC_SIZE 4 typedef struct chiaki_gkcrypt_t { uint8_t *key_buf; @@ -45,6 +46,7 @@ CHIAKI_EXPORT void chiaki_gkcrypt_fini(ChiakiGKCrypt *gkcrypt); CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_gen_key_stream(ChiakiGKCrypt *gkcrypt, size_t key_pos, uint8_t *buf, size_t buf_size); CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_decrypt(ChiakiGKCrypt *gkcrypt, size_t key_pos, uint8_t *buf, size_t buf_size); static inline ChiakiErrorCode chiaki_gkcrypt_encrypt(ChiakiGKCrypt *gkcrypt, size_t key_pos, uint8_t *buf, size_t buf_size) { return chiaki_gkcrypt_decrypt(gkcrypt, key_pos, buf, buf_size); } +CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_gmac(ChiakiGKCrypt *gkcrypt, size_t key_pos, uint8_t *buf, size_t buf_size, uint8_t *gmac_out); static inline ChiakiGKCrypt *chiaki_gkcrypt_new(ChiakiLog *log, size_t key_buf_blocks, uint8_t index, const uint8_t *handshake_key, const uint8_t *ecdh_secret) { diff --git a/lib/src/gkcrypt.c b/lib/src/gkcrypt.c index 4b3a954..e616bd7 100644 --- a/lib/src/gkcrypt.c +++ b/lib/src/gkcrypt.c @@ -150,5 +150,44 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_decrypt(ChiakiGKCrypt *gkcrypt, siz xor_bytes(buf, key_stream + padding_pre, buf_size); free(key_stream); + return CHIAKI_ERR_SUCCESS; +} + +CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_gmac(ChiakiGKCrypt *gkcrypt, size_t key_pos, uint8_t *buf, size_t buf_size, uint8_t *gmac_out) +{ + uint8_t iv[CHIAKI_GKCRYPT_BLOCK_SIZE]; + counter_add(iv, gkcrypt->iv, (int)key_pos); + + uint8_t *key = gkcrypt->key; // TODO: calculate new key? (conditions?) + + EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + if(!ctx) + return CHIAKI_ERR_MEMORY; + + if(!EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, key, iv)) + { + EVP_CIPHER_CTX_free(ctx); + return CHIAKI_ERR_UNKNOWN; + } + + if(!EVP_EncryptUpdate(ctx, NULL, NULL, buf, (int)buf_size)) + { + EVP_CIPHER_CTX_free(ctx); + return CHIAKI_ERR_UNKNOWN; + } + + if(!EVP_EncryptFinal_ex(ctx, NULL, NULL)) + { + EVP_CIPHER_CTX_free(ctx); + return CHIAKI_ERR_UNKNOWN; + } + + if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, CHIAKI_GKCRYPT_GMAC_SIZE, gmac_out)) + { + EVP_CIPHER_CTX_free(ctx); + return CHIAKI_ERR_UNKNOWN; + } + + EVP_CIPHER_CTX_free(ctx); return CHIAKI_ERR_SUCCESS; } \ No newline at end of file