Line data Source code
1 : /*
2 : AES-CMAC-128 (rfc 4493)
3 : Copyright (C) Stefan Metzmacher 2012
4 : Copyright (C) Jeremy Allison 2012
5 : Copyright (C) Michael Adam 2012
6 :
7 : This program is free software; you can redistribute it and/or modify
8 : it under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 3 of the License, or
10 : (at your option) any later version.
11 :
12 : This program is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with this program. If not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include "replace.h"
22 : #include "lib/crypto/aes.h"
23 : #include "lib/crypto/aes_cmac_128.h"
24 :
25 : static const uint8_t const_Zero[] = {
26 : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
27 : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
28 : };
29 :
30 : static const uint8_t const_Rb[] = {
31 : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
32 : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87
33 : };
34 :
35 : #define _MSB(x) (((x)[0] & 0x80)?1:0)
36 :
37 303 : void aes_cmac_128_init(struct aes_cmac_128_context *ctx,
38 : const uint8_t K[AES_BLOCK_SIZE])
39 : {
40 303 : ZERO_STRUCTP(ctx);
41 :
42 303 : AES_set_encrypt_key(K, 128, &ctx->aes_key);
43 :
44 : /* step 1 - generate subkeys k1 and k2 */
45 :
46 303 : AES_encrypt(const_Zero, ctx->L, &ctx->aes_key);
47 :
48 303 : if (_MSB(ctx->L) == 0) {
49 150 : aes_block_lshift(ctx->L, ctx->K1);
50 : } else {
51 153 : aes_block_lshift(ctx->L, ctx->tmp);
52 153 : aes_block_xor(ctx->tmp, const_Rb, ctx->K1);
53 : }
54 :
55 303 : if (_MSB(ctx->K1) == 0) {
56 193 : aes_block_lshift(ctx->K1, ctx->K2);
57 : } else {
58 110 : aes_block_lshift(ctx->K1, ctx->tmp);
59 110 : aes_block_xor(ctx->tmp, const_Rb, ctx->K2);
60 : }
61 303 : }
62 :
63 1211 : void aes_cmac_128_update(struct aes_cmac_128_context *ctx,
64 : const uint8_t *msg, size_t msg_len)
65 : {
66 : /*
67 : * check if we expand the block
68 : */
69 1211 : if (ctx->last_len < AES_BLOCK_SIZE) {
70 589 : size_t len = MIN(AES_BLOCK_SIZE - ctx->last_len, msg_len);
71 :
72 589 : if (len > 0) {
73 556 : memcpy(&ctx->last[ctx->last_len], msg, len);
74 556 : msg += len;
75 556 : msg_len -= len;
76 556 : ctx->last_len += len;
77 : }
78 : }
79 :
80 1211 : if (msg_len == 0) {
81 : /* if it is still the last block, we are done */
82 162 : return;
83 : }
84 :
85 : /*
86 : * now checksum everything but the last block
87 : */
88 1049 : aes_block_xor(ctx->X, ctx->last, ctx->Y);
89 1049 : AES_encrypt(ctx->Y, ctx->X, &ctx->aes_key);
90 :
91 10841 : while (msg_len > AES_BLOCK_SIZE) {
92 8743 : aes_block_xor(ctx->X, msg, ctx->Y);
93 8743 : AES_encrypt(ctx->Y, ctx->X, &ctx->aes_key);
94 8743 : msg += AES_BLOCK_SIZE;
95 8743 : msg_len -= AES_BLOCK_SIZE;
96 : }
97 :
98 : /*
99 : * copy the last block, it will be processed in
100 : * aes_cmac_128_final().
101 : */
102 1049 : ZERO_STRUCT(ctx->last);
103 1049 : memcpy(ctx->last, msg, msg_len);
104 1049 : ctx->last_len = msg_len;
105 : }
106 :
107 303 : void aes_cmac_128_final(struct aes_cmac_128_context *ctx,
108 : uint8_t T[AES_BLOCK_SIZE])
109 : {
110 303 : if (ctx->last_len < AES_BLOCK_SIZE) {
111 253 : ctx->last[ctx->last_len] = 0x80;
112 253 : aes_block_xor(ctx->last, ctx->K2, ctx->tmp);
113 : } else {
114 50 : aes_block_xor(ctx->last, ctx->K1, ctx->tmp);
115 : }
116 :
117 303 : aes_block_xor(ctx->tmp, ctx->X, ctx->Y);
118 303 : AES_encrypt(ctx->Y, T, &ctx->aes_key);
119 :
120 303 : ZERO_STRUCTP(ctx);
121 303 : }
|