]>
git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/cmac/cmac.c
2 * Copyright 2010-2021 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
)
58 ctx
->cctx
= EVP_CIPHER_CTX_new();
59 if (ctx
->cctx
== NULL
) {
63 ctx
->nlast_block
= -1;
67 void CMAC_CTX_cleanup(CMAC_CTX
*ctx
)
69 EVP_CIPHER_CTX_reset(ctx
->cctx
);
70 OPENSSL_cleanse(ctx
->tbl
, EVP_MAX_BLOCK_LENGTH
);
71 OPENSSL_cleanse(ctx
->k1
, EVP_MAX_BLOCK_LENGTH
);
72 OPENSSL_cleanse(ctx
->k2
, EVP_MAX_BLOCK_LENGTH
);
73 OPENSSL_cleanse(ctx
->last_block
, EVP_MAX_BLOCK_LENGTH
);
74 ctx
->nlast_block
= -1;
77 EVP_CIPHER_CTX
*CMAC_CTX_get0_cipher_ctx(CMAC_CTX
*ctx
)
82 void CMAC_CTX_free(CMAC_CTX
*ctx
)
86 CMAC_CTX_cleanup(ctx
);
87 EVP_CIPHER_CTX_free(ctx
->cctx
);
91 int CMAC_CTX_copy(CMAC_CTX
*out
, const CMAC_CTX
*in
)
95 if (in
->nlast_block
== -1)
97 if ((bl
= EVP_CIPHER_CTX_get_block_size(in
->cctx
)) < 0)
99 if (!EVP_CIPHER_CTX_copy(out
->cctx
, in
->cctx
))
101 memcpy(out
->k1
, in
->k1
, bl
);
102 memcpy(out
->k2
, in
->k2
, bl
);
103 memcpy(out
->tbl
, in
->tbl
, bl
);
104 memcpy(out
->last_block
, in
->last_block
, bl
);
105 out
->nlast_block
= in
->nlast_block
;
109 int CMAC_Init(CMAC_CTX
*ctx
, const void *key
, size_t keylen
,
110 const EVP_CIPHER
*cipher
, ENGINE
*impl
)
112 static const unsigned char zero_iv
[EVP_MAX_BLOCK_LENGTH
] = { 0 };
114 /* All zeros means restart */
115 if (!key
&& !cipher
&& !impl
&& keylen
== 0) {
116 /* Not initialised */
117 if (ctx
->nlast_block
== -1)
119 if (!EVP_EncryptInit_ex(ctx
->cctx
, NULL
, NULL
, NULL
, zero_iv
))
121 memset(ctx
->tbl
, 0, EVP_CIPHER_CTX_get_block_size(ctx
->cctx
));
122 ctx
->nlast_block
= 0;
125 /* Initialise context */
126 if (cipher
!= NULL
) {
127 /* Ensure we can't use this ctx until we also have a key */
128 ctx
->nlast_block
= -1;
129 if (!EVP_EncryptInit_ex(ctx
->cctx
, cipher
, impl
, NULL
, NULL
))
132 /* Non-NULL key means initialisation complete */
136 /* If anything fails then ensure we can't use this ctx */
137 ctx
->nlast_block
= -1;
138 if (EVP_CIPHER_CTX_get0_cipher(ctx
->cctx
) == NULL
)
140 if (EVP_CIPHER_CTX_set_key_length(ctx
->cctx
, keylen
) <= 0)
142 if (!EVP_EncryptInit_ex(ctx
->cctx
, NULL
, NULL
, key
, zero_iv
))
144 if ((bl
= EVP_CIPHER_CTX_get_block_size(ctx
->cctx
)) < 0)
146 if (EVP_Cipher(ctx
->cctx
, ctx
->tbl
, zero_iv
, bl
) <= 0)
148 make_kn(ctx
->k1
, ctx
->tbl
, bl
);
149 make_kn(ctx
->k2
, ctx
->k1
, bl
);
150 OPENSSL_cleanse(ctx
->tbl
, bl
);
151 /* Reset context again ready for first data block */
152 if (!EVP_EncryptInit_ex(ctx
->cctx
, NULL
, NULL
, NULL
, zero_iv
))
154 /* Zero tbl so resume works */
155 memset(ctx
->tbl
, 0, bl
);
156 ctx
->nlast_block
= 0;
161 int CMAC_Update(CMAC_CTX
*ctx
, const void *in
, size_t dlen
)
163 const unsigned char *data
= in
;
166 if (ctx
->nlast_block
== -1)
170 if ((bl
= EVP_CIPHER_CTX_get_block_size(ctx
->cctx
)) < 0)
172 /* Copy into partial block if we need to */
173 if (ctx
->nlast_block
> 0) {
176 nleft
= bl
- ctx
->nlast_block
;
179 memcpy(ctx
->last_block
+ ctx
->nlast_block
, data
, nleft
);
181 ctx
->nlast_block
+= nleft
;
182 /* If no more to process return */
186 /* Else not final block so encrypt it */
187 if (EVP_Cipher(ctx
->cctx
, ctx
->tbl
, ctx
->last_block
, bl
) <= 0)
190 /* Encrypt all but one of the complete blocks left */
191 while (dlen
> (size_t)bl
) {
192 if (EVP_Cipher(ctx
->cctx
, ctx
->tbl
, data
, bl
) <= 0)
197 /* Copy any data left to last block buffer */
198 memcpy(ctx
->last_block
, data
, dlen
);
199 ctx
->nlast_block
= dlen
;
204 int CMAC_Final(CMAC_CTX
*ctx
, unsigned char *out
, size_t *poutlen
)
208 if (ctx
->nlast_block
== -1)
210 if ((bl
= EVP_CIPHER_CTX_get_block_size(ctx
->cctx
)) < 0)
213 *poutlen
= (size_t)bl
;
216 lb
= ctx
->nlast_block
;
217 /* Is last block complete? */
219 for (i
= 0; i
< bl
; i
++)
220 out
[i
] = ctx
->last_block
[i
] ^ ctx
->k1
[i
];
222 ctx
->last_block
[lb
] = 0x80;
224 memset(ctx
->last_block
+ lb
+ 1, 0, bl
- lb
- 1);
225 for (i
= 0; i
< bl
; i
++)
226 out
[i
] = ctx
->last_block
[i
] ^ ctx
->k2
[i
];
228 if (EVP_Cipher(ctx
->cctx
, out
, out
, bl
) <= 0) {
229 OPENSSL_cleanse(out
, bl
);
235 int CMAC_resume(CMAC_CTX
*ctx
)
237 if (ctx
->nlast_block
== -1)
240 * The buffer "tbl" contains the last fully encrypted block which is the
241 * last IV (or all zeroes if no last encrypted block). The last block has
242 * not been modified since CMAC_final(). So reinitialising using the last
243 * decrypted block will allow CMAC to continue after calling
246 return EVP_EncryptInit_ex(ctx
->cctx
, NULL
, NULL
, NULL
, ctx
->tbl
);