1386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari/* 2386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * xfm.c 3386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 4386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * Crypto transform implementation 5386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 6386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * David A. McGrew 7386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * Cisco Systems, Inc. 8386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 9386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 10386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#include "cryptoalg.h" 11386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#include "aes_cbc.h" 12386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#include "hmac.h" 13386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#include "crypto_kernel.h" /* for crypto_get_random() */ 14386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 15386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#define KEY_LEN 16 16386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#define ENC_KEY_LEN 16 17386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#define MAC_KEY_LEN 16 18386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#define IV_LEN 16 19386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#define TAG_LEN 12 20386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#define MAX_EXPAND 27 21386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 22386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t 23386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagariaes_128_cbc_hmac_sha1_96_func(void *key, 24386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari void *clear, 25386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned clear_len, 26386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari void *iv, 27386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari void *opaque, 28386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned *opaque_len, 29386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari void *auth_tag) { 30386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari aes_cbc_ctx_t aes_ctx; 31386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari hmac_ctx_t hmac_ctx; 32386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned char enc_key[ENC_KEY_LEN]; 33386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned char mac_key[MAC_KEY_LEN]; 34386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari err_status_t status; 35386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 36386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* check if we're doing authentication only */ 37386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) { 38386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 39386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* perform authentication only */ 40386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 41386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) { 42386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 43386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 44386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * bad parameter - we expect either all three pointers to be NULL, 45386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * or none of those pointers to be NULL 46386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 47386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_fail; 48386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 49386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } else { 50386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 51386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* derive encryption and authentication keys from the input key */ 52386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = hmac_init(&hmac_ctx, key, KEY_LEN); 53386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 54386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key); 55386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 56386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 57386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = hmac_init(&hmac_ctx, key, KEY_LEN); 58386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 59386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key); 60386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 61386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 62386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 63386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* perform encryption and authentication */ 64386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 65386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* set aes key */ 66386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = aes_cbc_context_init(&aes_ctx, key, direction_encrypt); 67386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 68386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 69386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* set iv */ 70386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = crypto_get_random(iv, IV_LEN); 71386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 72386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = aes_cbc_set_iv(&aes_ctx, iv); 73386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 74386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* encrypt the opaque data */ 75386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = aes_cbc_nist_encrypt(&aes_ctx, opaque, opaque_len); 76386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 77386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 78386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* authenticate clear and opaque data */ 79386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN); 80386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 81386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 82386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = hmac_start(&hmac_ctx); 83386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 84386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 85386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = hmac_update(&hmac_ctx, clear, clear_len); 86386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 87386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 88386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, auth_tag); 89386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 90386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 91386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 92386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 93386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_ok; 94386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 95386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 96386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t 97386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagariaes_128_cbc_hmac_sha1_96_inv(void *key, 98386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari void *clear, 99386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned clear_len, 100386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari void *iv, 101386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari void *opaque, 102386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned *opaque_len, 103386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari void *auth_tag) { 104386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari aes_cbc_ctx_t aes_ctx; 105386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari hmac_ctx_t hmac_ctx; 106386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned char enc_key[ENC_KEY_LEN]; 107386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned char mac_key[MAC_KEY_LEN]; 108386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned char tmp_tag[TAG_LEN]; 109386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned char *tag = auth_tag; 110386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari err_status_t status; 111386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari int i; 112386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 113386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* check if we're doing authentication only */ 114386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) { 115386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 116386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* perform authentication only */ 117386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 118386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) { 119386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 120386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 121386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * bad parameter - we expect either all three pointers to be NULL, 122386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * or none of those pointers to be NULL 123386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 124386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_fail; 125386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 126386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } else { 127386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 128386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* derive encryption and authentication keys from the input key */ 129386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = hmac_init(&hmac_ctx, key, KEY_LEN); 130386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 131386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key); 132386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 133386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 134386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = hmac_init(&hmac_ctx, key, KEY_LEN); 135386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 136386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key); 137386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 138386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 139386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* perform encryption and authentication */ 140386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 141386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* set aes key */ 142386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = aes_cbc_context_init(&aes_ctx, key, direction_decrypt); 143386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 144386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 145386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* set iv */ 146386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = rand_source_get_octet_string(iv, IV_LEN); 147386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 148386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = aes_cbc_set_iv(&aes_ctx, iv); 149386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 150386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* encrypt the opaque data */ 151386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = aes_cbc_nist_decrypt(&aes_ctx, opaque, opaque_len); 152386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 153386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 154386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* authenticate clear and opaque data */ 155386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN); 156386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 157386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 158386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = hmac_start(&hmac_ctx); 159386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 160386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 161386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = hmac_update(&hmac_ctx, clear, clear_len); 162386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 163386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 164386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, tmp_tag); 165386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 166386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 167386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* compare the computed tag with the one provided as input */ 168386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari for (i=0; i < TAG_LEN; i++) 169386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (tmp_tag[i] != tag[i]) 170386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_auth_fail; 171386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 172386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 173386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 174386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_ok; 175386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 176386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 177386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 178386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#define ENC 1 179386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 180386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#undef DEBUG 181386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#define DEBUG 0 182386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 183386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t 184386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagariaes_128_cbc_hmac_sha1_96_enc(void *key, 185386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari const void *clear, 186386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned clear_len, 187386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari void *iv, 188386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari void *opaque, 189386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned *opaque_len) { 190386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari aes_cbc_ctx_t aes_ctx; 191386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari hmac_ctx_t hmac_ctx; 192386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned char enc_key[ENC_KEY_LEN]; 193386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned char mac_key[MAC_KEY_LEN]; 194386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned char *auth_tag; 195386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari err_status_t status; 196386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 197386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* check if we're doing authentication only */ 198386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) { 199386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 200386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* perform authentication only */ 201386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 202386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) { 203386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 204386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 205386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * bad parameter - we expect either all three pointers to be NULL, 206386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * or none of those pointers to be NULL 207386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 208386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_fail; 209386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 210386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } else { 211386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 212386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#if DEBUG 213386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("ENC using key %s\n", octet_string_hex_string(key, KEY_LEN)); 214386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 215386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 216386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* derive encryption and authentication keys from the input key */ 217386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = hmac_init(&hmac_ctx, key, KEY_LEN); 218386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 219386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key); 220386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 221386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 222386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = hmac_init(&hmac_ctx, key, KEY_LEN); 223386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 224386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key); 225386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 226386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 227386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 228386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* perform encryption and authentication */ 229386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 230386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* set aes key */ 231386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = aes_cbc_context_init(&aes_ctx, key, direction_encrypt); 232386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 233386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 234386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* set iv */ 235386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = rand_source_get_octet_string(iv, IV_LEN); 236386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 237386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = aes_cbc_set_iv(&aes_ctx, iv); 238386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 239386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 240386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#if DEBUG 241386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("plaintext len: %d\n", *opaque_len); 242386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("iv: %s\n", octet_string_hex_string(iv, IV_LEN)); 243386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("plaintext: %s\n", octet_string_hex_string(opaque, *opaque_len)); 244386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 245386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 246386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#if ENC 247386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* encrypt the opaque data */ 248386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = aes_cbc_nist_encrypt(&aes_ctx, opaque, opaque_len); 249386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 250386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 251386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 252386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#if DEBUG 253386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("ciphertext len: %d\n", *opaque_len); 254386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("ciphertext: %s\n", octet_string_hex_string(opaque, *opaque_len)); 255386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 256386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 257386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 258386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * authenticate clear and opaque data, then write the 259386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * authentication tag to the location immediately following the 260386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * ciphertext 261386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 262386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN); 263386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 264386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 265386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = hmac_start(&hmac_ctx); 266386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 267386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 268386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = hmac_update(&hmac_ctx, clear, clear_len); 269386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 270386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#if DEBUG 271386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("hmac input: %s\n", 272386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari octet_string_hex_string(clear, clear_len)); 273386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 274386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_tag = (unsigned char *)opaque; 275386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_tag += *opaque_len; 276386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, auth_tag); 277386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 278386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#if DEBUG 279386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("hmac input: %s\n", 280386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari octet_string_hex_string(opaque, *opaque_len)); 281386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 282386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* bump up the opaque_len to reflect the authentication tag */ 283386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *opaque_len += TAG_LEN; 284386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 285386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#if DEBUG 286386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("prot data len: %d\n", *opaque_len); 287386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("prot data: %s\n", octet_string_hex_string(opaque, *opaque_len)); 288386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 289386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 290386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 291386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_ok; 292386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 293386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 294386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t 295386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagariaes_128_cbc_hmac_sha1_96_dec(void *key, 296386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari const void *clear, 297386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned clear_len, 298386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari void *iv, 299386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari void *opaque, 300386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned *opaque_len) { 301386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari aes_cbc_ctx_t aes_ctx; 302386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari hmac_ctx_t hmac_ctx; 303386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned char enc_key[ENC_KEY_LEN]; 304386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned char mac_key[MAC_KEY_LEN]; 305386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned char tmp_tag[TAG_LEN]; 306386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned char *auth_tag; 307386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned ciphertext_len; 308386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari err_status_t status; 309386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari int i; 310386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 311386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* check if we're doing authentication only */ 312386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) { 313386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 314386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* perform authentication only */ 315386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 316386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) { 317386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 318386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 319386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * bad parameter - we expect either all three pointers to be NULL, 320386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * or none of those pointers to be NULL 321386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 322386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_fail; 323386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 324386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } else { 325386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#if DEBUG 326386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("DEC using key %s\n", octet_string_hex_string(key, KEY_LEN)); 327386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 328386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 329386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* derive encryption and authentication keys from the input key */ 330386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = hmac_init(&hmac_ctx, key, KEY_LEN); 331386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 332386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key); 333386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 334386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 335386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = hmac_init(&hmac_ctx, key, KEY_LEN); 336386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 337386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key); 338386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 339386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 340386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#if DEBUG 341386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("prot data len: %d\n", *opaque_len); 342386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("prot data: %s\n", octet_string_hex_string(opaque, *opaque_len)); 343386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 344386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 345386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 346386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * set the protected data length to that of the ciphertext, by 347386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * subtracting out the length of the authentication tag 348386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 349386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari ciphertext_len = *opaque_len - TAG_LEN; 350386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 351386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#if DEBUG 352386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("ciphertext len: %d\n", ciphertext_len); 353386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 354386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* verify the authentication tag */ 355386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 356386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 357386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * compute the authentication tag for the clear and opaque data, 358386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * and write it to a temporary location 359386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 360386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN); 361386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 362386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 363386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = hmac_start(&hmac_ctx); 364386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 365386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 366386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = hmac_update(&hmac_ctx, clear, clear_len); 367386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 368386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 369386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#if DEBUG 370386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("hmac input: %s\n", 371386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari octet_string_hex_string(clear, clear_len)); 372386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 373386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 374386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = hmac_compute(&hmac_ctx, opaque, ciphertext_len, TAG_LEN, tmp_tag); 375386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 376386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 377386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#if DEBUG 378386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("hmac input: %s\n", 379386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari octet_string_hex_string(opaque, ciphertext_len)); 380386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 381386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 382386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 383386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * compare the computed tag with the one provided as input (which 384386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * immediately follows the ciphertext) 385386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 386386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_tag = (unsigned char *)opaque; 387386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_tag += ciphertext_len; 388386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#if DEBUG 389386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("auth_tag: %s\n", octet_string_hex_string(auth_tag, TAG_LEN)); 390386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("tmp_tag: %s\n", octet_string_hex_string(tmp_tag, TAG_LEN)); 391386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 392386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari for (i=0; i < TAG_LEN; i++) { 393386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (tmp_tag[i] != auth_tag[i]) 394386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_auth_fail; 395386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 396386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 397386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* bump down the opaque_len to reflect the authentication tag */ 398386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *opaque_len -= TAG_LEN; 399386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 400386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* decrypt the confidential data */ 401386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = aes_cbc_context_init(&aes_ctx, key, direction_decrypt); 402386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 403386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = aes_cbc_set_iv(&aes_ctx, iv); 404386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 405386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 406386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#if DEBUG 407386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("ciphertext: %s\n", octet_string_hex_string(opaque, *opaque_len)); 408386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("iv: %s\n", octet_string_hex_string(iv, IV_LEN)); 409386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 410386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 411386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#if ENC 412386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = aes_cbc_nist_decrypt(&aes_ctx, opaque, &ciphertext_len); 413386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 414386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 415386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 416386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#if DEBUG 417386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("plaintext len: %d\n", ciphertext_len); 418386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("plaintext: %s\n", 419386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari octet_string_hex_string(opaque, ciphertext_len)); 420386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 421386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 422386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* indicate the length of the plaintext */ 423386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *opaque_len = ciphertext_len; 424386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 425386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 426386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_ok; 427386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 428386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 429386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagaricryptoalg_ctx_t cryptoalg_ctx = { 430386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari aes_128_cbc_hmac_sha1_96_enc, 431386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari aes_128_cbc_hmac_sha1_96_dec, 432386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari KEY_LEN, 433386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari IV_LEN, 434386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari TAG_LEN, 435386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari MAX_EXPAND, 436386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari}; 437386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 438386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagaricryptoalg_t cryptoalg = &cryptoalg_ctx; 439386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 440386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#define NULL_TAG_LEN 12 441386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 442386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t 443386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarinull_enc(void *key, 444386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari const void *clear, 445386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned clear_len, 446386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari void *iv, 447386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari void *opaque, 448386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned *opaque_len) { 449386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari int i; 450386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned char *auth_tag; 451386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned char *init_vec = iv; 452386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 453386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* check if we're doing authentication only */ 454386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) { 455386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 456386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* perform authentication only */ 457386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 458386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) { 459386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 460386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 461386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * bad parameter - we expect either all three pointers to be NULL, 462386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * or none of those pointers to be NULL 463386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 464386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_fail; 465386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 466386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } else { 467386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 468386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#if DEBUG 469386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("NULL ENC using key %s\n", octet_string_hex_string(key, KEY_LEN)); 470386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("NULL_TAG_LEN: %d\n", NULL_TAG_LEN); 471386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("plaintext len: %d\n", *opaque_len); 472386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 473386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari for (i=0; i < IV_LEN; i++) 474386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari init_vec[i] = i + (i * 16); 475386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#if DEBUG 476386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("iv: %s\n", 477386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari octet_string_hex_string(iv, IV_LEN)); 478386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("plaintext: %s\n", 479386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari octet_string_hex_string(opaque, *opaque_len)); 480386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 481386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_tag = opaque; 482386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_tag += *opaque_len; 483386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari for (i=0; i < NULL_TAG_LEN; i++) 484386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_tag[i] = i + (i * 16); 485386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *opaque_len += NULL_TAG_LEN; 486386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#if DEBUG 487386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("protected data len: %d\n", *opaque_len); 488386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("protected data: %s\n", 489386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari octet_string_hex_string(opaque, *opaque_len)); 490386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 491386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 492386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 493386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 494386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_ok; 495386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 496386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 497386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t 498386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarinull_dec(void *key, 499386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari const void *clear, 500386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned clear_len, 501386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari void *iv, 502386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari void *opaque, 503386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned *opaque_len) { 504386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned char *auth_tag; 505386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 506386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* check if we're doing authentication only */ 507386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) { 508386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 509386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* perform authentication only */ 510386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 511386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) { 512386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 513386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 514386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * bad parameter - we expect either all three pointers to be NULL, 515386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * or none of those pointers to be NULL 516386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 517386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_fail; 518386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 519386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } else { 520386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 521386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#if DEBUG 522386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("NULL DEC using key %s\n", octet_string_hex_string(key, KEY_LEN)); 523386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 524386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("protected data len: %d\n", *opaque_len); 525386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("protected data: %s\n", 526386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari octet_string_hex_string(opaque, *opaque_len)); 527386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 528386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_tag = opaque; 529386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_tag += (*opaque_len - NULL_TAG_LEN); 530386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#if DEBUG 531386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("iv: %s\n", octet_string_hex_string(iv, IV_LEN)); 532386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 533386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *opaque_len -= NULL_TAG_LEN; 534386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#if DEBUG 535386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("plaintext len: %d\n", *opaque_len); 536386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari printf("plaintext: %s\n", 537386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari octet_string_hex_string(opaque, *opaque_len)); 538386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 539386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 540386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 541386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_ok; 542386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 543386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 544386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagaricryptoalg_ctx_t null_cryptoalg_ctx = { 545386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari null_enc, 546386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari null_dec, 547386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari KEY_LEN, 548386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari IV_LEN, 549386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari NULL_TAG_LEN, 550386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari MAX_EXPAND, 551386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari}; 552386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 553386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagaricryptoalg_t null_cryptoalg = &null_cryptoalg_ctx; 554386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 555386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagariint 556386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagaricryptoalg_get_id(cryptoalg_t c) { 557386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (c == cryptoalg) 558386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return 1; 559386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return 0; 560386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 561386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 562386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagaricryptoalg_t 563386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagaricryptoalg_find_by_id(int id) { 564386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari switch(id) { 565386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case 1: 566386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return cryptoalg; 567386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari default: 568386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari break; 569386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 570386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return 0; 571386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 572