From 0b4813725dbc4abd95cd8da7c00f4c9ffdd3e14c Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Fri, 20 May 2016 12:22:30 +0200 Subject: [PATCH] Add AES CCM example. Change-Id: I1dbb4d481f6ab0c1b373698ae1d6b827b9b6ab82 --- examples/CMakeLists.txt | 14 +- .../{encrypt_aes_gcm.c => encrypt_aes_gcm_ccm.c} | 149 ++++++++++++++++++++- 2 files changed, 154 insertions(+), 9 deletions(-) rename examples/{encrypt_aes_gcm.c => encrypt_aes_gcm_ccm.c} (53%) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index c8461ec..4cf4681 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -43,13 +43,13 @@ FUNCTION(BUILD_EXAMPLE EXAMPLE_NAME SOURCE_FILE) DESTINATION ${EXAMPLES_DIR}) ENDFUNCTION(BUILD_EXAMPLE) -BUILD_EXAMPLE("yaca-example-digest" digest.c) -BUILD_EXAMPLE("yaca-example-encrypt" encrypt.c) -BUILD_EXAMPLE("yaca-example-seal" seal.c) -BUILD_EXAMPLE("yaca-example-encrypt-gcm" encrypt_aes_gcm.c) -BUILD_EXAMPLE("yaca-example-sign" sign.c) -BUILD_EXAMPLE("yaca-example-key-exchange" key_exchange.c) -BUILD_EXAMPLE("yaca-example-key-impexp" key_import_export.c) +BUILD_EXAMPLE("yaca-example-digest" digest.c) +BUILD_EXAMPLE("yaca-example-encrypt" encrypt.c) +BUILD_EXAMPLE("yaca-example-seal" seal.c) +BUILD_EXAMPLE("yaca-example-encrypt-gcm-ccm" encrypt_aes_gcm_ccm.c) +BUILD_EXAMPLE("yaca-example-sign" sign.c) +BUILD_EXAMPLE("yaca-example-key-exchange" key_exchange.c) +BUILD_EXAMPLE("yaca-example-key-impexp" key_import_export.c) INSTALL(FILES ${COMMON_SOURCES} DESTINATION ${EXAMPLES_DIR}) diff --git a/examples/encrypt_aes_gcm.c b/examples/encrypt_aes_gcm_ccm.c similarity index 53% rename from examples/encrypt_aes_gcm.c rename to examples/encrypt_aes_gcm_ccm.c index 7fc0fa0..4ae8ff6 100644 --- a/examples/encrypt_aes_gcm.c +++ b/examples/encrypt_aes_gcm_ccm.c @@ -17,7 +17,7 @@ */ /** - * @file encrypt_aes_gcm.c + * @file encrypt_aes_gcm_ccm.c * @brief */ @@ -26,7 +26,6 @@ #include #include #include -#include #include #include "lorem.h" @@ -60,6 +59,7 @@ void encrypt_decrypt_aes_gcm(void) size_t out_size; size_t rem; + printf("AES GCM 256bit key encryption/decryption\n"); printf("Plain data (16 of %zu bytes): %.16s\n", LOREM4096_SIZE, lorem4096); /* Key generation */ @@ -171,6 +171,150 @@ clean: yaca_key_free(key); } +void encrypt_decrypt_aes_ccm(void) +{ + yaca_enc_algo_e algo = YACA_ENC_AES; + yaca_block_cipher_mode_e bcm = YACA_BCM_CCM; + yaca_key_type_e key_type = YACA_KEY_TYPE_SYMMETRIC; + size_t key_bits = YACA_KEY_256BIT; + size_t iv_bits = YACA_KEY_IV_64BIT; + + yaca_ctx_h ctx = YACA_CTX_NULL; + yaca_key_h key = YACA_KEY_NULL; + yaca_key_h iv = YACA_KEY_NULL; + + char *enc = NULL; + char *dec = NULL; + size_t enc_size; + size_t dec_size; + + char *aad = NULL; + char *tag = NULL; + size_t aad_size = 16; + size_t tag_size = 12; + + size_t block_len; + size_t output_len; + size_t out_size; + size_t rem; + size_t len; + + printf("AES CCM 256bit key encryption/decryption\n"); + printf("Plain data (16 of %zu bytes): %.16s\n", LOREM4096_SIZE, lorem4096); + + /* Key generation */ + if (yaca_key_gen(&key, key_type, key_bits) != 0) + return; + + /* IV generation */ + if (yaca_key_gen(&iv, YACA_KEY_TYPE_IV, iv_bits) != 0) + goto clean; + + if ((aad = yaca_zalloc(aad_size)) == NULL) + goto clean; + + if (yaca_rand_bytes(aad, aad_size) != 0) + goto clean; + + if ((tag = yaca_zalloc(tag_size)) == NULL) + goto clean; + + /* Encryption */ + { + if (yaca_encrypt_init(&ctx, algo, bcm, key, iv) != 0) + goto clean; + + /* Set tag length (optionally) */ + if (yaca_ctx_set_param(ctx, YACA_PARAM_CCM_TAG_LEN, + (void*)&tag_size, sizeof(tag_size)) != 0) + goto clean; + + /* The total plain text length must be passed (only needed if AAD is passed) */ + if (yaca_encrypt_update(ctx, NULL, LOREM4096_SIZE , NULL, &len) != 0) + goto clean; + + if (yaca_ctx_set_param(ctx, YACA_PARAM_CCM_AAD, aad, aad_size) != 0) + goto clean; + + if (yaca_get_block_length(ctx, &block_len) != 0) + goto clean; + + if (yaca_get_output_length(ctx, LOREM4096_SIZE, &output_len) != 0) + goto clean; + + /* Calculate max output: size of update + final chunks */ + enc_size = output_len + block_len; + if ((enc = yaca_malloc(enc_size)) == NULL) + goto clean; + + out_size = enc_size; + if (yaca_encrypt_update(ctx, lorem4096, LOREM4096_SIZE, enc, &out_size) != 0) + goto clean; + + rem = enc_size - out_size; + if (yaca_encrypt_final(ctx, enc + out_size, &rem) != 0) + goto clean; + + enc_size = rem + out_size; + + /* Get the tag after final encryption */ + if (yaca_ctx_get_param(ctx, YACA_PARAM_CCM_TAG, (void**)tag, &tag_size) != 0) + goto clean; + + dump_hex(enc, 16, "Encrypted data (16 of %zu bytes): ", enc_size); + + yaca_ctx_free(ctx); + ctx = YACA_CTX_NULL; + } + + /* Decryption */ + { + if (yaca_decrypt_init(&ctx, algo, bcm, key, iv) != 0) + goto clean; + + /* Set expected tag value */ + if (yaca_ctx_set_param(ctx, YACA_PARAM_CCM_TAG, tag, tag_size) != 0) + goto clean; + + /* The total encrypted text length must be passed (only needed if AAD is passed) */ + if (yaca_decrypt_update(ctx, NULL, enc_size , NULL, &len) != 0) + goto clean; + + if (yaca_ctx_set_param(ctx, YACA_PARAM_CCM_AAD, aad, aad_size) != 0) + goto clean; + + if (yaca_get_block_length(ctx, &block_len) != 0) + goto clean; + + if (yaca_get_output_length(ctx, LOREM4096_SIZE, &output_len) != 0) + goto clean; + + /* Calculate max output: size of update + final chunks */ + dec_size = output_len + block_len; + if ((dec = yaca_malloc(dec_size)) == NULL) + goto clean; + + out_size = dec_size; + /* The tag verify is performed when you call the final yaca_decrypt_update(), + * there is no call to yaca_decrypt_final() */ + if (yaca_decrypt_update(ctx, enc, enc_size, dec, &out_size) != 0) + goto clean; + + dec_size = out_size; + + printf("Decrypted data (16 of %zu bytes): %.16s\n\n", dec_size, dec); + } + +clean: + yaca_free(enc); + yaca_free(dec); + yaca_free(tag); + yaca_free(aad); + yaca_ctx_free(ctx); + yaca_key_free(iv); + yaca_key_free(key); +} + int main() { yaca_debug_set_error_cb(debug_func); @@ -180,6 +324,7 @@ int main() return ret; encrypt_decrypt_aes_gcm(); + encrypt_decrypt_aes_ccm(); yaca_exit(); return ret; -- 2.7.4