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