]>
git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/cmac/cmac.c
2 * Copyright 2010-2023 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>
23 #define LOCAL_BUF_SIZE 2048
25 /* Cipher context to use */
28 unsigned char k1
[EVP_MAX_BLOCK_LENGTH
];
29 unsigned char k2
[EVP_MAX_BLOCK_LENGTH
];
31 unsigned char tbl
[EVP_MAX_BLOCK_LENGTH
];
32 /* Last (possibly partial) block */
33 unsigned char last_block
[EVP_MAX_BLOCK_LENGTH
];
34 /* Number of bytes in last block: -1 means context not initialised */
38 /* Make temporary keys K1 and K2 */
40 static void make_kn(unsigned char *k1
, const unsigned char *l
, int bl
)
43 unsigned char c
= l
[0], carry
= c
>> 7, cnext
;
45 /* Shift block to left, including carry */
46 for (i
= 0; i
< bl
- 1; i
++, c
= cnext
)
47 k1
[i
] = (c
<< 1) | ((cnext
= l
[i
+ 1]) >> 7);
49 /* If MSB set fixup with R */
50 k1
[i
] = (c
<< 1) ^ ((0 - carry
) & (bl
== 16 ? 0x87 : 0x1b));
53 CMAC_CTX
*CMAC_CTX_new(void)
57 if ((ctx
= OPENSSL_malloc(sizeof(*ctx
))) == NULL
)
59 ctx
->cctx
= EVP_CIPHER_CTX_new();
60 if (ctx
->cctx
== NULL
) {
64 ctx
->nlast_block
= -1;
68 void CMAC_CTX_cleanup(CMAC_CTX
*ctx
)
70 EVP_CIPHER_CTX_reset(ctx
->cctx
);
71 OPENSSL_cleanse(ctx
->tbl
, EVP_MAX_BLOCK_LENGTH
);
72 OPENSSL_cleanse(ctx
->k1
, EVP_MAX_BLOCK_LENGTH
);
73 OPENSSL_cleanse(ctx
->k2
, EVP_MAX_BLOCK_LENGTH
);
74 OPENSSL_cleanse(ctx
->last_block
, EVP_MAX_BLOCK_LENGTH
);
75 ctx
->nlast_block
= -1;
78 EVP_CIPHER_CTX
*CMAC_CTX_get0_cipher_ctx(CMAC_CTX
*ctx
)
83 void CMAC_CTX_free(CMAC_CTX
*ctx
)
87 CMAC_CTX_cleanup(ctx
);
88 EVP_CIPHER_CTX_free(ctx
->cctx
);
92 int CMAC_CTX_copy(CMAC_CTX
*out
, const CMAC_CTX
*in
)
96 if (in
->nlast_block
== -1)
98 if ((bl
= EVP_CIPHER_CTX_get_block_size(in
->cctx
)) == 0)
100 if (!EVP_CIPHER_CTX_copy(out
->cctx
, in
->cctx
))
102 memcpy(out
->k1
, in
->k1
, bl
);
103 memcpy(out
->k2
, in
->k2
, bl
);
104 memcpy(out
->tbl
, in
->tbl
, bl
);
105 memcpy(out
->last_block
, in
->last_block
, bl
);
106 out
->nlast_block
= in
->nlast_block
;
110 int CMAC_Init(CMAC_CTX
*ctx
, const void *key
, size_t keylen
,
111 const EVP_CIPHER
*cipher
, ENGINE
*impl
)
113 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 block_len
= EVP_CIPHER_CTX_get_block_size(ctx
->cctx
);
126 memset(ctx
->tbl
, 0, block_len
);
127 ctx
->nlast_block
= 0;
130 /* Initialise context */
131 if (cipher
!= NULL
) {
132 /* Ensure we can't use this ctx until we also have a key */
133 ctx
->nlast_block
= -1;
134 if (!EVP_EncryptInit_ex(ctx
->cctx
, cipher
, impl
, NULL
, NULL
))
137 /* Non-NULL key means initialisation complete */
141 /* If anything fails then ensure we can't use this ctx */
142 ctx
->nlast_block
= -1;
143 if (EVP_CIPHER_CTX_get0_cipher(ctx
->cctx
) == NULL
)
145 if (EVP_CIPHER_CTX_set_key_length(ctx
->cctx
, keylen
) <= 0)
147 if (!EVP_EncryptInit_ex(ctx
->cctx
, NULL
, NULL
, key
, zero_iv
))
149 if ((bl
= EVP_CIPHER_CTX_get_block_size(ctx
->cctx
)) < 0)
151 if (EVP_Cipher(ctx
->cctx
, ctx
->tbl
, zero_iv
, bl
) <= 0)
153 make_kn(ctx
->k1
, ctx
->tbl
, bl
);
154 make_kn(ctx
->k2
, ctx
->k1
, bl
);
155 OPENSSL_cleanse(ctx
->tbl
, bl
);
156 /* Reset context again ready for first data block */
157 if (!EVP_EncryptInit_ex(ctx
->cctx
, NULL
, NULL
, NULL
, zero_iv
))
159 /* Zero tbl so resume works */
160 memset(ctx
->tbl
, 0, bl
);
161 ctx
->nlast_block
= 0;
166 int CMAC_Update(CMAC_CTX
*ctx
, const void *in
, size_t dlen
)
168 const unsigned char *data
= in
;
170 size_t max_burst_blocks
, cipher_blocks
;
171 unsigned char buf
[LOCAL_BUF_SIZE
];
173 if (ctx
->nlast_block
== -1)
177 if ((bl
= EVP_CIPHER_CTX_get_block_size(ctx
->cctx
)) == 0)
179 /* Copy into partial block if we need to */
180 if (ctx
->nlast_block
> 0) {
183 nleft
= bl
- ctx
->nlast_block
;
186 memcpy(ctx
->last_block
+ ctx
->nlast_block
, data
, nleft
);
188 ctx
->nlast_block
+= nleft
;
189 /* If no more to process return */
193 /* Else not final block so encrypt it */
194 if (EVP_Cipher(ctx
->cctx
, ctx
->tbl
, ctx
->last_block
, bl
) <= 0)
197 /* Encrypt all but one of the complete blocks left */
199 max_burst_blocks
= LOCAL_BUF_SIZE
/ bl
;
200 cipher_blocks
= (dlen
- 1) / bl
;
201 if (max_burst_blocks
== 0) {
203 * When block length is greater than local buffer size,
204 * use ctx->tbl as cipher output.
206 while (dlen
> (size_t)bl
) {
207 if (EVP_Cipher(ctx
->cctx
, ctx
->tbl
, data
, bl
) <= 0)
213 while (cipher_blocks
> max_burst_blocks
) {
214 if (EVP_Cipher(ctx
->cctx
, buf
, data
, max_burst_blocks
* bl
) <= 0)
216 dlen
-= max_burst_blocks
* bl
;
217 data
+= max_burst_blocks
* bl
;
218 cipher_blocks
-= max_burst_blocks
;
220 if (cipher_blocks
> 0) {
221 if (EVP_Cipher(ctx
->cctx
, buf
, data
, cipher_blocks
* bl
) <= 0)
223 dlen
-= cipher_blocks
* bl
;
224 data
+= cipher_blocks
* bl
;
225 memcpy(ctx
->tbl
, &buf
[(cipher_blocks
- 1) * bl
], bl
);
228 /* Copy any data left to last block buffer */
229 memcpy(ctx
->last_block
, data
, dlen
);
230 ctx
->nlast_block
= dlen
;
235 int CMAC_Final(CMAC_CTX
*ctx
, unsigned char *out
, size_t *poutlen
)
239 if (ctx
->nlast_block
== -1)
241 if ((bl
= EVP_CIPHER_CTX_get_block_size(ctx
->cctx
)) == 0)
244 *poutlen
= (size_t)bl
;
247 lb
= ctx
->nlast_block
;
248 /* Is last block complete? */
250 for (i
= 0; i
< bl
; i
++)
251 out
[i
] = ctx
->last_block
[i
] ^ ctx
->k1
[i
];
253 ctx
->last_block
[lb
] = 0x80;
255 memset(ctx
->last_block
+ lb
+ 1, 0, bl
- lb
- 1);
256 for (i
= 0; i
< bl
; i
++)
257 out
[i
] = ctx
->last_block
[i
] ^ ctx
->k2
[i
];
259 if (EVP_Cipher(ctx
->cctx
, out
, out
, bl
) <= 0) {
260 OPENSSL_cleanse(out
, bl
);
266 int CMAC_resume(CMAC_CTX
*ctx
)
268 if (ctx
->nlast_block
== -1)
271 * The buffer "tbl" contains the last fully encrypted block which is the
272 * last IV (or all zeroes if no last encrypted block). The last block has
273 * not been modified since CMAC_final(). So reinitialising using the last
274 * decrypted block will allow CMAC to continue after calling
277 return EVP_EncryptInit_ex(ctx
->cctx
, NULL
, NULL
, NULL
, ctx
->tbl
);