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