1*8835ffd0Sriastradh /* $NetBSD: aesxcbcmac.c,v 1.3 2020/06/29 23:34:48 riastradh Exp $ */
2ebc232a5Sdrochner
3ebc232a5Sdrochner /*
4ebc232a5Sdrochner * Copyright (C) 1995, 1996, 1997, 1998 and 2003 WIDE Project.
5ebc232a5Sdrochner * All rights reserved.
6ebc232a5Sdrochner *
7ebc232a5Sdrochner * Redistribution and use in source and binary forms, with or without
8ebc232a5Sdrochner * modification, are permitted provided that the following conditions
9ebc232a5Sdrochner * are met:
10ebc232a5Sdrochner * 1. Redistributions of source code must retain the above copyright
11ebc232a5Sdrochner * notice, this list of conditions and the following disclaimer.
12ebc232a5Sdrochner * 2. Redistributions in binary form must reproduce the above copyright
13ebc232a5Sdrochner * notice, this list of conditions and the following disclaimer in the
14ebc232a5Sdrochner * documentation and/or other materials provided with the distribution.
15ebc232a5Sdrochner * 3. Neither the name of the project nor the names of its contributors
16ebc232a5Sdrochner * may be used to endorse or promote products derived from this software
17ebc232a5Sdrochner * without specific prior written permission.
18ebc232a5Sdrochner *
19ebc232a5Sdrochner * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20ebc232a5Sdrochner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21ebc232a5Sdrochner * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22ebc232a5Sdrochner * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23ebc232a5Sdrochner * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24ebc232a5Sdrochner * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25ebc232a5Sdrochner * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26ebc232a5Sdrochner * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27ebc232a5Sdrochner * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28ebc232a5Sdrochner * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29ebc232a5Sdrochner * SUCH DAMAGE.
30ebc232a5Sdrochner */
31ebc232a5Sdrochner
32ebc232a5Sdrochner #include <sys/cdefs.h>
33*8835ffd0Sriastradh __KERNEL_RCSID(0, "$NetBSD: aesxcbcmac.c,v 1.3 2020/06/29 23:34:48 riastradh Exp $");
34ebc232a5Sdrochner
35ebc232a5Sdrochner #include <sys/param.h>
36ebc232a5Sdrochner #include <sys/systm.h>
37*8835ffd0Sriastradh
38*8835ffd0Sriastradh #include <crypto/aes/aes.h>
39ebc232a5Sdrochner
40ebc232a5Sdrochner #include <opencrypto/aesxcbcmac.h>
41ebc232a5Sdrochner
42ebc232a5Sdrochner int
aes_xcbc_mac_init(void * vctx,const uint8_t * key,u_int16_t keylen)433ee5c00aSchristos aes_xcbc_mac_init(void *vctx, const uint8_t *key, u_int16_t keylen)
44ebc232a5Sdrochner {
453ee5c00aSchristos static const uint8_t k1seed[AES_BLOCKSIZE] =
463ee5c00aSchristos { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 };
473ee5c00aSchristos static const uint8_t k2seed[AES_BLOCKSIZE] =
483ee5c00aSchristos { 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 };
493ee5c00aSchristos static const uint8_t k3seed[AES_BLOCKSIZE] =
503ee5c00aSchristos { 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 };
51*8835ffd0Sriastradh struct aesenc r_ks;
52ebc232a5Sdrochner aesxcbc_ctx *ctx;
533ee5c00aSchristos uint8_t k1[AES_BLOCKSIZE];
54ebc232a5Sdrochner
553ee5c00aSchristos ctx = vctx;
563ee5c00aSchristos memset(ctx, 0, sizeof(*ctx));
57ebc232a5Sdrochner
58*8835ffd0Sriastradh switch (keylen) {
59*8835ffd0Sriastradh case 16:
60*8835ffd0Sriastradh ctx->r_nr = aes_setenckey128(&r_ks, key);
61*8835ffd0Sriastradh break;
62*8835ffd0Sriastradh case 24:
63*8835ffd0Sriastradh ctx->r_nr = aes_setenckey192(&r_ks, key);
64*8835ffd0Sriastradh break;
65*8835ffd0Sriastradh case 32:
66*8835ffd0Sriastradh ctx->r_nr = aes_setenckey256(&r_ks, key);
67*8835ffd0Sriastradh break;
68*8835ffd0Sriastradh }
69*8835ffd0Sriastradh aes_enc(&r_ks, k1seed, k1, ctx->r_nr);
70*8835ffd0Sriastradh aes_enc(&r_ks, k2seed, ctx->k2, ctx->r_nr);
71*8835ffd0Sriastradh aes_enc(&r_ks, k3seed, ctx->k3, ctx->r_nr);
72*8835ffd0Sriastradh aes_setenckey128(&ctx->r_k1s, k1);
73*8835ffd0Sriastradh
74*8835ffd0Sriastradh explicit_memset(&r_ks, 0, sizeof(r_ks));
75*8835ffd0Sriastradh explicit_memset(k1, 0, sizeof(k1));
76ebc232a5Sdrochner
77ebc232a5Sdrochner return 0;
78ebc232a5Sdrochner }
79ebc232a5Sdrochner
80ebc232a5Sdrochner int
aes_xcbc_mac_loop(void * vctx,const uint8_t * addr,u_int16_t len)813ee5c00aSchristos aes_xcbc_mac_loop(void *vctx, const uint8_t *addr, u_int16_t len)
82ebc232a5Sdrochner {
833ee5c00aSchristos uint8_t buf[AES_BLOCKSIZE];
84ebc232a5Sdrochner aesxcbc_ctx *ctx;
853ee5c00aSchristos const uint8_t *ep;
86ebc232a5Sdrochner int i;
87ebc232a5Sdrochner
883ee5c00aSchristos ctx = vctx;
89ebc232a5Sdrochner ep = addr + len;
90ebc232a5Sdrochner
91ebc232a5Sdrochner if (ctx->buflen == sizeof(ctx->buf)) {
92ebc232a5Sdrochner for (i = 0; i < sizeof(ctx->e); i++)
93ebc232a5Sdrochner ctx->buf[i] ^= ctx->e[i];
94*8835ffd0Sriastradh aes_enc(&ctx->r_k1s, ctx->buf, ctx->e, ctx->r_nr);
95ebc232a5Sdrochner ctx->buflen = 0;
96ebc232a5Sdrochner }
97ebc232a5Sdrochner if (ctx->buflen + len < sizeof(ctx->buf)) {
98ebc232a5Sdrochner memcpy(ctx->buf + ctx->buflen, addr, len);
99ebc232a5Sdrochner ctx->buflen += len;
100ebc232a5Sdrochner return 0;
101ebc232a5Sdrochner }
102ebc232a5Sdrochner if (ctx->buflen && ctx->buflen + len > sizeof(ctx->buf)) {
103ebc232a5Sdrochner memcpy(ctx->buf + ctx->buflen, addr,
104ebc232a5Sdrochner sizeof(ctx->buf) - ctx->buflen);
105ebc232a5Sdrochner for (i = 0; i < sizeof(ctx->e); i++)
106ebc232a5Sdrochner ctx->buf[i] ^= ctx->e[i];
107*8835ffd0Sriastradh aes_enc(&ctx->r_k1s, ctx->buf, ctx->e, ctx->r_nr);
108ebc232a5Sdrochner addr += sizeof(ctx->buf) - ctx->buflen;
109ebc232a5Sdrochner ctx->buflen = 0;
110ebc232a5Sdrochner }
111ebc232a5Sdrochner /* due to the special processing for M[n], "=" case is not included */
1123ee5c00aSchristos while (ep - addr > AES_BLOCKSIZE) {
113ebc232a5Sdrochner memcpy(buf, addr, AES_BLOCKSIZE);
114ebc232a5Sdrochner for (i = 0; i < sizeof(buf); i++)
115ebc232a5Sdrochner buf[i] ^= ctx->e[i];
116*8835ffd0Sriastradh aes_enc(&ctx->r_k1s, buf, ctx->e, ctx->r_nr);
117ebc232a5Sdrochner addr += AES_BLOCKSIZE;
118ebc232a5Sdrochner }
119ebc232a5Sdrochner if (addr < ep) {
120ebc232a5Sdrochner memcpy(ctx->buf + ctx->buflen, addr, ep - addr);
121ebc232a5Sdrochner ctx->buflen += ep - addr;
122ebc232a5Sdrochner }
123ebc232a5Sdrochner return 0;
124ebc232a5Sdrochner }
125ebc232a5Sdrochner
126ebc232a5Sdrochner void
aes_xcbc_mac_result(uint8_t * addr,void * vctx)1273ee5c00aSchristos aes_xcbc_mac_result(uint8_t *addr, void *vctx)
128ebc232a5Sdrochner {
1293ee5c00aSchristos uint8_t digest[AES_BLOCKSIZE];
130ebc232a5Sdrochner aesxcbc_ctx *ctx;
131ebc232a5Sdrochner int i;
132ebc232a5Sdrochner
1333ee5c00aSchristos ctx = vctx;
134ebc232a5Sdrochner
135ebc232a5Sdrochner if (ctx->buflen == sizeof(ctx->buf)) {
136ebc232a5Sdrochner for (i = 0; i < sizeof(ctx->buf); i++) {
137ebc232a5Sdrochner ctx->buf[i] ^= ctx->e[i];
138ebc232a5Sdrochner ctx->buf[i] ^= ctx->k2[i];
139ebc232a5Sdrochner }
140*8835ffd0Sriastradh aes_enc(&ctx->r_k1s, ctx->buf, digest, ctx->r_nr);
141ebc232a5Sdrochner } else {
142ebc232a5Sdrochner for (i = ctx->buflen; i < sizeof(ctx->buf); i++)
143ebc232a5Sdrochner ctx->buf[i] = (i == ctx->buflen) ? 0x80 : 0x00;
144ebc232a5Sdrochner for (i = 0; i < sizeof(ctx->buf); i++) {
145ebc232a5Sdrochner ctx->buf[i] ^= ctx->e[i];
146ebc232a5Sdrochner ctx->buf[i] ^= ctx->k3[i];
147ebc232a5Sdrochner }
148*8835ffd0Sriastradh aes_enc(&ctx->r_k1s, ctx->buf, digest, ctx->r_nr);
149ebc232a5Sdrochner }
150ebc232a5Sdrochner
151ebc232a5Sdrochner memcpy(addr, digest, sizeof(digest));
152ebc232a5Sdrochner }
153