diff options
author | Reyk Floeter <reyk@cvs.openbsd.org> | 2006-03-21 18:40:55 +0000 |
---|---|---|
committer | Reyk Floeter <reyk@cvs.openbsd.org> | 2006-03-21 18:40:55 +0000 |
commit | 8767ac816d870fc31ad15b6dab06c6abb82878ea (patch) | |
tree | 804a7a605ea6be12095bfde5784f84222f9d9da8 /sys | |
parent | 8be52bf3f280d86a9655758a1887266d07e455fc (diff) |
Implementation of the Michael MIC as defined in IEEE 802.11i for TKIP.
The MIC generates a weak 64bit digest protected by an additional key.
Obviously, this digest alg is required for future IEEE 802.11i/WPA
support.
test vectors passed on alpha amd64 mvme68k mvme88k sgi sparc sparc64 vax i386
ok djm@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/conf/files | 3 | ||||
-rw-r--r-- | sys/crypto/michael.c | 87 | ||||
-rw-r--r-- | sys/crypto/michael.h | 47 |
3 files changed, 136 insertions, 1 deletions
diff --git a/sys/conf/files b/sys/conf/files index 6b91296b45d..54f6c748ff7 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1,4 +1,4 @@ -# $OpenBSD: files,v 1.367 2006/03/12 00:18:07 brad Exp $ +# $OpenBSD: files,v 1.368 2006/03/21 18:40:54 reyk Exp $ # $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $ # @(#)files.newconf 7.5 (Berkeley) 5/10/93 @@ -782,6 +782,7 @@ file crypto/cryptosoft.c (inet & ipsec) | crypto file crypto/xform.c (inet & ipsec) | crypto file crypto/deflate.c (inet & ipsec) | crypto file crypto/arc4.c wi | wlan +file crypto/michael.c wlan file netatalk/aarp.c netatalk file netatalk/at_control.c netatalk file netatalk/at_proto.c netatalk diff --git a/sys/crypto/michael.c b/sys/crypto/michael.c new file mode 100644 index 00000000000..8a4b6a31100 --- /dev/null +++ b/sys/crypto/michael.c @@ -0,0 +1,87 @@ +/* $OpenBSD: michael.c,v 1.1 2006/03/21 18:40:54 reyk Exp $ */ + +/* + * Copyright (c) 2005, 2006 Reyk Floeter <reyk@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Implementation of the Michael MIC as defined in IEEE 802.11i for TKIP. + * The MIC generates a 64bit digest, which shouldn't be used for any other + * applications except TKIP. + */ + +#include <sys/param.h> +#include <sys/systm.h> + +#include <crypto/michael.h> + +#define ROL(n, x) (((x) << (n)) | ((x) >> (32 - (n)))) +#define ROR(n, x) (((x) >> (n)) | ((x) << (32 - (n)))) +#define VAL32(x) (*((u_int32_t *)(x))) +#define XSWAP(x) (((x) & 0xff00ff00UL) >> 8) | ((((x) & 0x00ff00ffUL) << 8)) + +#define MICHAEL_BLOCK(l, r) do { \ + r ^= ROL(17, l); \ + l += r; \ + r ^= XSWAP(l); \ + l += r; \ + r ^= ROL(3, l); \ + l += r; \ + r ^= ROR(2, l); \ + l += r; \ +} while (0) + +void +michael_init(MICHAEL_CTX *ctx) +{ + bzero(ctx, sizeof(MICHAEL_CTX)); +} + +void +michael_update(MICHAEL_CTX *ctx, const u_int8_t *data, u_int len) +{ + int i; + + for (i = 0; i < len; i++) { + ctx->michael_state |= data[i] << (ctx->michael_count << 3); + ctx->michael_count++; + + if (ctx->michael_count >= MICHAEL_RAW_BLOCK_LENGTH) { + ctx->michael_l ^= ctx->michael_state; + MICHAEL_BLOCK(ctx->michael_l, ctx->michael_r); + ctx->michael_state = ctx->michael_count = 0; + } + } +} + +void +michael_final(u_int8_t digest[MICHAEL_DIGEST_LENGTH], MICHAEL_CTX *ctx) +{ + u_int8_t pad[] = { 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + michael_update(ctx, pad, sizeof(pad)); + + VAL32(digest) = letoh32(ctx->michael_l); + VAL32(digest + MICHAEL_RAW_BLOCK_LENGTH) = letoh32(ctx->michael_r); +} + +void +michael_key(const u_int8_t *key, MICHAEL_CTX *ctx) +{ + ctx->michael_l = ctx->michael_key[0] = + htole32(VAL32(key)); + ctx->michael_r = ctx->michael_key[1] = + htole32(VAL32(key + MICHAEL_RAW_BLOCK_LENGTH)); +} diff --git a/sys/crypto/michael.h b/sys/crypto/michael.h new file mode 100644 index 00000000000..3b7c435842e --- /dev/null +++ b/sys/crypto/michael.h @@ -0,0 +1,47 @@ +/* $OpenBSD: michael.h,v 1.1 2006/03/21 18:40:54 reyk Exp $ */ + +/* + * Copyright (c) 2005, 2006 Reyk Floeter <reyk@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _MICHAEL_H_ +#define _MICHAEL_H_ + +#define MICHAEL_BLOCK_LENGTH 8 +#define MICHAEL_RAW_BLOCK_LENGTH 4 +#define MICHAEL_DIGEST_LENGTH 8 + +typedef struct michael_context { + u_int32_t michael_key[2]; + u_int32_t michael_l, michael_r; + u_int32_t michael_state; + u_int michael_count; +} MICHAEL_CTX; + +#include <sys/cdefs.h> + +__BEGIN_DECLS +void michael_init(MICHAEL_CTX *); +void michael_update(MICHAEL_CTX *, const u_int8_t *, u_int) + __attribute__((__bounded__(__buffer__, 2, 3))); +void michael_final(u_int8_t [MICHAEL_DIGEST_LENGTH], MICHAEL_CTX *) + __attribute__((__bounded__(__minbytes__, 1, + MICHAEL_DIGEST_LENGTH))); +void michael_key(const u_int8_t *, MICHAEL_CTX *) + __attribute__((__bounded__(__minbytes__, 1, + MICHAEL_BLOCK_LENGTH))); +__END_DECLS + +#endif /* _MICHAEL_H_ */ |