Add basic GMAC implementation

This commit is contained in:
Florian Märkl 2019-03-19 23:04:37 +01:00
commit e4d8213842
No known key found for this signature in database
GPG key ID: 125BC8A5A6A1E857
2 changed files with 41 additions and 0 deletions

View file

@ -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)
{

View file

@ -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;
}