summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/cmac/cmac.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lib/libcrypto/cmac/cmac.c125
1 files changed, 65 insertions, 60 deletions
diff --git a/src/lib/libcrypto/cmac/cmac.c b/src/lib/libcrypto/cmac/cmac.c
index 237ff01b6b..b2f77c59bd 100644
--- a/src/lib/libcrypto/cmac/cmac.c
+++ b/src/lib/libcrypto/cmac/cmac.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: cmac.c,v 1.5 2014/06/12 15:49:28 deraadt Exp $ */ 1/* $OpenBSD: cmac.c,v 1.6 2014/06/21 12:07:02 miod Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project. 3 * project.
4 */ 4 */
@@ -57,8 +57,7 @@
57#include "cryptlib.h" 57#include "cryptlib.h"
58#include <openssl/cmac.h> 58#include <openssl/cmac.h>
59 59
60struct CMAC_CTX_st 60struct CMAC_CTX_st {
61 {
62 /* Cipher context to use */ 61 /* Cipher context to use */
63 EVP_CIPHER_CTX cctx; 62 EVP_CIPHER_CTX cctx;
64 /* Keys k1 and k2 */ 63 /* Keys k1 and k2 */
@@ -70,61 +69,69 @@ struct CMAC_CTX_st
70 unsigned char last_block[EVP_MAX_BLOCK_LENGTH]; 69 unsigned char last_block[EVP_MAX_BLOCK_LENGTH];
71 /* Number of bytes in last block: -1 means context not initialised */ 70 /* Number of bytes in last block: -1 means context not initialised */
72 int nlast_block; 71 int nlast_block;
73 }; 72};
74 73
75 74
76/* Make temporary keys K1 and K2 */ 75/* Make temporary keys K1 and K2 */
77 76
78static void make_kn(unsigned char *k1, unsigned char *l, int bl) 77static void
79 { 78make_kn(unsigned char *k1, unsigned char *l, int bl)
79{
80 int i; 80 int i;
81
81 /* Shift block to left, including carry */ 82 /* Shift block to left, including carry */
82 for (i = 0; i < bl; i++) 83 for (i = 0; i < bl; i++) {
83 {
84 k1[i] = l[i] << 1; 84 k1[i] = l[i] << 1;
85 if (i < bl - 1 && l[i + 1] & 0x80) 85 if (i < bl - 1 && l[i + 1] & 0x80)
86 k1[i] |= 1; 86 k1[i] |= 1;
87 } 87 }
88 /* If MSB set fixup with R */ 88 /* If MSB set fixup with R */
89 if (l[0] & 0x80) 89 if (l[0] & 0x80)
90 k1[bl - 1] ^= bl == 16 ? 0x87 : 0x1b; 90 k1[bl - 1] ^= bl == 16 ? 0x87 : 0x1b;
91 } 91}
92 92
93CMAC_CTX *CMAC_CTX_new(void) 93CMAC_CTX *
94 { 94CMAC_CTX_new(void)
95{
95 CMAC_CTX *ctx; 96 CMAC_CTX *ctx;
97
96 ctx = malloc(sizeof(CMAC_CTX)); 98 ctx = malloc(sizeof(CMAC_CTX));
97 if (!ctx) 99 if (!ctx)
98 return NULL; 100 return NULL;
99 EVP_CIPHER_CTX_init(&ctx->cctx); 101 EVP_CIPHER_CTX_init(&ctx->cctx);
100 ctx->nlast_block = -1; 102 ctx->nlast_block = -1;
101 return ctx; 103 return ctx;
102 } 104}
103 105
104void CMAC_CTX_cleanup(CMAC_CTX *ctx) 106void
105 { 107CMAC_CTX_cleanup(CMAC_CTX *ctx)
108{
106 EVP_CIPHER_CTX_cleanup(&ctx->cctx); 109 EVP_CIPHER_CTX_cleanup(&ctx->cctx);
107 OPENSSL_cleanse(ctx->tbl, EVP_MAX_BLOCK_LENGTH); 110 OPENSSL_cleanse(ctx->tbl, EVP_MAX_BLOCK_LENGTH);
108 OPENSSL_cleanse(ctx->k1, EVP_MAX_BLOCK_LENGTH); 111 OPENSSL_cleanse(ctx->k1, EVP_MAX_BLOCK_LENGTH);
109 OPENSSL_cleanse(ctx->k2, EVP_MAX_BLOCK_LENGTH); 112 OPENSSL_cleanse(ctx->k2, EVP_MAX_BLOCK_LENGTH);
110 OPENSSL_cleanse(ctx->last_block, EVP_MAX_BLOCK_LENGTH); 113 OPENSSL_cleanse(ctx->last_block, EVP_MAX_BLOCK_LENGTH);
111 ctx->nlast_block = -1; 114 ctx->nlast_block = -1;
112 } 115}
113 116
114EVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx) 117EVP_CIPHER_CTX *
115 { 118CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx)
119{
116 return &ctx->cctx; 120 return &ctx->cctx;
117 } 121}
118 122
119void CMAC_CTX_free(CMAC_CTX *ctx) 123void
120 { 124CMAC_CTX_free(CMAC_CTX *ctx)
125{
121 CMAC_CTX_cleanup(ctx); 126 CMAC_CTX_cleanup(ctx);
122 free(ctx); 127 free(ctx);
123 } 128}
124 129
125int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in) 130int
126 { 131CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in)
132{
127 int bl; 133 int bl;
134
128 if (in->nlast_block == -1) 135 if (in->nlast_block == -1)
129 return 0; 136 return 0;
130 if (!EVP_CIPHER_CTX_copy(&out->cctx, &in->cctx)) 137 if (!EVP_CIPHER_CTX_copy(&out->cctx, &in->cctx))
@@ -136,15 +143,16 @@ int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in)
136 memcpy(out->last_block, in->last_block, bl); 143 memcpy(out->last_block, in->last_block, bl);
137 out->nlast_block = in->nlast_block; 144 out->nlast_block = in->nlast_block;
138 return 1; 145 return 1;
139 } 146}
140 147
141int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, 148int
142 const EVP_CIPHER *cipher, ENGINE *impl) 149CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
143 { 150 const EVP_CIPHER *cipher, ENGINE *impl)
151{
144 static unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH]; 152 static unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH];
153
145 /* All zeros means restart */ 154 /* All zeros means restart */
146 if (!key && !cipher && !impl && keylen == 0) 155 if (!key && !cipher && !impl && keylen == 0) {
147 {
148 /* Not initialised */ 156 /* Not initialised */
149 if (ctx->nlast_block == -1) 157 if (ctx->nlast_block == -1)
150 return 0; 158 return 0;
@@ -153,14 +161,14 @@ int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
153 memset(ctx->tbl, 0, EVP_CIPHER_CTX_block_size(&ctx->cctx)); 161 memset(ctx->tbl, 0, EVP_CIPHER_CTX_block_size(&ctx->cctx));
154 ctx->nlast_block = 0; 162 ctx->nlast_block = 0;
155 return 1; 163 return 1;
156 } 164 }
157 /* Initialiase context */ 165 /* Initialiase context */
158 if (cipher && !EVP_EncryptInit_ex(&ctx->cctx, cipher, impl, NULL, NULL)) 166 if (cipher && !EVP_EncryptInit_ex(&ctx->cctx, cipher, impl, NULL, NULL))
159 return 0; 167 return 0;
160 /* Non-NULL key means initialisation complete */ 168 /* Non-NULL key means initialisation complete */
161 if (key) 169 if (key) {
162 {
163 int bl; 170 int bl;
171
164 if (!EVP_CIPHER_CTX_cipher(&ctx->cctx)) 172 if (!EVP_CIPHER_CTX_cipher(&ctx->cctx))
165 return 0; 173 return 0;
166 if (!EVP_CIPHER_CTX_set_key_length(&ctx->cctx, keylen)) 174 if (!EVP_CIPHER_CTX_set_key_length(&ctx->cctx, keylen))
@@ -179,12 +187,13 @@ int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
179 /* Zero tbl so resume works */ 187 /* Zero tbl so resume works */
180 memset(ctx->tbl, 0, bl); 188 memset(ctx->tbl, 0, bl);
181 ctx->nlast_block = 0; 189 ctx->nlast_block = 0;
182 }
183 return 1;
184 } 190 }
191 return 1;
192}
185 193
186int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen) 194int
187 { 195CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen)
196{
188 const unsigned char *data = in; 197 const unsigned char *data = in;
189 size_t bl; 198 size_t bl;
190 199
@@ -194,9 +203,9 @@ int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen)
194 return 1; 203 return 1;
195 bl = EVP_CIPHER_CTX_block_size(&ctx->cctx); 204 bl = EVP_CIPHER_CTX_block_size(&ctx->cctx);
196 /* Copy into partial block if we need to */ 205 /* Copy into partial block if we need to */
197 if (ctx->nlast_block > 0) 206 if (ctx->nlast_block > 0) {
198 {
199 size_t nleft; 207 size_t nleft;
208
200 nleft = bl - ctx->nlast_block; 209 nleft = bl - ctx->nlast_block;
201 if (dlen < nleft) 210 if (dlen < nleft)
202 nleft = dlen; 211 nleft = dlen;
@@ -210,24 +219,23 @@ int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen)
210 /* Else not final block so encrypt it */ 219 /* Else not final block so encrypt it */
211 if (!EVP_Cipher(&ctx->cctx, ctx->tbl, ctx->last_block,bl)) 220 if (!EVP_Cipher(&ctx->cctx, ctx->tbl, ctx->last_block,bl))
212 return 0; 221 return 0;
213 } 222 }
214 /* Encrypt all but one of the complete blocks left */ 223 /* Encrypt all but one of the complete blocks left */
215 while(dlen > bl) 224 while (dlen > bl) {
216 {
217 if (!EVP_Cipher(&ctx->cctx, ctx->tbl, data, bl)) 225 if (!EVP_Cipher(&ctx->cctx, ctx->tbl, data, bl))
218 return 0; 226 return 0;
219 dlen -= bl; 227 dlen -= bl;
220 data += bl; 228 data += bl;
221 } 229 }
222 /* Copy any data left to last block buffer */ 230 /* Copy any data left to last block buffer */
223 memcpy(ctx->last_block, data, dlen); 231 memcpy(ctx->last_block, data, dlen);
224 ctx->nlast_block = dlen; 232 ctx->nlast_block = dlen;
225 return 1; 233 return 1;
234}
226 235
227 } 236int
228 237CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen)
229int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen) 238{
230 {
231 int i, bl, lb; 239 int i, bl, lb;
232 240
233 if (ctx->nlast_block == -1) 241 if (ctx->nlast_block == -1)
@@ -238,29 +246,26 @@ int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen)
238 return 1; 246 return 1;
239 lb = ctx->nlast_block; 247 lb = ctx->nlast_block;
240 /* Is last block complete? */ 248 /* Is last block complete? */
241 if (lb == bl) 249 if (lb == bl) {
242 {
243 for (i = 0; i < bl; i++) 250 for (i = 0; i < bl; i++)
244 out[i] = ctx->last_block[i] ^ ctx->k1[i]; 251 out[i] = ctx->last_block[i] ^ ctx->k1[i];
245 } 252 } else {
246 else
247 {
248 ctx->last_block[lb] = 0x80; 253 ctx->last_block[lb] = 0x80;
249 if (bl - lb > 1) 254 if (bl - lb > 1)
250 memset(ctx->last_block + lb + 1, 0, bl - lb - 1); 255 memset(ctx->last_block + lb + 1, 0, bl - lb - 1);
251 for (i = 0; i < bl; i++) 256 for (i = 0; i < bl; i++)
252 out[i] = ctx->last_block[i] ^ ctx->k2[i]; 257 out[i] = ctx->last_block[i] ^ ctx->k2[i];
253 } 258 }
254 if (!EVP_Cipher(&ctx->cctx, out, out, bl)) 259 if (!EVP_Cipher(&ctx->cctx, out, out, bl)) {
255 {
256 OPENSSL_cleanse(out, bl); 260 OPENSSL_cleanse(out, bl);
257 return 0; 261 return 0;
258 }
259 return 1;
260 } 262 }
263 return 1;
264}
261 265
262int CMAC_resume(CMAC_CTX *ctx) 266int
263 { 267CMAC_resume(CMAC_CTX *ctx)
268{
264 if (ctx->nlast_block == -1) 269 if (ctx->nlast_block == -1)
265 return 0; 270 return 0;
266 /* The buffer "tbl" containes the last fully encrypted block 271 /* The buffer "tbl" containes the last fully encrypted block
@@ -270,4 +275,4 @@ int CMAC_resume(CMAC_CTX *ctx)
270 * CMAC to continue after calling CMAC_Final(). 275 * CMAC to continue after calling CMAC_Final().
271 */ 276 */
272 return EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, ctx->tbl); 277 return EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, ctx->tbl);
273 } 278}