]>
git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/cmac/cmac.c
2 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
5 /* ====================================================================
6 * Copyright (c) 2010 The OpenSSL Project. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
34 * 6. Redistributions of any form whatsoever must retain the following
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
57 #include "internal/cryptlib.h"
58 #include <openssl/cmac.h>
61 /* Cipher context to use */
64 unsigned char k1
[EVP_MAX_BLOCK_LENGTH
];
65 unsigned char k2
[EVP_MAX_BLOCK_LENGTH
];
67 unsigned char tbl
[EVP_MAX_BLOCK_LENGTH
];
68 /* Last (possibly partial) block */
69 unsigned char last_block
[EVP_MAX_BLOCK_LENGTH
];
70 /* Number of bytes in last block: -1 means context not initialised */
74 /* Make temporary keys K1 and K2 */
76 static void make_kn(unsigned char *k1
, const unsigned char *l
, int bl
)
79 unsigned char c
= l
[0], carry
= c
>> 7, cnext
;
81 /* Shift block to left, including carry */
82 for (i
= 0; i
< bl
- 1; i
++, c
= cnext
)
83 k1
[i
] = (c
<< 1) | ((cnext
= l
[i
+ 1]) >> 7);
85 /* If MSB set fixup with R */
86 k1
[i
] = (c
<< 1) ^ ((0 - carry
) & (bl
== 16 ? 0x87 : 0x1b));
89 CMAC_CTX
*CMAC_CTX_new(void)
93 ctx
= OPENSSL_malloc(sizeof(*ctx
));
96 ctx
->cctx
= EVP_CIPHER_CTX_new();
97 if (ctx
->cctx
== NULL
) {
101 ctx
->nlast_block
= -1;
105 void CMAC_CTX_cleanup(CMAC_CTX
*ctx
)
107 EVP_CIPHER_CTX_free(ctx
->cctx
);
108 OPENSSL_cleanse(ctx
->tbl
, EVP_MAX_BLOCK_LENGTH
);
109 OPENSSL_cleanse(ctx
->k1
, EVP_MAX_BLOCK_LENGTH
);
110 OPENSSL_cleanse(ctx
->k2
, EVP_MAX_BLOCK_LENGTH
);
111 OPENSSL_cleanse(ctx
->last_block
, EVP_MAX_BLOCK_LENGTH
);
112 ctx
->nlast_block
= -1;
115 EVP_CIPHER_CTX
*CMAC_CTX_get0_cipher_ctx(CMAC_CTX
*ctx
)
120 void CMAC_CTX_free(CMAC_CTX
*ctx
)
124 CMAC_CTX_cleanup(ctx
);
128 int CMAC_CTX_copy(CMAC_CTX
*out
, const CMAC_CTX
*in
)
131 if (in
->nlast_block
== -1)
133 if (!EVP_CIPHER_CTX_copy(out
->cctx
, in
->cctx
))
135 bl
= EVP_CIPHER_CTX_block_size(in
->cctx
);
136 memcpy(out
->k1
, in
->k1
, bl
);
137 memcpy(out
->k2
, in
->k2
, bl
);
138 memcpy(out
->tbl
, in
->tbl
, bl
);
139 memcpy(out
->last_block
, in
->last_block
, bl
);
140 out
->nlast_block
= in
->nlast_block
;
144 int CMAC_Init(CMAC_CTX
*ctx
, const void *key
, size_t keylen
,
145 const EVP_CIPHER
*cipher
, ENGINE
*impl
)
147 static const unsigned char zero_iv
[EVP_MAX_BLOCK_LENGTH
] = { 0 };
148 /* All zeros means restart */
149 if (!key
&& !cipher
&& !impl
&& keylen
== 0) {
150 /* Not initialised */
151 if (ctx
->nlast_block
== -1)
153 if (!EVP_EncryptInit_ex(ctx
->cctx
, NULL
, NULL
, NULL
, zero_iv
))
155 memset(ctx
->tbl
, 0, EVP_CIPHER_CTX_block_size(ctx
->cctx
));
156 ctx
->nlast_block
= 0;
159 /* Initialiase context */
160 if (cipher
&& !EVP_EncryptInit_ex(ctx
->cctx
, cipher
, impl
, NULL
, NULL
))
162 /* Non-NULL key means initialisation complete */
165 if (!EVP_CIPHER_CTX_cipher(ctx
->cctx
))
167 if (!EVP_CIPHER_CTX_set_key_length(ctx
->cctx
, keylen
))
169 if (!EVP_EncryptInit_ex(ctx
->cctx
, NULL
, NULL
, key
, zero_iv
))
171 bl
= EVP_CIPHER_CTX_block_size(ctx
->cctx
);
172 if (!EVP_Cipher(ctx
->cctx
, ctx
->tbl
, zero_iv
, bl
))
174 make_kn(ctx
->k1
, ctx
->tbl
, bl
);
175 make_kn(ctx
->k2
, ctx
->k1
, bl
);
176 OPENSSL_cleanse(ctx
->tbl
, bl
);
177 /* Reset context again ready for first data block */
178 if (!EVP_EncryptInit_ex(ctx
->cctx
, NULL
, NULL
, NULL
, zero_iv
))
180 /* Zero tbl so resume works */
181 memset(ctx
->tbl
, 0, bl
);
182 ctx
->nlast_block
= 0;
187 int CMAC_Update(CMAC_CTX
*ctx
, const void *in
, size_t dlen
)
189 const unsigned char *data
= in
;
191 if (ctx
->nlast_block
== -1)
195 bl
= EVP_CIPHER_CTX_block_size(ctx
->cctx
);
196 /* Copy into partial block if we need to */
197 if (ctx
->nlast_block
> 0) {
199 nleft
= bl
- ctx
->nlast_block
;
202 memcpy(ctx
->last_block
+ ctx
->nlast_block
, data
, nleft
);
204 ctx
->nlast_block
+= nleft
;
205 /* If no more to process return */
209 /* Else not final block so encrypt it */
210 if (!EVP_Cipher(ctx
->cctx
, ctx
->tbl
, ctx
->last_block
, bl
))
213 /* Encrypt all but one of the complete blocks left */
215 if (!EVP_Cipher(ctx
->cctx
, ctx
->tbl
, data
, bl
))
220 /* Copy any data left to last block buffer */
221 memcpy(ctx
->last_block
, data
, dlen
);
222 ctx
->nlast_block
= dlen
;
227 int CMAC_Final(CMAC_CTX
*ctx
, unsigned char *out
, size_t *poutlen
)
230 if (ctx
->nlast_block
== -1)
232 bl
= EVP_CIPHER_CTX_block_size(ctx
->cctx
);
233 *poutlen
= (size_t)bl
;
236 lb
= ctx
->nlast_block
;
237 /* Is last block complete? */
239 for (i
= 0; i
< bl
; i
++)
240 out
[i
] = ctx
->last_block
[i
] ^ ctx
->k1
[i
];
242 ctx
->last_block
[lb
] = 0x80;
244 memset(ctx
->last_block
+ lb
+ 1, 0, bl
- lb
- 1);
245 for (i
= 0; i
< bl
; i
++)
246 out
[i
] = ctx
->last_block
[i
] ^ ctx
->k2
[i
];
248 if (!EVP_Cipher(ctx
->cctx
, out
, out
, bl
)) {
249 OPENSSL_cleanse(out
, bl
);
255 int CMAC_resume(CMAC_CTX
*ctx
)
257 if (ctx
->nlast_block
== -1)
260 * The buffer "tbl" containes the last fully encrypted block which is the
261 * last IV (or all zeroes if no last encrypted block). The last block has
262 * not been modified since CMAC_final(). So reinitliasing using the last
263 * decrypted block will allow CMAC to continue after calling
266 return EVP_EncryptInit_ex(ctx
->cctx
, NULL
, NULL
, NULL
, ctx
->tbl
);