From 236c6e17cbe66c96ec84087b3f1663f145142c13 Mon Sep 17 00:00:00 2001 From: Zhi Guan Date: Mon, 13 Feb 2023 11:52:24 +0800 Subject: [PATCH] Add AEAD modes --- CMakeLists.txt | 1 + include/gmssl/aead.h | 19 +-- src/aead.c | 330 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 342 insertions(+), 8 deletions(-) create mode 100644 src/aead.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 385cfe9c..6c28c291 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,7 @@ set(src src/pbkdf2.c src/gf128.c src/gcm.c + src/aead.c src/pkcs8.c src/ec.c src/rsa.c diff --git a/include/gmssl/aead.h b/include/gmssl/aead.h index 5828f3a0..158fc5b8 100644 --- a/include/gmssl/aead.h +++ b/include/gmssl/aead.h @@ -12,6 +12,9 @@ #include #include +#include +#include +#include #ifdef __cplusplus extern "C" { @@ -19,8 +22,10 @@ extern "C" { typedef struct { - SM4_CBC_CTX cbc_ctx; - SM3_HMAC_CTX hmac_ctx; + SM4_CBC_CTX enc_ctx; + SM3_HMAC_CTX mac_ctx; + uint8_t mac[SM3_HMAC_SIZE]; + size_t maclen; } SM4_CBC_SM3_HMAC_CTX; int sm4_cbc_sm3_hmac_encrypt_init(SM4_CBC_SM3_HMAC_CTX *ctx, @@ -36,8 +41,10 @@ int sm4_cbc_sm3_hmac_decrypt_finish(SM4_CBC_SM3_HMAC_CTX *ctx, uint8_t *out, siz typedef struct { - SM4_CTR_CTX ctr_ctx; - SM3_HMAC_CTX hmac_ctx; + SM4_CTR_CTX enc_ctx; + SM3_HMAC_CTX mac_ctx; + uint8_t mac[SM3_HMAC_SIZE]; + size_t maclen; } SM4_CTR_SM3_HMAC_CTX; int sm4_ctr_sm3_hmac_encrypt_init(SM4_CTR_SM3_HMAC_CTX *ctx, @@ -74,10 +81,6 @@ int sm4_gcm_decrypt_finish(SM4_GCM_CTX *ctx, uint8_t *out, size_t *outlen); typedef struct { } ZUC_WITH_MAC_CTX; -int zuc_encrypt_init(ZUC_CTX *ctx, const uint8_t key[ZUC_KEY_SIZE], const uint8_t iv[ZUC_IV_SIZE]); -int zuc_encrypt_update(ZUC_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); -int zuc_encrypt_finish(ZUC_CTX *ctx, uint8_t *out, size_t *outlen); - int zuc_with_mac_encrypt_init(ZUC_WITH_MAC_CTX *ctx, const uint8_t key[ZUC_KEY_SIZE], const uint8_t iv[ZUC_IV_SIZE], const uint8_t *aad, size_t aadlen); diff --git a/src/aead.c b/src/aead.c new file mode 100644 index 00000000..d331cd54 --- /dev/null +++ b/src/aead.c @@ -0,0 +1,330 @@ +/* + * Copyright 2014-2023 The GmSSL Project. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ + + +#include +#include +#include +#include +#include + + +int sm4_cbc_sm3_hmac_encrypt_init(SM4_CBC_SM3_HMAC_CTX *ctx, + const uint8_t key[SM4_KEY_SIZE + SM3_HMAC_SIZE], const uint8_t iv[SM4_BLOCK_SIZE], + const uint8_t *aad, size_t aadlen) +{ + if (sm4_cbc_encrypt_init(&ctx->enc_ctx, key, iv) != 1) { + error_print(); + return -1; + } + sm3_hmac_init(&ctx->mac_ctx, key + SM4_KEY_SIZE, SM3_HMAC_SIZE); + if (aad && aadlen) { + sm3_hmac_update(&ctx->mac_ctx, aad, aadlen); + } + return 1; +} + +int sm4_cbc_sm3_hmac_encrypt_update(SM4_CBC_SM3_HMAC_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) +{ + if (sm4_cbc_encrypt_update(&ctx->enc_ctx, in, inlen, out, outlen) != 1) { + error_print(); + return -1; + } + sm3_hmac_update(&ctx->mac_ctx, out, *outlen); + return 1; +} + +int sm4_cbc_sm3_hmac_encrypt_finish(SM4_CBC_SM3_HMAC_CTX *ctx, uint8_t *out, size_t *outlen) +{ + if (sm4_cbc_encrypt_finish(&ctx->enc_ctx, out, outlen) != 1) { + error_print(); + return -1; + } + sm3_hmac_update(&ctx->mac_ctx, out, *outlen); + sm3_hmac_finish(&ctx->mac_ctx, out + *outlen); + *outlen += SM3_HMAC_SIZE; + return 1; +} + +int sm4_cbc_sm3_hmac_decrypt_init(SM4_CBC_SM3_HMAC_CTX *ctx, + const uint8_t key[SM4_KEY_SIZE + SM3_HMAC_SIZE], const uint8_t iv[SM4_BLOCK_SIZE], + const uint8_t *aad, size_t aadlen) +{ + if (sm4_cbc_decrypt_init(&ctx->enc_ctx, key, iv) != 1) { + error_print(); + return -1; + } + sm3_hmac_init(&ctx->mac_ctx, key + SM4_KEY_SIZE, SM3_HMAC_SIZE); + if (aad && aadlen) { + sm3_hmac_update(&ctx->mac_ctx, aad, aadlen); + } + return 1; +} + +int sm4_cbc_sm3_hmac_decrypt_update(SM4_CBC_SM3_HMAC_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) +{ + size_t len; + + if (ctx->maclen > SM3_HMAC_SIZE) { + error_print(); + return -1; + } + + if (ctx->maclen < SM3_HMAC_SIZE) { + len = SM3_HMAC_SIZE - ctx->maclen; + if (inlen <= len) { + memcpy(ctx->mac + ctx->maclen, in, inlen); + ctx->maclen += inlen; + return 1; + } else { + memcpy(ctx->mac + ctx->maclen, in, len); + in += len; + inlen -= len; + } + } + + if (inlen <= SM3_HMAC_SIZE) { + sm3_hmac_update(&ctx->mac_ctx, ctx->mac, inlen); + if (sm4_cbc_decrypt_update(&ctx->enc_ctx, ctx->mac, inlen, out, outlen) != 1) { + error_print(); + return -1; + } + len = SM3_HMAC_SIZE - inlen; + memcpy(ctx->mac, ctx->mac + inlen, len); + memcpy(ctx->mac + len, in, inlen); + } else { + sm3_hmac_update(&ctx->mac_ctx, ctx->mac, SM3_HMAC_SIZE); + if (sm4_cbc_decrypt_update(&ctx->enc_ctx, ctx->mac, SM3_HMAC_SIZE, out, outlen) != 1) { + error_print(); + return -1; + } + out += *outlen; + + inlen -= SM3_HMAC_SIZE; + sm3_hmac_update(&ctx->mac_ctx, in, inlen); + if (sm4_cbc_decrypt_update(&ctx->enc_ctx, in, inlen, out, &len) != 1) { + error_print(); + return -1; + } + *outlen += len; + memcpy(ctx->mac, in + inlen, SM3_HMAC_SIZE); + } + return 1; +} + +int sm4_cbc_sm3_hmac_decrypt_finish(SM4_CBC_SM3_HMAC_CTX *ctx, uint8_t *out, size_t *outlen) +{ + uint8_t mac[SM3_HMAC_SIZE]; + + if (ctx->maclen != SM3_HMAC_SIZE) { + error_print(); + return -1; + } + sm3_hmac_finish(&ctx->mac_ctx, mac); + if (sm4_cbc_decrypt_finish(&ctx->enc_ctx, out, outlen) != 1) { + error_print(); + return -1; + } + if (memcmp(mac, ctx->mac, SM3_HMAC_SIZE) != 0) { + error_print(); + return -1; + } + return 1; +} + +int sm4_ctr_sm3_hmac_encrypt_init(SM4_CTR_SM3_HMAC_CTX *ctx, + const uint8_t key[SM4_KEY_SIZE + SM3_HMAC_SIZE], const uint8_t iv[SM4_BLOCK_SIZE], + const uint8_t *aad, size_t aadlen) +{ + if (sm4_ctr_encrypt_init(&ctx->enc_ctx, key, iv) != 1) { + error_print(); + return -1; + } + sm3_hmac_init(&ctx->mac_ctx, key + SM4_KEY_SIZE, SM3_HMAC_SIZE); + if (aad && aadlen) { + sm3_hmac_update(&ctx->mac_ctx, aad, aadlen); + } + return 1; +} + +int sm4_ctr_sm3_hmac_encrypt_update(SM4_CTR_SM3_HMAC_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) +{ + if (sm4_ctr_encrypt_update(&ctx->enc_ctx, in, inlen, out, outlen) != 1) { + error_print(); + return -1; + } + sm3_hmac_update(&ctx->mac_ctx, out, *outlen); + return 1; +} + +int sm4_ctr_sm3_hmac_encrypt_finish(SM4_CTR_SM3_HMAC_CTX *ctx, uint8_t *out, size_t *outlen) +{ + if (sm4_ctr_encrypt_finish(&ctx->enc_ctx, out, outlen) != 1) { + error_print(); + return -1; + } + sm3_hmac_update(&ctx->mac_ctx, out, *outlen); + sm3_hmac_finish(&ctx->mac_ctx, out + *outlen); + *outlen += SM3_HMAC_SIZE; + return 1; +} + +int sm4_ctr_sm3_hmac_decrypt_init(SM4_CTR_SM3_HMAC_CTX *ctx, + const uint8_t key[SM4_KEY_SIZE + SM3_HMAC_SIZE], const uint8_t iv[SM4_BLOCK_SIZE], + const uint8_t *aad, size_t aadlen) +{ + if (sm4_ctr_decrypt_init(&ctx->enc_ctx, key, iv) != 1) { + error_print(); + return -1; + } + sm3_hmac_init(&ctx->mac_ctx, key + SM4_KEY_SIZE, SM3_HMAC_SIZE); + if (aad && aadlen) { + sm3_hmac_update(&ctx->mac_ctx, aad, aadlen); + } + return 1; +} + +int sm4_ctr_sm3_hmac_decrypt_update(SM4_CTR_SM3_HMAC_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) +{ + size_t len; + + if (ctx->maclen > SM3_HMAC_SIZE) { + error_print(); + return -1; + } + + if (ctx->maclen < SM3_HMAC_SIZE) { + len = SM3_HMAC_SIZE - ctx->maclen; + if (inlen <= len) { + memcpy(ctx->mac + ctx->maclen, in, inlen); + ctx->maclen += inlen; + return 1; + } else { + memcpy(ctx->mac + ctx->maclen, in, len); + in += len; + inlen -= len; + } + } + + if (inlen <= SM3_HMAC_SIZE) { + sm3_hmac_update(&ctx->mac_ctx, ctx->mac, inlen); + if (sm4_ctr_decrypt_update(&ctx->enc_ctx, ctx->mac, inlen, out, outlen) != 1) { + error_print(); + return -1; + } + len = SM3_HMAC_SIZE - inlen; + memcpy(ctx->mac, ctx->mac + inlen, len); + memcpy(ctx->mac + len, in, inlen); + } else { + sm3_hmac_update(&ctx->mac_ctx, ctx->mac, SM3_HMAC_SIZE); + if (sm4_ctr_decrypt_update(&ctx->enc_ctx, ctx->mac, SM3_HMAC_SIZE, out, outlen) != 1) { + error_print(); + return -1; + } + out += *outlen; + + inlen -= SM3_HMAC_SIZE; + sm3_hmac_update(&ctx->mac_ctx, in, inlen); + if (sm4_ctr_decrypt_update(&ctx->enc_ctx, in, inlen, out, &len) != 1) { + error_print(); + return -1; + } + *outlen += len; + memcpy(ctx->mac, in + inlen, SM3_HMAC_SIZE); + } + return 1; +} + +int sm4_ctr_sm3_hmac_decrypt_finish(SM4_CTR_SM3_HMAC_CTX *ctx, uint8_t *out, size_t *outlen) +{ + uint8_t mac[SM3_HMAC_SIZE]; + + if (ctx->maclen != SM3_HMAC_SIZE) { + error_print(); + return -1; + } + sm3_hmac_finish(&ctx->mac_ctx, mac); + if (sm4_ctr_decrypt_finish(&ctx->enc_ctx, out, outlen) != 1) { + error_print(); + return -1; + } + if (memcmp(mac, ctx->mac, SM3_HMAC_SIZE) != 0) { + error_print(); + return -1; + } + return 1; +} + +int sm4_gcm_encrypt_init(SM4_GCM_CTX *ctx, + const uint8_t key[SM4_KEY_SIZE], const uint8_t *iv, size_t ivlen, + const uint8_t *aad, size_t aadlen) +{ + return -1; +} + +int sm4_gcm_encrypt_update(SM4_GCM_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) +{ + return -1; +} + +int sm4_gcm_encrypt_finish(SM4_GCM_CTX *ctx, uint8_t *out, size_t *outlen) +{ + return -1; +} + +int sm4_gcm_decrypt_init(SM4_GCM_CTX *ctx, + const uint8_t key[SM4_KEY_SIZE], const uint8_t *iv, size_t ivlen, + const uint8_t *aad, size_t aadlen) +{ + return -1; +} + +int sm4_gcm_decrypt_update(SM4_GCM_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) +{ + return -1; +} + +int sm4_gcm_decrypt_finish(SM4_GCM_CTX *ctx, uint8_t *out, size_t *outlen) +{ + return -1; +} + +int zuc_with_mac_encrypt_init(ZUC_WITH_MAC_CTX *ctx, + const uint8_t key[ZUC_KEY_SIZE], const uint8_t iv[ZUC_IV_SIZE], + const uint8_t *aad, size_t aadlen) +{ + return -1; +} + +int zuc_with_mac_encrypt_update(ZUC_WITH_MAC_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) +{ + return -1; +} + +int zuc_with_mac_encrypt_finish(ZUC_WITH_MAC_CTX *ctx, uint8_t *out, size_t *outlen) +{ + return -1; +} + +int zuc_with_mac_decrypt_init(ZUC_WITH_MAC_CTX *ctx, + const uint8_t key[ZUC_KEY_SIZE], const uint8_t iv[ZUC_IV_SIZE], + const uint8_t *aad, size_t aadlen) +{ + return -1; +} + +int zuc_with_mac_decrypt_update(ZUC_WITH_MAC_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) +{ + return -1; +} + +int zuc_with_mac_decrypt_finish(ZUC_WITH_MAC_CTX *ctx, uint8_t *out, size_t *outlen) +{ + return -1; +}