]>
git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/cmac/cmac.c
2 * Copyright 2010-2018 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
11 * CMAC low level APIs are deprecated for public use, but still ok for internal
14 #include "internal/deprecated.h"
19 #include "internal/cryptlib.h"
20 #include <openssl/cmac.h>
21 #include <openssl/err.h>
24 /* Cipher context to use */
27 unsigned char k1
[EVP_MAX_BLOCK_LENGTH
];
28 unsigned char k2
[EVP_MAX_BLOCK_LENGTH
];
30 unsigned char tbl
[EVP_MAX_BLOCK_LENGTH
];
31 /* Last (possibly partial) block */
32 unsigned char last_block
[EVP_MAX_BLOCK_LENGTH
];
33 /* Number of bytes in last block: -1 means context not initialised */
37 /* Make temporary keys K1 and K2 */
39 static void make_kn(unsigned char *k1
, const unsigned char *l
, int bl
)
42 unsigned char c
= l
[0], carry
= c
>> 7, cnext
;
44 /* Shift block to left, including carry */
45 for (i
= 0; i
< bl
- 1; i
++, c
= cnext
)
46 k1
[i
] = (c
<< 1) | ((cnext
= l
[i
+ 1]) >> 7);
48 /* If MSB set fixup with R */
49 k1
[i
] = (c
<< 1) ^ ((0 - carry
) & (bl
== 16 ? 0x87 : 0x1b));
52 CMAC_CTX
*CMAC_CTX_new(void)
56 if ((ctx
= OPENSSL_malloc(sizeof(*ctx
))) == NULL
) {
57 CRYPTOerr(CRYPTO_F_CMAC_CTX_NEW
, ERR_R_MALLOC_FAILURE
);
60 ctx
->cctx
= EVP_CIPHER_CTX_new();
61 if (ctx
->cctx
== NULL
) {
65 ctx
->nlast_block
= -1;
69 void CMAC_CTX_cleanup(CMAC_CTX
*ctx
)
71 EVP_CIPHER_CTX_reset(ctx
->cctx
);
72 OPENSSL_cleanse(ctx
->tbl
, EVP_MAX_BLOCK_LENGTH
);
73 OPENSSL_cleanse(ctx
->k1
, EVP_MAX_BLOCK_LENGTH
);
74 OPENSSL_cleanse(ctx
->k2
, EVP_MAX_BLOCK_LENGTH
);
75 OPENSSL_cleanse(ctx
->last_block
, EVP_MAX_BLOCK_LENGTH
);
76 ctx
->nlast_block
= -1;
79 EVP_CIPHER_CTX
*CMAC_CTX_get0_cipher_ctx(CMAC_CTX
*ctx
)
84 void CMAC_CTX_free(CMAC_CTX
*ctx
)
88 CMAC_CTX_cleanup(ctx
);
89 EVP_CIPHER_CTX_free(ctx
->cctx
);
93 int CMAC_CTX_copy(CMAC_CTX
*out
, const CMAC_CTX
*in
)
97 if (in
->nlast_block
== -1)
99 if ((bl
= EVP_CIPHER_CTX_block_size(in
->cctx
)) < 0)
101 if (!EVP_CIPHER_CTX_copy(out
->cctx
, in
->cctx
))
103 memcpy(out
->k1
, in
->k1
, bl
);
104 memcpy(out
->k2
, in
->k2
, bl
);
105 memcpy(out
->tbl
, in
->tbl
, bl
);
106 memcpy(out
->last_block
, in
->last_block
, bl
);
107 out
->nlast_block
= in
->nlast_block
;
111 int CMAC_Init(CMAC_CTX
*ctx
, const void *key
, size_t keylen
,
112 const EVP_CIPHER
*cipher
, ENGINE
*impl
)
114 static const unsigned char zero_iv
[EVP_MAX_BLOCK_LENGTH
] = { 0 };
116 /* All zeros means restart */
117 if (!key
&& !cipher
&& !impl
&& keylen
== 0) {
118 /* Not initialised */
119 if (ctx
->nlast_block
== -1)
121 if (!EVP_EncryptInit_ex(ctx
->cctx
, NULL
, NULL
, NULL
, zero_iv
))
123 memset(ctx
->tbl
, 0, EVP_CIPHER_CTX_block_size(ctx
->cctx
));
124 ctx
->nlast_block
= 0;
127 /* Initialise context */
128 if (cipher
&& !EVP_EncryptInit_ex(ctx
->cctx
, cipher
, impl
, NULL
, NULL
))
130 /* Non-NULL key means initialisation complete */
134 if (!EVP_CIPHER_CTX_cipher(ctx
->cctx
))
136 if (!EVP_CIPHER_CTX_set_key_length(ctx
->cctx
, keylen
))
138 if (!EVP_EncryptInit_ex(ctx
->cctx
, NULL
, NULL
, key
, zero_iv
))
140 if ((bl
= EVP_CIPHER_CTX_block_size(ctx
->cctx
)) < 0)
142 if (!EVP_Cipher(ctx
->cctx
, ctx
->tbl
, zero_iv
, bl
))
144 make_kn(ctx
->k1
, ctx
->tbl
, bl
);
145 make_kn(ctx
->k2
, ctx
->k1
, bl
);
146 OPENSSL_cleanse(ctx
->tbl
, bl
);
147 /* Reset context again ready for first data block */
148 if (!EVP_EncryptInit_ex(ctx
->cctx
, NULL
, NULL
, NULL
, zero_iv
))
150 /* Zero tbl so resume works */
151 memset(ctx
->tbl
, 0, bl
);
152 ctx
->nlast_block
= 0;
157 int CMAC_Update(CMAC_CTX
*ctx
, const void *in
, size_t dlen
)
159 const unsigned char *data
= in
;
162 if (ctx
->nlast_block
== -1)
166 if ((bl
= EVP_CIPHER_CTX_block_size(ctx
->cctx
)) < 0)
168 /* Copy into partial block if we need to */
169 if (ctx
->nlast_block
> 0) {
172 nleft
= bl
- ctx
->nlast_block
;
175 memcpy(ctx
->last_block
+ ctx
->nlast_block
, data
, nleft
);
177 ctx
->nlast_block
+= nleft
;
178 /* If no more to process return */
182 /* Else not final block so encrypt it */
183 if (!EVP_Cipher(ctx
->cctx
, ctx
->tbl
, ctx
->last_block
, bl
))
186 /* Encrypt all but one of the complete blocks left */
187 while (dlen
> (size_t)bl
) {
188 if (!EVP_Cipher(ctx
->cctx
, ctx
->tbl
, data
, bl
))
193 /* Copy any data left to last block buffer */
194 memcpy(ctx
->last_block
, data
, dlen
);
195 ctx
->nlast_block
= dlen
;
200 int CMAC_Final(CMAC_CTX
*ctx
, unsigned char *out
, size_t *poutlen
)
204 if (ctx
->nlast_block
== -1)
206 if ((bl
= EVP_CIPHER_CTX_block_size(ctx
->cctx
)) < 0)
209 *poutlen
= (size_t)bl
;
212 lb
= ctx
->nlast_block
;
213 /* Is last block complete? */
215 for (i
= 0; i
< bl
; i
++)
216 out
[i
] = ctx
->last_block
[i
] ^ ctx
->k1
[i
];
218 ctx
->last_block
[lb
] = 0x80;
220 memset(ctx
->last_block
+ lb
+ 1, 0, bl
- lb
- 1);
221 for (i
= 0; i
< bl
; i
++)
222 out
[i
] = ctx
->last_block
[i
] ^ ctx
->k2
[i
];
224 if (!EVP_Cipher(ctx
->cctx
, out
, out
, bl
)) {
225 OPENSSL_cleanse(out
, bl
);
231 int CMAC_resume(CMAC_CTX
*ctx
)
233 if (ctx
->nlast_block
== -1)
236 * The buffer "tbl" contains the last fully encrypted block which is the
237 * last IV (or all zeroes if no last encrypted block). The last block has
238 * not been modified since CMAC_final(). So reinitialising using the last
239 * decrypted block will allow CMAC to continue after calling
242 return EVP_EncryptInit_ex(ctx
->cctx
, NULL
, NULL
, NULL
, ctx
->tbl
);