]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/netinet6/ah_core.c
xnu-3789.60.24.tar.gz
[apple/xnu.git] / bsd / netinet6 / ah_core.c
index c30b9c7592e8c2a580f0131882e469bb0e217963..b072b692ecce92e778198901b7db5281b0e5a082 100644 (file)
@@ -1,3 +1,31 @@
+/*
+ * Copyright (c) 2008-2016 Apple Inc. All rights reserved.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ *
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
+ */
+
 /*     $FreeBSD: src/sys/netinet6/ah_core.c,v 1.2.2.4 2001/07/03 11:01:49 ume Exp $    */
 /*     $KAME: ah_core.c,v 1.44 2001/03/12 11:24:39 itojun Exp $        */
 
 #endif
 #include <net/pfkeyv2.h>
 #include <netkey/keydb.h>
-#include <sys/md5.h>
-#include <crypto/sha1.h>
-#include <crypto/sha2/sha2.h>
+#include <libkern/crypto/md5.h>
+#include <libkern/crypto/sha1.h>
+#include <libkern/crypto/sha2.h>
 
 #include <net/net_osdep.h>
 
@@ -91,93 +119,107 @@ static int ah_sumsiz_zero(struct secasvar *);
 static int ah_none_mature(struct secasvar *);
 static int ah_none_init(struct ah_algorithm_state *, struct secasvar *);
 static void ah_none_loop(struct ah_algorithm_state *, caddr_t, size_t);
-static void ah_none_result(struct ah_algorithm_state *, caddr_t);
+static void ah_none_result(struct ah_algorithm_state *, caddr_t, size_t);
 static int ah_keyed_md5_mature(struct secasvar *);
 static int ah_keyed_md5_init(struct ah_algorithm_state *, struct secasvar *);
 static void ah_keyed_md5_loop(struct ah_algorithm_state *, caddr_t, size_t);
-static void ah_keyed_md5_result(struct ah_algorithm_state *, caddr_t);
+static void ah_keyed_md5_result(struct ah_algorithm_state *, caddr_t, size_t);
 static int ah_keyed_sha1_mature(struct secasvar *);
 static int ah_keyed_sha1_init(struct ah_algorithm_state *, struct secasvar *);
 static void ah_keyed_sha1_loop(struct ah_algorithm_state *, caddr_t, size_t);
-static void ah_keyed_sha1_result(struct ah_algorithm_state *, caddr_t);
+static void ah_keyed_sha1_result(struct ah_algorithm_state *, caddr_t, size_t);
 static int ah_hmac_md5_mature(struct secasvar *);
 static int ah_hmac_md5_init(struct ah_algorithm_state *, struct secasvar *);
 static void ah_hmac_md5_loop(struct ah_algorithm_state *, caddr_t, size_t);
-static void ah_hmac_md5_result(struct ah_algorithm_state *, caddr_t);
+static void ah_hmac_md5_result(struct ah_algorithm_state *, caddr_t, size_t);
 static int ah_hmac_sha1_mature(struct secasvar *);
 static int ah_hmac_sha1_init(struct ah_algorithm_state *, struct secasvar *);
 static void ah_hmac_sha1_loop(struct ah_algorithm_state *, caddr_t, size_t);
-static void ah_hmac_sha1_result(struct ah_algorithm_state *, caddr_t);
+static void ah_hmac_sha1_result(struct ah_algorithm_state *, caddr_t, size_t);
+#if AH_ALL_CRYPTO
+static int ah_sumsiz_sha2_256(struct secasvar *);
 static int ah_hmac_sha2_256_mature(struct secasvar *);
 static int ah_hmac_sha2_256_init(struct ah_algorithm_state *,
        struct secasvar *);
 static void ah_hmac_sha2_256_loop(struct ah_algorithm_state *, caddr_t, size_t);
-static void ah_hmac_sha2_256_result(struct ah_algorithm_state *, caddr_t);
+static void ah_hmac_sha2_256_result(struct ah_algorithm_state *, caddr_t, size_t);
+static int ah_sumsiz_sha2_384(struct secasvar *);
 static int ah_hmac_sha2_384_mature(struct secasvar *);
 static int ah_hmac_sha2_384_init(struct ah_algorithm_state *,
        struct secasvar *);
 static void ah_hmac_sha2_384_loop(struct ah_algorithm_state *, caddr_t, size_t);
-static void ah_hmac_sha2_384_result(struct ah_algorithm_state *, caddr_t);
+static void ah_hmac_sha2_384_result(struct ah_algorithm_state *, caddr_t, size_t);
+static int ah_sumsiz_sha2_512(struct secasvar *);
 static int ah_hmac_sha2_512_mature(struct secasvar *);
 static int ah_hmac_sha2_512_init(struct ah_algorithm_state *,
        struct secasvar *);
 static void ah_hmac_sha2_512_loop(struct ah_algorithm_state *, caddr_t, size_t);
-static void ah_hmac_sha2_512_result(struct ah_algorithm_state *, caddr_t);
+static void ah_hmac_sha2_512_result(struct ah_algorithm_state *, caddr_t, size_t);
+#endif /* AH_ALL_CRYPTO */
 
 static void ah_update_mbuf(struct mbuf *, int, int,
        const struct ah_algorithm *, struct ah_algorithm_state *);
 
 const struct ah_algorithm *
