4 Copyright (C) Stefan Metzmacher 2012
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "../lib/crypto/crypto.h"
22 #include "lib/util/byteorder.h"
24 #define M_ ((AES_CCM_128_M - 2) / 2)
25 #define L_ (AES_CCM_128_L - 1)
27 static inline void aes_ccm_128_xor(const uint8_t in1
[AES_BLOCK_SIZE
],
28 const uint8_t in2
[AES_BLOCK_SIZE
],
29 uint8_t out
[AES_BLOCK_SIZE
])
33 for (i
= 0; i
< AES_BLOCK_SIZE
; i
++) {
34 out
[i
] = in1
[i
] ^ in2
[i
];
38 void aes_ccm_128_init(struct aes_ccm_128_context
*ctx
,
39 const uint8_t K
[AES_BLOCK_SIZE
],
40 const uint8_t N
[AES_CCM_128_NONCE_SIZE
],
41 size_t a_total
, size_t m_total
)
43 uint8_t B_0
[AES_BLOCK_SIZE
];
47 AES_set_encrypt_key(K
, 128, &ctx
->aes_key
);
48 memcpy(ctx
->nonce
, N
, AES_CCM_128_NONCE_SIZE
);
49 ctx
->a_remain
= a_total
;
50 ctx
->m_remain
= m_total
;
60 memcpy(&B_0
[1], ctx
->nonce
, AES_CCM_128_NONCE_SIZE
);
61 RSIVAL(B_0
, (AES_BLOCK_SIZE
- AES_CCM_128_L
), m_total
);
66 AES_encrypt(B_0
, ctx
->X_i
, &ctx
->aes_key
);
71 if (a_total
>= UINT32_MAX
) {
72 RSSVAL(ctx
->B_i
, 0, 0xFFFF);
73 RSBVAL(ctx
->B_i
, 2, (uint64_t)a_total
);
75 } else if (a_total
>= 0xFF00) {
76 RSSVAL(ctx
->B_i
, 0, 0xFFFE);
77 RSIVAL(ctx
->B_i
, 2, a_total
);
79 } else if (a_total
> 0) {
80 RSSVAL(ctx
->B_i
, 0, a_total
);
84 ctx
->S_i_ofs
= AES_BLOCK_SIZE
;
87 void aes_ccm_128_update(struct aes_ccm_128_context
*ctx
,
88 const uint8_t *v
, size_t v_len
)
92 if (ctx
->a_remain
> 0) {
93 remain
= &ctx
->a_remain
;
95 remain
= &ctx
->m_remain
;
99 size_t n
= MIN(AES_BLOCK_SIZE
- ctx
->B_i_ofs
, v_len
);
102 memcpy(&ctx
->B_i
[ctx
->B_i_ofs
], v
, n
);
108 if (ctx
->B_i_ofs
== AES_BLOCK_SIZE
) {
110 } else if (*remain
== 0) {
118 aes_ccm_128_xor(ctx
->X_i
, ctx
->B_i
, ctx
->B_i
);
119 AES_encrypt(ctx
->B_i
, ctx
->X_i
, &ctx
->aes_key
);
121 ZERO_STRUCT(ctx
->B_i
);
126 static void aes_ccm_128_S_i(struct aes_ccm_128_context
*ctx
,
127 uint8_t S_i
[AES_BLOCK_SIZE
],
130 uint8_t A_i
[AES_BLOCK_SIZE
];
133 memcpy(&A_i
[1], ctx
->nonce
, AES_CCM_128_NONCE_SIZE
);
134 RSIVAL(A_i
, (AES_BLOCK_SIZE
- AES_CCM_128_L
), i
);
136 AES_encrypt(A_i
, S_i
, &ctx
->aes_key
);
139 void aes_ccm_128_crypt(struct aes_ccm_128_context
*ctx
,
140 uint8_t *m
, size_t m_len
)
143 if (ctx
->S_i_ofs
== AES_BLOCK_SIZE
) {
145 aes_ccm_128_S_i(ctx
, ctx
->S_i
, ctx
->S_i_ctr
);
149 m
[0] ^= ctx
->S_i
[ctx
->S_i_ofs
];
156 void aes_ccm_128_digest(struct aes_ccm_128_context
*ctx
,
157 uint8_t digest
[AES_BLOCK_SIZE
])
159 uint8_t S_0
[AES_BLOCK_SIZE
];
161 aes_ccm_128_S_i(ctx
, S_0
, 0);
166 aes_ccm_128_xor(ctx
->X_i
, S_0
, digest
);