1 /* $NetBSD: ah_aesxcbcmac.c,v 1.6 2009/03/18 17:06:52 cegger Exp $ */
2 /* $KAME: ah_aesxcbcmac.c,v 1.7 2004/06/02 05:53:14 itojun Exp $ */
5 * Copyright (C) 1995, 1996, 1997, 1998 and 2003 WIDE Project.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the project nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 #include <sys/cdefs.h>
34 __KERNEL_RCSID(0, "$NetBSD: ah_aesxcbcmac.c,v 1.6 2009/03/18 17:06:52 cegger Exp $");
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/socket.h>
39 #include <sys/queue.h>
40 #include <sys/syslog.h>
44 #include <net/route.h>
46 #include <netinet/in.h>
48 #include <netinet6/ipsec.h>
49 #include <netinet6/ah.h>
50 #include <netinet6/ah_aesxcbcmac.h>
52 #include <netkey/key.h>
54 #include <crypto/rijndael/rijndael.h>
56 #include <net/net_osdep.h>
58 #define AES_BLOCKSIZE 16
61 u_int8_t e
[AES_BLOCKSIZE
];
62 u_int8_t buf
[AES_BLOCKSIZE
];
64 u_int32_t r_k1s
[(RIJNDAEL_MAXNR
+1)*4];
65 u_int32_t r_k2s
[(RIJNDAEL_MAXNR
+1)*4];
66 u_int32_t r_k3s
[(RIJNDAEL_MAXNR
+1)*4];
67 int r_nr
; /* key-length-dependent number of rounds */
68 u_int8_t k2
[AES_BLOCKSIZE
];
69 u_int8_t k3
[AES_BLOCKSIZE
];
73 ah_aes_xcbc_mac_init(struct ah_algorithm_state
*state
, struct secasvar
* sav
)
75 u_int8_t k1seed
[AES_BLOCKSIZE
] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 };
76 u_int8_t k2seed
[AES_BLOCKSIZE
] = { 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 };
77 u_int8_t k3seed
[AES_BLOCKSIZE
] = { 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 };
78 u_int32_t r_ks
[(RIJNDAEL_MAXNR
+1)*4];
80 u_int8_t k1
[AES_BLOCKSIZE
];
83 panic("ah_aes_xcbc_mac_init: what?");
86 state
->foo
= malloc(sizeof(aesxcbc_ctx
), M_TEMP
, M_NOWAIT
|M_ZERO
);
90 ctx
= (aesxcbc_ctx
*)state
->foo
;
92 if ((ctx
->r_nr
= rijndaelKeySetupEnc(r_ks
,
93 (char *)_KEYBUF(sav
->key_auth
), AES_BLOCKSIZE
* 8)) == 0)
95 rijndaelEncrypt(r_ks
, ctx
->r_nr
, k1seed
, k1
);
96 rijndaelEncrypt(r_ks
, ctx
->r_nr
, k2seed
, ctx
->k2
);
97 rijndaelEncrypt(r_ks
, ctx
->r_nr
, k3seed
, ctx
->k3
);
98 if (rijndaelKeySetupEnc(ctx
->r_k1s
, k1
, AES_BLOCKSIZE
* 8) == 0)
100 if (rijndaelKeySetupEnc(ctx
->r_k2s
, ctx
->k2
, AES_BLOCKSIZE
* 8) == 0)
102 if (rijndaelKeySetupEnc(ctx
->r_k3s
, ctx
->k3
, AES_BLOCKSIZE
* 8) == 0)
109 ah_aes_xcbc_mac_loop(struct ah_algorithm_state
*state
, u_int8_t
*addr
,
112 u_int8_t buf
[AES_BLOCKSIZE
];
117 if (!state
|| !state
->foo
)
118 panic("ah_aes_xcbc_mac_loop: what?");
120 ctx
= (aesxcbc_ctx
*)state
->foo
;
123 if (ctx
->buflen
== sizeof(ctx
->buf
)) {
124 for (i
= 0; i
< sizeof(ctx
->e
); i
++)
125 ctx
->buf
[i
] ^= ctx
->e
[i
];
126 rijndaelEncrypt(ctx
->r_k1s
, ctx
->r_nr
, ctx
->buf
, ctx
->e
);
129 if (ctx
->buflen
+ len
< sizeof(ctx
->buf
)) {
130 memcpy(ctx
->buf
+ ctx
->buflen
, addr
, len
);
134 if (ctx
->buflen
&& ctx
->buflen
+ len
> sizeof(ctx
->buf
)) {
135 memcpy(ctx
->buf
+ ctx
->buflen
, addr
,
136 sizeof(ctx
->buf
) - ctx
->buflen
);
137 for (i
= 0; i
< sizeof(ctx
->e
); i
++)
138 ctx
->buf
[i
] ^= ctx
->e
[i
];
139 rijndaelEncrypt(ctx
->r_k1s
, ctx
->r_nr
, ctx
->buf
, ctx
->e
);
140 addr
+= sizeof(ctx
->buf
) - ctx
->buflen
;
143 /* due to the special processing for M[n], "=" case is not included */
144 while (addr
+ AES_BLOCKSIZE
< ep
) {
145 memcpy(buf
, addr
, AES_BLOCKSIZE
);
146 for (i
= 0; i
< sizeof(buf
); i
++)
148 rijndaelEncrypt(ctx
->r_k1s
, ctx
->r_nr
, buf
, ctx
->e
);
149 addr
+= AES_BLOCKSIZE
;
152 memcpy(ctx
->buf
+ ctx
->buflen
, addr
, ep
- addr
);
153 ctx
->buflen
+= ep
- addr
;
158 ah_aes_xcbc_mac_result(struct ah_algorithm_state
*state
, u_int8_t
*addr
,
161 u_char digest
[AES_BLOCKSIZE
];
165 ctx
= (aesxcbc_ctx
*)state
->foo
;
167 if (ctx
->buflen
== sizeof(ctx
->buf
)) {
168 for (i
= 0; i
< sizeof(ctx
->buf
); i
++) {
169 ctx
->buf
[i
] ^= ctx
->e
[i
];
170 ctx
->buf
[i
] ^= ctx
->k2
[i
];
172 rijndaelEncrypt(ctx
->r_k1s
, ctx
->r_nr
, ctx
->buf
, digest
);
174 for (i
= ctx
->buflen
; i
< sizeof(ctx
->buf
); i
++)
175 ctx
->buf
[i
] = (i
== ctx
->buflen
) ? 0x80 : 0x00;
176 for (i
= 0; i
< sizeof(ctx
->buf
); i
++) {
177 ctx
->buf
[i
] ^= ctx
->e
[i
];
178 ctx
->buf
[i
] ^= ctx
->k3
[i
];
180 rijndaelEncrypt(ctx
->r_k1s
, ctx
->r_nr
, ctx
->buf
, digest
);
183 memcpy(addr
, digest
, sizeof(digest
) > l
? l
: sizeof(digest
));
185 free(state
->foo
, M_TEMP
);