-ah_algorithm_lookup(idx)
-       int idx;
+ah_algorithm_lookup(int idx)
 {
        /* checksum algorithms */
-       static struct ah_algorithm ah_algorithms[] = {
+       static struct ah_algorithm hmac_md5 =
                { ah_sumsiz_1216, ah_hmac_md5_mature, 128, 128, "hmac-md5",
                        ah_hmac_md5_init, ah_hmac_md5_loop,
-                       ah_hmac_md5_result, },
-               { ah_sumsiz_1216, ah_hmac_sha1_mature, 160, 160, "hmac-sha1",
-                       ah_hmac_sha1_init, ah_hmac_sha1_loop,
-                       ah_hmac_sha1_result, },
+                       ah_hmac_md5_result, };
+       static struct ah_algorithm keyed_md5 =
                { ah_sumsiz_1216, ah_keyed_md5_mature, 128, 128, "keyed-md5",
                        ah_keyed_md5_init, ah_keyed_md5_loop,
-                       ah_keyed_md5_result, },
+                       ah_keyed_md5_result, };
+       static struct ah_algorithm hmac_sha1 =
+               { ah_sumsiz_1216, ah_hmac_sha1_mature, 160, 160, "hmac-sha1",
+                       ah_hmac_sha1_init, ah_hmac_sha1_loop,
+                       ah_hmac_sha1_result, };
+       static struct ah_algorithm keyed_sha1 =
                { ah_sumsiz_1216, ah_keyed_sha1_mature, 160, 160, "keyed-sha1",
                        ah_keyed_sha1_init, ah_keyed_sha1_loop,
-                       ah_keyed_sha1_result, },
+                       ah_keyed_sha1_result, };
+       static struct ah_algorithm ah_none =
                { ah_sumsiz_zero, ah_none_mature, 0, 2048, "none",
-                       ah_none_init, ah_none_loop, ah_none_result, },
-               { ah_sumsiz_1216, ah_hmac_sha2_256_mature, 256, 256,
+                       ah_none_init, ah_none_loop, ah_none_result, };
+#if AH_ALL_CRYPTO
+       static struct ah_algorithm hmac_sha2_256 =
+               { ah_sumsiz_sha2_256, ah_hmac_sha2_256_mature, 256, 256,
                        "hmac-sha2-256",
                        ah_hmac_sha2_256_init, ah_hmac_sha2_256_loop,
-                       ah_hmac_sha2_256_result, },
-               { ah_sumsiz_1216, ah_hmac_sha2_384_mature, 384, 384,
+                       ah_hmac_sha2_256_result, };
+       static struct ah_algorithm hmac_sha2_384 =
+               { ah_sumsiz_sha2_384, ah_hmac_sha2_384_mature, 384, 384,
                        "hmac-sha2-384",
                        ah_hmac_sha2_384_init, ah_hmac_sha2_384_loop,
-                       ah_hmac_sha2_384_result, },
-               { ah_sumsiz_1216, ah_hmac_sha2_512_mature, 512, 512,
+                       ah_hmac_sha2_384_result, };
+       static struct ah_algorithm hmac_sha2_512 =
+               { ah_sumsiz_sha2_512, ah_hmac_sha2_512_mature, 512, 512,
                        "hmac-sha2-512",
                        ah_hmac_sha2_512_init, ah_hmac_sha2_512_loop,
-                       ah_hmac_sha2_512_result, },
-       };
+                       ah_hmac_sha2_512_result, };
+#endif /* AH_ALL_CRYPTO */
 
        switch (idx) {
        case SADB_AALG_MD5HMAC:
-               return &ah_algorithms[0];
+               return &hmac_md5;
        case SADB_AALG_SHA1HMAC:
-               return &ah_algorithms[1];
+               return &hmac_sha1;
        case SADB_X_AALG_MD5:
-               return &ah_algorithms[2];
+               return &keyed_md5;
        case SADB_X_AALG_SHA:
-               return &ah_algorithms[3];
+               return &keyed_sha1;
        case SADB_X_AALG_NULL:
-               return &ah_algorithms[4];
+               return &ah_none;
+#if AH_ALL_CRYPTO
        case SADB_X_AALG_SHA2_256:
-               return &ah_algorithms[5];
+               return &hmac_sha2_256;
        case SADB_X_AALG_SHA2_384:
-               return &ah_algorithms[6];
+               return &hmac_sha2_384;
        case SADB_X_AALG_SHA2_512:
-               return &ah_algorithms[7];
+               return &hmac_sha2_512;
+#endif /* AH_ALL_CRYPTO */
        default:
                return NULL;
        }
@@ -185,8 +227,7 @@ ah_algorithm_lookup(idx)
 
 
 static int
-ah_sumsiz_1216(sav)
-       struct secasvar *sav;
+ah_sumsiz_1216(struct secasvar *sav)
 {
        if (!sav)
                return -1;
@@ -197,8 +238,7 @@ ah_sumsiz_1216(sav)
 }
 
 static int
-ah_sumsiz_zero(sav)
-       struct secasvar *sav;
+ah_sumsiz_zero(struct secasvar *sav)
 {
        if (!sav)
                return -1;
@@ -206,8 +246,7 @@ ah_sumsiz_zero(sav)
 }
 
 static int
-ah_none_mature(sav)
-       struct secasvar *sav;
+ah_none_mature(struct secasvar *sav)
 {
        if (sav->sah->saidx.proto == IPPROTO_AH) {
                ipseclog((LOG_ERR,
@@ -218,51 +257,50 @@ ah_none_mature(sav)
 }
 
 static int
-ah_none_init(state, sav)
-       struct ah_algorithm_state *state;
-       struct secasvar *sav;
+ah_none_init(
+       struct ah_algorithm_state *state,
+       __unused struct secasvar *sav)
 {
        state->foo = NULL;
        return 0;
 }
 
 static void
-ah_none_loop(state, addr, len)
-       struct ah_algorithm_state *state;
-       caddr_t addr;
-       size_t len;
+ah_none_loop(
+       __unused struct ah_algorithm_state *state,
+       __unused caddr_t addr,
+       __unused size_t len)
 {
 }
 
 static void
-ah_none_result(state, addr)
-       struct ah_algorithm_state *state;
-       caddr_t addr;
+ah_none_result(
+       __unused struct ah_algorithm_state *state,
+       __unused caddr_t addr,
+       __unused size_t l)
 {
 }
 
 static int
-ah_keyed_md5_mature(sav)
-       struct secasvar *sav;
+ah_keyed_md5_mature(
+       __unused struct secasvar *sav)
 {
        /* anything is okay */
        return 0;
 }
 
 static int
-ah_keyed_md5_init(state, sav)
-       struct ah_algorithm_state *state;
-       struct secasvar *sav;
+ah_keyed_md5_init(struct ah_algorithm_state *state, struct secasvar *sav)
 {
        size_t padlen;
        size_t keybitlen;
-       u_int8_t buf[32];
+       u_int8_t buf[32] __attribute__((aligned(4)));
 
        if (!state)
                panic("ah_keyed_md5_init: what?");
 
        state->sav = sav;
-       state->foo = (void *)_MALLOC(sizeof(MD5_CTX), M_TEMP, M_WAITOK);
+       state->foo = (void *)_MALLOC(sizeof(MD5_CTX), M_TEMP, M_NOWAIT);
        if (state->foo == NULL)
                return ENOBUFS;
 
@@ -308,10 +346,7 @@ ah_keyed_md5_init(state, sav)
 }
 
 static void
-ah_keyed_md5_loop(state, addr, len)
-       struct ah_algorithm_state *state;
-       caddr_t addr;
-       size_t len;
+ah_keyed_md5_loop(struct ah_algorithm_state *state, caddr_t addr, size_t len)
 {
        if (!state)
                panic("ah_keyed_md5_loop: what?");
@@ -320,11 +355,9 @@ ah_keyed_md5_loop(state, addr, len)
 }
 
 static void
-ah_keyed_md5_result(state, addr)
-       struct ah_algorithm_state *state;
-       caddr_t addr;
+ah_keyed_md5_result(struct ah_algorithm_state *state, caddr_t addr, size_t l)
 {
-       u_char digest[16];
+       u_char digest[16] __attribute__((aligned(4)));
 
        if (!state)
                panic("ah_keyed_md5_result: what?");
@@ -336,12 +369,11 @@ ah_keyed_md5_result(state, addr)
        }
        MD5Final(&digest[0], (MD5_CTX *)state->foo);
        FREE(state->foo, M_TEMP);
-       bcopy(&digest[0], (void *)addr, sizeof(digest));
+       bcopy(&digest[0], (void *)addr, sizeof(digest) > l ? l : sizeof(digest));
 }
 
 static int
-ah_keyed_sha1_mature(sav)
-       struct secasvar *sav;
+ah_keyed_sha1_mature(struct secasvar *sav)
 {
        const struct ah_algorithm *algo;
 
@@ -368,20 +400,18 @@ ah_keyed_sha1_mature(sav)
 }
 
 static int
-ah_keyed_sha1_init(state, sav)
-       struct ah_algorithm_state *state;
-       struct secasvar *sav;
+ah_keyed_sha1_init(struct ah_algorithm_state *state, struct secasvar *sav)
 {
        SHA1_CTX *ctxt;
        size_t padlen;
        size_t keybitlen;
-       u_int8_t buf[32];
+       u_int8_t buf[32] __attribute__((aligned(4)));
 
        if (!state)
                panic("ah_keyed_sha1_init: what?");
 
        state->sav = sav;
-       state->foo = (void *)_MALLOC(sizeof(SHA1_CTX), M_TEMP, M_WAITOK);
+       state->foo = (void *)_MALLOC(sizeof(SHA1_CTX), M_TEMP, M_NOWAIT);
        if (!state->foo)
                return ENOBUFS;
 
@@ -426,10 +456,7 @@ ah_keyed_sha1_init(state, sav)
 }
 
 static void
-ah_keyed_sha1_loop(state, addr, len)
-       struct ah_algorithm_state *state;
-       caddr_t addr;
-       size_t len;
+ah_keyed_sha1_loop(struct ah_algorithm_state *state, caddr_t addr, size_t len)
 {
        SHA1_CTX *ctxt;
 
@@ -441,11 +468,9 @@ ah_keyed_sha1_loop(state, addr, len)
 }
 
 static void
-ah_keyed_sha1_result(state, addr)
-       struct ah_algorithm_state *state;
-       caddr_t addr;
+ah_keyed_sha1_result(struct ah_algorithm_state *state, caddr_t addr, size_t l)
 {
-       u_char digest[SHA1_RESULTLEN];  /* SHA-1 generates 160 bits */
+       u_char digest[SHA1_RESULTLEN] __attribute__((aligned(4)));      /* SHA-1 generates 160 bits */
        SHA1_CTX *ctxt;
 
        if (!state || !state->foo)
@@ -457,14 +482,13 @@ ah_keyed_sha1_result(state, addr)
                        (u_int)_KEYLEN(state->sav->key_auth));
        }
        SHA1Final((caddr_t)&digest[0], ctxt);
-       bcopy(&digest[0], (void *)addr, HMACSIZE);
+       bcopy(&digest[0], (void *)addr, sizeof(digest) > l ? l : sizeof(digest));
 
        FREE(state->foo, M_TEMP);
 }
 
 static int
-ah_hmac_md5_mature(sav)
-       struct secasvar *sav;
+ah_hmac_md5_mature(struct secasvar *sav)
 {
        const struct ah_algorithm *algo;
 
@@ -491,13 +515,11 @@ ah_hmac_md5_mature(sav)
 }
 
 static int
-ah_hmac_md5_init(state, sav)
-       struct ah_algorithm_state *state;
-       struct secasvar *sav;
+ah_hmac_md5_init(struct ah_algorithm_state *state, struct secasvar *sav)
 {
        u_char *ipad;
        u_char *opad;
-       u_char tk[16];
+       u_char tk[16] __attribute__((aligned(4)));
        u_char *key;
        size_t keylen;
        size_t i;
@@ -507,13 +529,13 @@ ah_hmac_md5_init(state, sav)
                panic("ah_hmac_md5_init: what?");
 
        state->sav = sav;
-       state->foo = (void *)_MALLOC(64 + 64 + sizeof(MD5_CTX), M_TEMP, M_WAITOK);
+       state->foo = (void *)_MALLOC(64 + 64 + sizeof(MD5_CTX), M_TEMP, M_NOWAIT);
        if (!state->foo)
                return ENOBUFS;
 
        ipad = (u_char *)state->foo;
        opad = (u_char *)(ipad + 64);
-       ctxt = (MD5_CTX *)(opad + 64);
+       ctxt = (MD5_CTX *)(void *)(opad + 64);
 
        /* compress the key if necessery */
        if (64 < _KEYLEN(state->sav->key_auth)) {
@@ -524,7 +546,7 @@ ah_hmac_md5_init(state, sav)
                key = &tk[0];
                keylen = 16;
        } else {
-               key = _KEYBUF(state->sav->key_auth);
+               key = (u_char *) _KEYBUF(state->sav->key_auth);
                keylen = _KEYLEN(state->sav->key_auth);
        }
 
@@ -544,25 +566,20 @@ ah_hmac_md5_init(state, sav)
 }
 
 static void
-ah_hmac_md5_loop(state, addr, len)
-       struct ah_algorithm_state *state;
-       caddr_t addr;
-       size_t len;
+ah_hmac_md5_loop(struct ah_algorithm_state *state, caddr_t addr, size_t len)
 {
        MD5_CTX *ctxt;
 
        if (!state || !state->foo)
                panic("ah_hmac_md5_loop: what?");
-       ctxt = (MD5_CTX *)(((caddr_t)state->foo) + 128);
+       ctxt = (MD5_CTX *)(void *)(((caddr_t)state->foo) + 128);
        MD5Update(ctxt, addr, len);
 }
 
 static void
-ah_hmac_md5_result(state, addr)
-       struct ah_algorithm_state *state;
-       caddr_t addr;
+ah_hmac_md5_result(struct ah_algorithm_state *state, caddr_t addr, size_t l)
 {
-       u_char digest[16];
+       u_char digest[16] __attribute__((aligned(4)));
        u_char *ipad;
        u_char *opad;
        MD5_CTX *ctxt;
@@ -572,7 +589,7 @@ ah_hmac_md5_result(state, addr)
 
        ipad = (u_char *)state->foo;
        opad = (u_char *)(ipad + 64);
-       ctxt = (MD5_CTX *)(opad + 64);
+       ctxt = (MD5_CTX *)(void *)(opad + 64);
 
        MD5Final(&digest[0], ctxt);
 
@@ -581,14 +598,13 @@ ah_hmac_md5_result(state, addr)
        MD5Update(ctxt, &digest[0], sizeof(digest));
        MD5Final(&digest[0], ctxt);
 
-       bcopy(&digest[0], (void *)addr, HMACSIZE);
+       bcopy(&digest[0], (void *)addr, sizeof(digest) > l ? l : sizeof(digest));
 
        FREE(state->foo, M_TEMP);
 }
 
 static int
-ah_hmac_sha1_mature(sav)
-       struct secasvar *sav;
+ah_hmac_sha1_mature(struct secasvar *sav)
 {
        const struct ah_algorithm *algo;
 
@@ -615,14 +631,12 @@ ah_hmac_sha1_mature(sav)
 }
 
 static int
-ah_hmac_sha1_init(state, sav)
-       struct ah_algorithm_state *state;
-       struct secasvar *sav;
+ah_hmac_sha1_init(struct ah_algorithm_state *state, struct secasvar *sav)
 {
        u_char *ipad;
        u_char *opad;
        SHA1_CTX *ctxt;
-       u_char tk[SHA1_RESULTLEN];      /* SHA-1 generates 160 bits */
+       u_char tk[SHA1_RESULTLEN] __attribute__((aligned(4)));  /* SHA-1 generates 160 bits */
        u_char *key;
        size_t keylen;
        size_t i;
@@ -632,13 +646,13 @@ ah_hmac_sha1_init(state, sav)
 
        state->sav = sav;
        state->foo = (void *)_MALLOC(64 + 64 + sizeof(SHA1_CTX),
-                       M_TEMP, M_WAITOK);
+                       M_TEMP, M_NOWAIT);
        if (!state->foo)
                return ENOBUFS;
 
        ipad = (u_char *)state->foo;
        opad = (u_char *)(ipad + 64);
-       ctxt = (SHA1_CTX *)(opad + 64);
+       ctxt = (SHA1_CTX *)(void *)(opad + 64);
 
        /* compress the key if necessery */
        if (64 < _KEYLEN(state->sav->key_auth)) {
@@ -649,7 +663,7 @@ ah_hmac_sha1_init(state, sav)
                key = &tk[0];
                keylen = SHA1_RESULTLEN;
        } else {
-               key = _KEYBUF(state->sav->key_auth);
+               key = (u_char *) _KEYBUF(state->sav->key_auth);
                keylen = _KEYLEN(state->sav->key_auth);
        }
 
@@ -669,26 +683,21 @@ ah_hmac_sha1_init(state, sav)
 }
 
 static void
-ah_hmac_sha1_loop(state, addr, len)
-       struct ah_algorithm_state *state;
-       caddr_t addr;
-       size_t len;
+ah_hmac_sha1_loop(struct ah_algorithm_state *state, caddr_t addr, size_t len)
 {
        SHA1_CTX *ctxt;
 
        if (!state || !state->foo)
                panic("ah_hmac_sha1_loop: what?");
 
-       ctxt = (SHA1_CTX *)(((u_char *)state->foo) + 128);
+       ctxt = (SHA1_CTX *)(void *)(((u_char *)state->foo) + 128);
        SHA1Update(ctxt, (caddr_t)addr, (size_t)len);
 }
 
 static void
-ah_hmac_sha1_result(state, addr)
-       struct ah_algorithm_state *state;
-       caddr_t addr;
+ah_hmac_sha1_result(struct ah_algorithm_state *state, caddr_t addr, size_t l)
 {
-       u_char digest[SHA1_RESULTLEN];  /* SHA-1 generates 160 bits */
+       u_char digest[SHA1_RESULTLEN] __attribute__((aligned(4)));      /* SHA-1 generates 160 bits */
        u_char *ipad;
        u_char *opad;
        SHA1_CTX *ctxt;
@@ -698,7 +707,7 @@ ah_hmac_sha1_result(state, addr)
 
        ipad = (u_char *)state->foo;
        opad = (u_char *)(ipad + 64);
-       ctxt = (SHA1_CTX *)(opad + 64);
+       ctxt = (SHA1_CTX *)(void *)(opad + 64);
 
        SHA1Final((caddr_t)&digest[0], ctxt);
 
@@ -707,14 +716,23 @@ ah_hmac_sha1_result(state, addr)
        SHA1Update(ctxt, (caddr_t)&digest[0], sizeof(digest));
        SHA1Final((caddr_t)&digest[0], ctxt);
 
-       bcopy(&digest[0], (void *)addr, HMACSIZE);
+       bcopy(&digest[0], (void *)addr, sizeof(digest) > l ? l : sizeof(digest));
 
        FREE(state->foo, M_TEMP);
 }
 
+#if AH_ALL_CRYPTO
 static int
-ah_hmac_sha2_256_mature(sav)
-       struct secasvar *sav;
+ah_sumsiz_sha2_256(struct secasvar *sav)
+{
+       if (!sav)
+               return -1;
+       // return half the output size (in bytes), as per rfc 4868
+       return 16; // 256/(8*2)
+}
+
+static int
+ah_hmac_sha2_256_mature(struct secasvar *sav)
 {
        const struct ah_algorithm *algo;
 
@@ -743,14 +761,12 @@ ah_hmac_sha2_256_mature(sav)
 }
 
 static int
-ah_hmac_sha2_256_init(state, sav)
-       struct ah_algorithm_state *state;
-       struct secasvar *sav;
+ah_hmac_sha2_256_init(struct ah_algorithm_state *state, struct secasvar *sav)
 {
        u_char *ipad;
        u_char *opad;
        SHA256_CTX *ctxt;
-       u_char tk[SHA256_DIGEST_LENGTH];
+       u_char tk[SHA256_DIGEST_LENGTH] __attribute__((aligned(4)));
        u_char *key;
        size_t keylen;
        size_t i;
@@ -766,20 +782,20 @@ ah_hmac_sha2_256_init(state, sav)
 
        ipad = (u_char *)state->foo;
        opad = (u_char *)(ipad + 64);
-       ctxt = (SHA256_CTX *)(opad + 64);
+       ctxt = (SHA256_CTX *)(void *)(opad + 64);
 
        /* compress the key if necessery */
        if (64 < _KEYLEN(state->sav->key_auth)) {
                bzero(tk, sizeof(tk));
                bzero(ctxt, sizeof(*ctxt));
                SHA256_Init(ctxt);
-               SHA256_Update(ctxt, _KEYBUF(state->sav->key_auth),
+               SHA256_Update(ctxt, (const u_int8_t *) _KEYBUF(state->sav->key_auth),
                    _KEYLEN(state->sav->key_auth));
                SHA256_Final(&tk[0], ctxt);
                key = &tk[0];
                keylen = sizeof(tk) < 64 ? sizeof(tk) : 64;
        } else {
-               key = _KEYBUF(state->sav->key_auth);
+               key = (u_char *) _KEYBUF(state->sav->key_auth);
                keylen = _KEYLEN(state->sav->key_auth);
        }
 
@@ -800,26 +816,25 @@ ah_hmac_sha2_256_init(state, sav)
 }
 
 static void
-ah_hmac_sha2_256_loop(state, addr, len)
-       struct ah_algorithm_state *state;
-       caddr_t addr;
-       size_t len;
+ah_hmac_sha2_256_loop(struct ah_algorithm_state *state,
+                     caddr_t addr,
+                     size_t len)
 {
        SHA256_CTX *ctxt;
 
        if (!state || !state->foo)
                panic("ah_hmac_sha2_256_loop: what?");
 
-       ctxt = (SHA256_CTX *)(((u_char *)state->foo) + 128);
-       SHA256_Update(ctxt, (caddr_t)addr, (size_t)len);
+       ctxt = (SHA256_CTX *)(void *)(((u_char *)state->foo) + 128);
+       SHA256_Update(ctxt, (const u_int8_t *)addr, (size_t)len);
 }
 
 static void
-ah_hmac_sha2_256_result(state, addr)
-       struct ah_algorithm_state *state;
-       caddr_t addr;
+ah_hmac_sha2_256_result(struct ah_algorithm_state *state,
+                       caddr_t addr,
+                       size_t l)
 {
-       u_char digest[SHA256_DIGEST_LENGTH];
+       u_char digest[SHA256_DIGEST_LENGTH] __attribute__((aligned(4)));
        u_char *ipad;
        u_char *opad;
        SHA256_CTX *ctxt;
@@ -829,24 +844,31 @@ ah_hmac_sha2_256_result(state, addr)
 
        ipad = (u_char *)state->foo;
        opad = (u_char *)(ipad + 64);
-       ctxt = (SHA256_CTX *)(opad + 64);
+       ctxt = (SHA256_CTX *)(void *)(opad + 64);
 
-       SHA256_Final((caddr_t)&digest[0], ctxt);
+       SHA256_Final((u_int8_t *)digest, ctxt);
 
-       bzero(ctxt, sizeof(*ctxt));
        SHA256_Init(ctxt);
        SHA256_Update(ctxt, opad, 64);
-       SHA256_Update(ctxt, (caddr_t)&digest[0], sizeof(digest));
-       SHA256_Final((caddr_t)&digest[0], ctxt);
+       SHA256_Update(ctxt, (const u_int8_t *)digest, sizeof(digest));
+       SHA256_Final((u_int8_t *)digest, ctxt);
 
-       bcopy(&digest[0], (void *)addr, HMACSIZE);
+       bcopy(&digest[0], (void *)addr, sizeof(digest) > l ? l : sizeof(digest));
 
        FREE(state->foo, M_TEMP);
 }
 
 static int
-ah_hmac_sha2_384_mature(sav)
-       struct secasvar *sav;
+ah_sumsiz_sha2_384(struct secasvar *sav)
+{
+       if (!sav)
+               return -1;
+       // return half the output size (in bytes), as per rfc 4868
+       return 24; // 384/(8*2)
+}
+
+static int
+ah_hmac_sha2_384_mature(struct secasvar *sav)
 {
        const struct ah_algorithm *algo;
 
@@ -875,14 +897,12 @@ ah_hmac_sha2_384_mature(sav)
 }
 
 static int
-ah_hmac_sha2_384_init(state, sav)
-       struct ah_algorithm_state *state;
-       struct secasvar *sav;
+ah_hmac_sha2_384_init(struct ah_algorithm_state *state, struct secasvar *sav)
 {
        u_char *ipad;
        u_char *opad;
        SHA384_CTX *ctxt;
-       u_char tk[SHA384_DIGEST_LENGTH];
+       u_char tk[SHA384_DIGEST_LENGTH] __attribute__((aligned(4)));
        u_char *key;
        size_t keylen;
        size_t i;
@@ -891,66 +911,64 @@ ah_hmac_sha2_384_init(state, sav)
                panic("ah_hmac_sha2_384_init: what?");
 
        state->sav = sav;
-       state->foo = (void *)_MALLOC(64 + 64 + sizeof(SHA384_CTX),
-           M_TEMP, M_NOWAIT);
+       state->foo = (void *)_MALLOC(128 + 128 + sizeof(SHA384_CTX),
+           M_TEMP, M_NOWAIT | M_ZERO);
        if (!state->foo)
                return ENOBUFS;
-       bzero(state->foo, 64 + 64 + sizeof(SHA384_CTX));
 
        ipad = (u_char *)state->foo;
-       opad = (u_char *)(ipad + 64);
-       ctxt = (SHA384_CTX *)(opad + 64);
+       opad = (u_char *)(ipad + 128);
+       ctxt = (SHA384_CTX *)(void *)(opad + 128);
 
        /* compress the key if necessery */
-       if (64 < _KEYLEN(state->sav->key_auth)) {
+       if (128 < _KEYLEN(state->sav->key_auth)) {
                bzero(tk, sizeof(tk));
                bzero(ctxt, sizeof(*ctxt));
                SHA384_Init(ctxt);
-               SHA384_Update(ctxt, _KEYBUF(state->sav->key_auth),
+               SHA384_Update(ctxt, (const u_int8_t *) _KEYBUF(state->sav->key_auth),
                    _KEYLEN(state->sav->key_auth));
                SHA384_Final(&tk[0], ctxt);
                key = &tk[0];
-               keylen = sizeof(tk) < 64 ? sizeof(tk) : 64;
+               keylen = sizeof(tk) < 128 ? sizeof(tk) : 128;
        } else {
-               key = _KEYBUF(state->sav->key_auth);
+               key = (u_char *) _KEYBUF(state->sav->key_auth);
                keylen = _KEYLEN(state->sav->key_auth);
        }
 
-       bzero(ipad, 64);
-       bzero(opad, 64);
+       bzero(ipad, 128);
+       bzero(opad, 128);
        bcopy(key, ipad, keylen);
        bcopy(key, opad, keylen);
-       for (i = 0; i < 64; i++) {
+       for (i = 0; i < 128; i++) {
                ipad[i] ^= 0x36;
                opad[i] ^= 0x5c;
        }
 
        bzero(ctxt, sizeof(*ctxt));
        SHA384_Init(ctxt);
-       SHA384_Update(ctxt, ipad, 64);
+       SHA384_Update(ctxt, ipad, 128);
 
        return 0;
 }
 
 static void
-ah_hmac_sha2_384_loop(state, addr, len)
-       struct ah_algorithm_state *state;
-       caddr_t addr;
-       size_t len;
+ah_hmac_sha2_384_loop(struct ah_algorithm_state *state,
+                     caddr_t addr,
+                     size_t len)
 {
        SHA384_CTX *ctxt;
 
        if (!state || !state->foo)
                panic("ah_hmac_sha2_384_loop: what?");
 
-       ctxt = (SHA384_CTX *)(((u_char *)state->foo) + 128);
-       SHA384_Update(ctxt, (caddr_t)addr, (size_t)len);
+       ctxt = (SHA384_CTX *)(void *)(((u_char *)state->foo) + 256);
+       SHA384_Update(ctxt, (const u_int8_t *)addr, (size_t)len);
 }
 
 static void
-ah_hmac_sha2_384_result(state, addr)
-       struct ah_algorithm_state *state;
-       caddr_t addr;
+ah_hmac_sha2_384_result(struct ah_algorithm_state *state,
+                       caddr_t addr,
+                       size_t l)
 {
        u_char digest[SHA384_DIGEST_LENGTH];
        u_char *ipad;
@@ -961,25 +979,32 @@ ah_hmac_sha2_384_result(state, addr)
                panic("ah_hmac_sha2_384_result: what?");
 
        ipad = (u_char *)state->foo;
-       opad = (u_char *)(ipad + 64);
-       ctxt = (SHA384_CTX *)(opad + 64);
+       opad = (u_char *)(ipad + 128);
+       ctxt = (SHA384_CTX *)(void *)(opad + 128);
 
-       SHA384_Final((caddr_t)&digest[0], ctxt);
+       SHA384_Final((u_int8_t *)digest, ctxt);
 
-       bzero(ctxt, sizeof(*ctxt));
        SHA384_Init(ctxt);
-       SHA384_Update(ctxt, opad, 64);
-       SHA384_Update(ctxt, (caddr_t)&digest[0], sizeof(digest));
-       SHA384_Final((caddr_t)&digest[0], ctxt);
+       SHA384_Update(ctxt, opad, 128);
+       SHA384_Update(ctxt, (const u_int8_t *)digest, sizeof(digest));
+       SHA384_Final((u_int8_t *)digest, ctxt);
 
-       bcopy(&digest[0], (void *)addr, HMACSIZE);
+       bcopy(&digest[0], (void *)addr, sizeof(digest) > l ? l : sizeof(digest));
 
        FREE(state->foo, M_TEMP);
 }
 
 static int
-ah_hmac_sha2_512_mature(sav)
-       struct secasvar *sav;
+ah_sumsiz_sha2_512(struct secasvar *sav)
+{
+       if (!sav)
+               return -1;
+       // return half the output size (in bytes), as per rfc 4868
+       return 32; // 512/(8*2)
+}
+
+static int
+ah_hmac_sha2_512_mature(struct secasvar *sav)
 {
        const struct ah_algorithm *algo;
 
@@ -1008,14 +1033,12 @@ ah_hmac_sha2_512_mature(sav)
 }
 
 static int
-ah_hmac_sha2_512_init(state, sav)
-       struct ah_algorithm_state *state;
-       struct secasvar *sav;
+ah_hmac_sha2_512_init(struct ah_algorithm_state *state, struct secasvar *sav)
 {
        u_char *ipad;
        u_char *opad;
        SHA512_CTX *ctxt;
-       u_char tk[SHA512_DIGEST_LENGTH];
+       u_char tk[SHA512_DIGEST_LENGTH] __attribute__((aligned(4)));
        u_char *key;
        size_t keylen;
        size_t i;
@@ -1024,68 +1047,66 @@ ah_hmac_sha2_512_init(state, sav)
                panic("ah_hmac_sha2_512_init: what?");
 
        state->sav = sav;
-       state->foo = (void *)_MALLOC(64 + 64 + sizeof(SHA512_CTX),
-           M_TEMP, M_NOWAIT);
+       state->foo = (void *)_MALLOC(128 + 128 + sizeof(SHA512_CTX),
+           M_TEMP, M_NOWAIT | M_ZERO);
        if (!state->foo)
                return ENOBUFS;
-       bzero(state->foo, 64 + 64 + sizeof(SHA512_CTX));
 
        ipad = (u_char *)state->foo;
-       opad = (u_char *)(ipad + 64);
-       ctxt = (SHA512_CTX *)(opad + 64);
+       opad = (u_char *)(ipad + 128);
+       ctxt = (SHA512_CTX *)(void *)(opad + 128);
 
        /* compress the key if necessery */
-       if (64 < _KEYLEN(state->sav->key_auth)) {
+       if (128 < _KEYLEN(state->sav->key_auth)) {
                bzero(tk, sizeof(tk));
                bzero(ctxt, sizeof(*ctxt));
                SHA512_Init(ctxt);
-               SHA512_Update(ctxt, _KEYBUF(state->sav->key_auth),
+               SHA512_Update(ctxt, (const u_int8_t *) _KEYBUF(state->sav->key_auth),
                    _KEYLEN(state->sav->key_auth));
                SHA512_Final(&tk[0], ctxt);
                key = &tk[0];
-               keylen = sizeof(tk) < 64 ? sizeof(tk) : 64;
+               keylen = sizeof(tk) < 128 ? sizeof(tk) : 128;
        } else {
-               key = _KEYBUF(state->sav->key_auth);
+               key = (u_char *) _KEYBUF(state->sav->key_auth);
                keylen = _KEYLEN(state->sav->key_auth);
        }
 
-       bzero(ipad, 64);
-       bzero(opad, 64);
+       bzero(ipad, 128);
+       bzero(opad, 128);
        bcopy(key, ipad, keylen);
        bcopy(key, opad, keylen);
-       for (i = 0; i < 64; i++) {
+       for (i = 0; i < 128; i++) {
                ipad[i] ^= 0x36;
                opad[i] ^= 0x5c;
        }
 
        bzero(ctxt, sizeof(*ctxt));
        SHA512_Init(ctxt);
-       SHA512_Update(ctxt, ipad, 64);
+       SHA512_Update(ctxt, ipad, 128);
 
        return 0;
 }
 
 static void
-ah_hmac_sha2_512_loop(state, addr, len)
-       struct ah_algorithm_state *state;
-       caddr_t addr;
-       size_t len;
+ah_hmac_sha2_512_loop(struct ah_algorithm_state *state,
+                     caddr_t addr,
+                     size_t len)
 {
        SHA512_CTX *ctxt;
 
        if (!state || !state->foo)
                panic("ah_hmac_sha2_512_loop: what?");
 
-       ctxt = (SHA512_CTX *)(((u_char *)state->foo) + 128);
-       SHA512_Update(ctxt, (caddr_t)addr, (size_t)len);
+       ctxt = (SHA512_CTX *)(void *)(((u_char *)state->foo) + 256);
+       SHA512_Update(ctxt, (const u_int8_t *) addr, (size_t)len);
 }
 
 static void
-ah_hmac_sha2_512_result(state, addr)
-       struct ah_algorithm_state *state;
-       caddr_t addr;
+ah_hmac_sha2_512_result(struct ah_algorithm_state *state,
+                       caddr_t addr,
+                       size_t l)
 {
-       u_char digest[SHA512_DIGEST_LENGTH];
+       u_char digest[SHA512_DIGEST_LENGTH] __attribute__((aligned(4)));
        u_char *ipad;
        u_char *opad;
        SHA512_CTX *ctxt;
@@ -1094,21 +1115,21 @@ ah_hmac_sha2_512_result(state, addr)
                panic("ah_hmac_sha2_512_result: what?");
 
        ipad = (u_char *)state->foo;
-       opad = (u_char *)(ipad + 64);
-       ctxt = (SHA512_CTX *)(opad + 64);
+       opad = (u_char *)(ipad + 128);
+       ctxt = (SHA512_CTX *)(void *)(opad + 128);
 
-       SHA512_Final((caddr_t)&digest[0], ctxt);
+       SHA512_Final((u_int8_t *)digest, ctxt);
 
-       bzero(ctxt, sizeof(*ctxt));
        SHA512_Init(ctxt);
-       SHA512_Update(ctxt, opad, 64);
-       SHA512_Update(ctxt, (caddr_t)&digest[0], sizeof(digest));
-       SHA512_Final((caddr_t)&digest[0], ctxt);
+       SHA512_Update(ctxt, opad, 128);
+       SHA512_Update(ctxt, (const u_int8_t *)digest, sizeof(digest));
+       SHA512_Final((u_int8_t *)digest, ctxt);
 
-       bcopy(&digest[0], (void *)addr, HMACSIZE);
+       bcopy(&digest[0], (void *)addr, sizeof(digest) > l ? l : sizeof(digest));
 
        FREE(state->foo, M_TEMP);
 }
+#endif /* AH_ALL_CRYPTO */
 
 /*------------------------------------------------------------*/
 
@@ -1116,12 +1137,9 @@ ah_hmac_sha2_512_result(state, addr)
  * go generate the checksum.
  */
 static void
-ah_update_mbuf(m, off, len, algo, algos)
-       struct mbuf *m;
-       int off;
-       int len;
-       const struct ah_algorithm *algo;
-       struct ah_algorithm_state *algos;
+ah_update_mbuf(struct mbuf *m,int off, int len,
+              const struct ah_algorithm *algo,
+              struct ah_algorithm_state *algos)
 {
        struct mbuf *n;
        int tlen;
@@ -1166,18 +1184,14 @@ ah_update_mbuf(m, off, len, algo, algos)
  * Don't use m_copy(), it will try to share cluster mbuf by using refcnt.
  */
 int
-ah4_calccksum(m, ahdat, len, algo, sav)
-       struct mbuf *m;
-       caddr_t ahdat;
-       size_t len;
-       const struct ah_algorithm *algo;
-       struct secasvar *sav;
+ah4_calccksum(struct mbuf *m, caddr_t ahdat, size_t len,
+             const struct ah_algorithm *algo, struct secasvar *sav)
 {
        int off;
        int hdrtype;
        size_t advancewidth;
        struct ah_algorithm_state algos;
-       u_char sumbuf[AH_MAXSUMSIZE];
+       u_char sumbuf[AH_MAXSUMSIZE] __attribute__((aligned(4)));
        int error = 0;
        int ahseen;
        struct mbuf *n = NULL;
@@ -1309,8 +1323,9 @@ again:
                                        break;
                                i += l;
                        }
+
                        p = mtod(n, u_char *) + sizeof(struct ip);
-                       (algo->update)(&algos, p, hlen - sizeof(struct ip));
+                       (algo->update)(&algos, (caddr_t)p, hlen - sizeof(struct ip));
 
                        m_free(n);
                        n = NULL;
@@ -1386,7 +1401,7 @@ again:
                goto fail;
        }
 
-       (algo->result)(&algos, &sumbuf[0]);
+       (algo->result)(&algos, (caddr_t) &sumbuf[0], sizeof(sumbuf));
        bcopy(&sumbuf[0], ahdat, (*algo->sumsiz)(sav));
 
        if (n)
@@ -1409,12 +1424,8 @@ fail:
  * Don't use m_copy(), it will try to share cluster mbuf by using refcnt.
  */
 int
-ah6_calccksum(m, ahdat, len, algo, sav)
-       struct mbuf *m;
-       caddr_t ahdat;
-       size_t len;
-       const struct ah_algorithm *algo;
-       struct secasvar *sav;
+ah6_calccksum(struct mbuf *m, caddr_t ahdat, size_t len,
+             const struct ah_algorithm *algo, struct secasvar *sav)
 {
        int newoff, off;
        int proto, nxt;
@@ -1422,7 +1433,7 @@ ah6_calccksum(m, ahdat, len, algo, sav)
        int error;
        int ahseen;
        struct ah_algorithm_state algos;
-       u_char sumbuf[AH_MAXSUMSIZE];
+       u_char sumbuf[AH_MAXSUMSIZE] __attribute__((aligned(4)));
 
        if ((m->m_flags & M_PKTHDR) == 0)
                return EINVAL;
@@ -1613,7 +1624,7 @@ ah6_calccksum(m, ahdat, len, algo, sav)
                goto fail;
        }
 
-       (algo->result)(&algos, &sumbuf[0]);
+       (algo->result)(&algos, (caddr_t) &sumbuf[0], sizeof(sumbuf));
        bcopy(&sumbuf[0], ahdat, (*algo->sumsiz)(sav));
 
        /* just in case */