summaryrefslogtreecommitdiffstats
path: root/sys/netinet6/ah_core.c
diff options
context:
space:
mode:
authorume <ume@FreeBSD.org>2003-10-12 09:41:42 +0000
committerume <ume@FreeBSD.org>2003-10-12 09:41:42 +0000
commit2da6bcd32608963a87a6204b27810701287c97c2 (patch)
tree2decf36a0c89d43e5a0e70adbde87c593c8c9376 /sys/netinet6/ah_core.c
parent430e4069d35afcda4852e4771595eeeb4b5bbe02 (diff)
downloadFreeBSD-src-2da6bcd32608963a87a6204b27810701287c97c2.zip
FreeBSD-src-2da6bcd32608963a87a6204b27810701287c97c2.tar.gz
- RIPEMD160 support
- pass size arg to ah->result (avoid assuming result buffer size) Obtained from: KAME
Diffstat (limited to 'sys/netinet6/ah_core.c')
-rw-r--r--sys/netinet6/ah_core.c390
1 files changed, 186 insertions, 204 deletions
diff --git a/sys/netinet6/ah_core.c b/sys/netinet6/ah_core.c
index 2785fa0..a456926 100644
--- a/sys/netinet6/ah_core.c
+++ b/sys/netinet6/ah_core.c
@@ -85,6 +85,8 @@
#include <sys/md5.h>
#include <crypto/sha1.h>
#include <crypto/sha2/sha2.h>
+#include <crypto/ripemd160/rmd160.h>
+#define RIPEMD160_RESULTLEN 20
#include <net/net_osdep.h>
@@ -92,52 +94,60 @@
static int ah_sumsiz_1216 __P((struct secasvar *));
static int ah_sumsiz_zero __P((struct secasvar *));
+static int ah_common_mature __P((struct secasvar *));
static int ah_none_mature __P((struct secasvar *));
static int ah_none_init __P((struct ah_algorithm_state *, struct secasvar *));
static void ah_none_loop __P((struct ah_algorithm_state *, caddr_t, size_t));
-static void ah_none_result __P((struct ah_algorithm_state *, caddr_t));
+static void ah_none_result __P((struct ah_algorithm_state *, caddr_t, size_t));
static int ah_keyed_md5_mature __P((struct secasvar *));
static int ah_keyed_md5_init __P((struct ah_algorithm_state *,
struct secasvar *));
static void ah_keyed_md5_loop __P((struct ah_algorithm_state *, caddr_t,
size_t));
-static void ah_keyed_md5_result __P((struct ah_algorithm_state *, caddr_t));
-static int ah_keyed_sha1_mature __P((struct secasvar *));
+static void ah_keyed_md5_result __P((struct ah_algorithm_state *,
+ caddr_t, size_t));
static int ah_keyed_sha1_init __P((struct ah_algorithm_state *,
struct secasvar *));
static void ah_keyed_sha1_loop __P((struct ah_algorithm_state *, caddr_t,
size_t));
-static void ah_keyed_sha1_result __P((struct ah_algorithm_state *, caddr_t));
-static int ah_hmac_md5_mature __P((struct secasvar *));
+static void ah_keyed_sha1_result __P((struct ah_algorithm_state *, caddr_t,
+ size_t));
static int ah_hmac_md5_init __P((struct ah_algorithm_state *,
struct secasvar *));
static void ah_hmac_md5_loop __P((struct ah_algorithm_state *, caddr_t,
size_t));
-static void ah_hmac_md5_result __P((struct ah_algorithm_state *, caddr_t));
-static int ah_hmac_sha1_mature __P((struct secasvar *));
+static void ah_hmac_md5_result __P((struct ah_algorithm_state *,
+ caddr_t, size_t));
static int ah_hmac_sha1_init __P((struct ah_algorithm_state *,
struct secasvar *));
static void ah_hmac_sha1_loop __P((struct ah_algorithm_state *, caddr_t,
size_t));
-static void ah_hmac_sha1_result __P((struct ah_algorithm_state *, caddr_t));
-static int ah_hmac_sha2_256_mature __P((struct secasvar *));
+static void ah_hmac_sha1_result __P((struct ah_algorithm_state *,
+ caddr_t, size_t));
static int ah_hmac_sha2_256_init __P((struct ah_algorithm_state *,
struct secasvar *));
static void ah_hmac_sha2_256_loop __P((struct ah_algorithm_state *, caddr_t,
size_t));
-static void ah_hmac_sha2_256_result __P((struct ah_algorithm_state *, caddr_t));
-static int ah_hmac_sha2_384_mature __P((struct secasvar *));
+static void ah_hmac_sha2_256_result __P((struct ah_algorithm_state *,
+ caddr_t, size_t));
static int ah_hmac_sha2_384_init __P((struct ah_algorithm_state *,
struct secasvar *));
static void ah_hmac_sha2_384_loop __P((struct ah_algorithm_state *, caddr_t,
size_t));
-static void ah_hmac_sha2_384_result __P((struct ah_algorithm_state *, caddr_t));
-static int ah_hmac_sha2_512_mature __P((struct secasvar *));
+static void ah_hmac_sha2_384_result __P((struct ah_algorithm_state *,
+ caddr_t, size_t));
static int ah_hmac_sha2_512_init __P((struct ah_algorithm_state *,
struct secasvar *));
static void ah_hmac_sha2_512_loop __P((struct ah_algorithm_state *, caddr_t,
size_t));
-static void ah_hmac_sha2_512_result __P((struct ah_algorithm_state *, caddr_t));
+static void ah_hmac_sha2_512_result __P((struct ah_algorithm_state *,
+ caddr_t, size_t));
+static int ah_hmac_ripemd160_init __P((struct ah_algorithm_state *,
+ struct secasvar *));
+static void ah_hmac_ripemd160_loop __P((struct ah_algorithm_state *, caddr_t,
+ size_t));
+static void ah_hmac_ripemd160_result __P((struct ah_algorithm_state *,
+ caddr_t, size_t));
static void ah_update_mbuf __P((struct mbuf *, int, int,
const struct ah_algorithm *, struct ah_algorithm_state *));
@@ -148,32 +158,36 @@ ah_algorithm_lookup(idx)
{
/* checksum algorithms */
static struct ah_algorithm ah_algorithms[] = {
- { ah_sumsiz_1216, ah_hmac_md5_mature, 128, 128, "hmac-md5",
+ { ah_sumsiz_1216, ah_common_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_sumsiz_1216, ah_common_mature, 160, 160, "hmac-sha1",
ah_hmac_sha1_init, ah_hmac_sha1_loop,
ah_hmac_sha1_result, },
{ ah_sumsiz_1216, ah_keyed_md5_mature, 128, 128, "keyed-md5",
ah_keyed_md5_init, ah_keyed_md5_loop,
ah_keyed_md5_result, },
- { ah_sumsiz_1216, ah_keyed_sha1_mature, 160, 160, "keyed-sha1",
+ { ah_sumsiz_1216, ah_common_mature, 160, 160, "keyed-sha1",
ah_keyed_sha1_init, ah_keyed_sha1_loop,
ah_keyed_sha1_result, },
{ 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_sumsiz_1216, ah_common_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_sumsiz_1216, ah_common_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_sumsiz_1216, ah_common_mature, 512, 512,
"hmac-sha2-512",
ah_hmac_sha2_512_init, ah_hmac_sha2_512_loop,
ah_hmac_sha2_512_result, },
+ { ah_sumsiz_1216, ah_common_mature, 160, 160,
+ "hmac-ripemd160",
+ ah_hmac_ripemd160_init, ah_hmac_ripemd160_loop,
+ ah_hmac_ripemd160_result, },
};
switch (idx) {
@@ -193,6 +207,8 @@ ah_algorithm_lookup(idx)
return &ah_algorithms[6];
case SADB_X_AALG_SHA2_512:
return &ah_algorithms[7];
+ case SADB_X_AALG_RIPEMD160HMAC:
+ return &ah_algorithms[8];
default:
return NULL;
}
@@ -221,6 +237,34 @@ ah_sumsiz_zero(sav)
}
static int
+ah_common_mature(sav)
+ struct secasvar *sav;
+{
+ const struct ah_algorithm *algo;
+
+ if (!sav->key_auth) {
+ ipseclog((LOG_ERR, "ah_common_mature: no key is given.\n"));
+ return 1;
+ }
+
+ algo = ah_algorithm_lookup(sav->alg_auth);
+ if (!algo) {
+ ipseclog((LOG_ERR, "ah_common_mature: unsupported algorithm.\n"));
+ return 1;
+ }
+
+ if (sav->key_auth->sadb_key_bits < algo->keymin ||
+ algo->keymax < sav->key_auth->sadb_key_bits) {
+ ipseclog((LOG_ERR,
+ "ah_common_mature: invalid key length %d for %s.\n",
+ sav->key_auth->sadb_key_bits, algo->name));
+ return 1;
+ }
+
+ return 0;
+}
+
+static int
ah_none_mature(sav)
struct secasvar *sav;
{
@@ -250,9 +294,10 @@ ah_none_loop(state, addr, len)
}
static void
-ah_none_result(state, addr)
+ah_none_result(state, addr, l)
struct ah_algorithm_state *state;
caddr_t addr;
+ size_t l;
{
}
@@ -335,9 +380,10 @@ ah_keyed_md5_loop(state, addr, len)
}
static void
-ah_keyed_md5_result(state, addr)
+ah_keyed_md5_result(state, addr, l)
struct ah_algorithm_state *state;
caddr_t addr;
+ size_t l;
{
u_char digest[16];
@@ -355,34 +401,6 @@ ah_keyed_md5_result(state, addr)
}
static int
-ah_keyed_sha1_mature(sav)
- struct secasvar *sav;
-{
- const struct ah_algorithm *algo;
-
- if (!sav->key_auth) {
- ipseclog((LOG_ERR, "ah_keyed_sha1_mature: no key is given.\n"));
- return 1;
- }
-
- algo = ah_algorithm_lookup(sav->alg_auth);
- if (!algo) {
- ipseclog((LOG_ERR, "ah_keyed_sha1_mature: unsupported algorithm.\n"));
- return 1;
- }
-
- if (sav->key_auth->sadb_key_bits < algo->keymin
- || algo->keymax < sav->key_auth->sadb_key_bits) {
- ipseclog((LOG_ERR,
- "ah_keyed_sha1_mature: invalid key length %d.\n",
- sav->key_auth->sadb_key_bits));
- return 1;
- }
-
- return 0;
-}
-
-static int
ah_keyed_sha1_init(state, sav)
struct ah_algorithm_state *state;
struct secasvar *sav;
@@ -456,9 +474,10 @@ ah_keyed_sha1_loop(state, addr, len)
}
static void
-ah_keyed_sha1_result(state, addr)
+ah_keyed_sha1_result(state, addr, l)
struct ah_algorithm_state *state;
caddr_t addr;
+ size_t l;
{
u_char digest[SHA1_RESULTLEN]; /* SHA-1 generates 160 bits */
SHA1_CTX *ctxt;
@@ -478,34 +497,6 @@ ah_keyed_sha1_result(state, addr)
}
static int
-ah_hmac_md5_mature(sav)
- struct secasvar *sav;
-{
- const struct ah_algorithm *algo;
-
- if (!sav->key_auth) {
- ipseclog((LOG_ERR, "ah_hmac_md5_mature: no key is given.\n"));
- return 1;
- }
-
- algo = ah_algorithm_lookup(sav->alg_auth);
- if (!algo) {
- ipseclog((LOG_ERR, "ah_hmac_md5_mature: unsupported algorithm.\n"));
- return 1;
- }
-
- if (sav->key_auth->sadb_key_bits < algo->keymin
- || algo->keymax < sav->key_auth->sadb_key_bits) {
- ipseclog((LOG_ERR,
- "ah_hmac_md5_mature: invalid key length %d.\n",
- sav->key_auth->sadb_key_bits));
- return 1;
- }
-
- return 0;
-}
-
-static int
ah_hmac_md5_init(state, sav)
struct ah_algorithm_state *state;
struct secasvar *sav;
@@ -573,9 +564,10 @@ ah_hmac_md5_loop(state, addr, len)
}
static void
-ah_hmac_md5_result(state, addr)
+ah_hmac_md5_result(state, addr, l)
struct ah_algorithm_state *state;
caddr_t addr;
+ size_t l;
{
u_char digest[16];
u_char *ipad;
@@ -602,34 +594,6 @@ ah_hmac_md5_result(state, addr)
}
static int
-ah_hmac_sha1_mature(sav)
- struct secasvar *sav;
-{
- const struct ah_algorithm *algo;
-
- if (!sav->key_auth) {
- ipseclog((LOG_ERR, "ah_hmac_sha1_mature: no key is given.\n"));
- return 1;
- }
-
- algo = ah_algorithm_lookup(sav->alg_auth);
- if (!algo) {
- ipseclog((LOG_ERR, "ah_hmac_sha1_mature: unsupported algorithm.\n"));
- return 1;
- }
-
- if (sav->key_auth->sadb_key_bits < algo->keymin
- || algo->keymax < sav->key_auth->sadb_key_bits) {
- ipseclog((LOG_ERR,
- "ah_hmac_sha1_mature: invalid key length %d.\n",
- sav->key_auth->sadb_key_bits));
- return 1;
- }
-
- return 0;
-}
-
-static int
ah_hmac_sha1_init(state, sav)
struct ah_algorithm_state *state;
struct secasvar *sav;
@@ -699,9 +663,10 @@ ah_hmac_sha1_loop(state, addr, len)
}
static void
-ah_hmac_sha1_result(state, addr)
+ah_hmac_sha1_result(state, addr, l)
struct ah_algorithm_state *state;
caddr_t addr;
+ size_t l;
{
u_char digest[SHA1_RESULTLEN]; /* SHA-1 generates 160 bits */
u_char *ipad;
@@ -728,36 +693,6 @@ ah_hmac_sha1_result(state, addr)
}
static int
-ah_hmac_sha2_256_mature(sav)
- struct secasvar *sav;
-{
- const struct ah_algorithm *algo;
-
- if (!sav->key_auth) {
- ipseclog((LOG_ERR,
- "ah_hmac_sha2_256_mature: no key is given.\n"));
- return 1;
- }
-
- algo = ah_algorithm_lookup(sav->alg_auth);
- if (!algo) {
- ipseclog((LOG_ERR,
- "ah_hmac_sha2_256_mature: unsupported algorithm.\n"));
- return 1;
- }
-
- if (sav->key_auth->sadb_key_bits < algo->keymin ||
- algo->keymax < sav->key_auth->sadb_key_bits) {
- ipseclog((LOG_ERR,
- "ah_hmac_sha2_256_mature: invalid key length %d.\n",
- sav->key_auth->sadb_key_bits));
- return 1;
- }
-
- return 0;
-}
-
-static int
ah_hmac_sha2_256_init(state, sav)
struct ah_algorithm_state *state;
struct secasvar *sav;
@@ -830,9 +765,10 @@ ah_hmac_sha2_256_loop(state, addr, len)
}
static void
-ah_hmac_sha2_256_result(state, addr)
+ah_hmac_sha2_256_result(state, addr, l)
struct ah_algorithm_state *state;
caddr_t addr;
+ size_t l;
{
u_char digest[SHA256_DIGEST_LENGTH];
u_char *ipad;
@@ -860,36 +796,6 @@ ah_hmac_sha2_256_result(state, addr)
}
static int
-ah_hmac_sha2_384_mature(sav)
- struct secasvar *sav;
-{
- const struct ah_algorithm *algo;
-
- if (!sav->key_auth) {
- ipseclog((LOG_ERR,
- "ah_hmac_sha2_384_mature: no key is given.\n"));
- return 1;
- }
-
- algo = ah_algorithm_lookup(sav->alg_auth);
- if (!algo) {
- ipseclog((LOG_ERR,
- "ah_hmac_sha2_384_mature: unsupported algorithm.\n"));
- return 1;
- }
-
- if (sav->key_auth->sadb_key_bits < algo->keymin ||
- algo->keymax < sav->key_auth->sadb_key_bits) {
- ipseclog((LOG_ERR,
- "ah_hmac_sha2_384_mature: invalid key length %d.\n",
- sav->key_auth->sadb_key_bits));
- return 1;
- }
-
- return 0;
-}
-
-static int
ah_hmac_sha2_384_init(state, sav)
struct ah_algorithm_state *state;
struct secasvar *sav;
@@ -963,9 +869,10 @@ ah_hmac_sha2_384_loop(state, addr, len)
}
static void
-ah_hmac_sha2_384_result(state, addr)
+ah_hmac_sha2_384_result(state, addr, l)
struct ah_algorithm_state *state;
caddr_t addr;
+ size_t l;
{
u_char digest[SHA384_DIGEST_LENGTH];
u_char *ipad;
@@ -993,36 +900,6 @@ ah_hmac_sha2_384_result(state, addr)
}
static int
-ah_hmac_sha2_512_mature(sav)
- struct secasvar *sav;
-{
- const struct ah_algorithm *algo;
-
- if (!sav->key_auth) {
- ipseclog((LOG_ERR,
- "ah_hmac_sha2_512_mature: no key is given.\n"));
- return 1;
- }
-
- algo = ah_algorithm_lookup(sav->alg_auth);
- if (!algo) {
- ipseclog((LOG_ERR,
- "ah_hmac_sha2_512_mature: unsupported algorithm.\n"));
- return 1;
- }
-
- if (sav->key_auth->sadb_key_bits < algo->keymin ||
- algo->keymax < sav->key_auth->sadb_key_bits) {
- ipseclog((LOG_ERR,
- "ah_hmac_sha2_512_mature: invalid key length %d.\n",
- sav->key_auth->sadb_key_bits));
- return 1;
- }
-
- return 0;
-}
-
-static int
ah_hmac_sha2_512_init(state, sav)
struct ah_algorithm_state *state;
struct secasvar *sav;
@@ -1096,9 +973,10 @@ ah_hmac_sha2_512_loop(state, addr, len)
}
static void
-ah_hmac_sha2_512_result(state, addr)
+ah_hmac_sha2_512_result(state, addr, l)
struct ah_algorithm_state *state;
caddr_t addr;
+ size_t l;
{
u_char digest[SHA512_DIGEST_LENGTH];
u_char *ipad;
@@ -1125,6 +1003,110 @@ ah_hmac_sha2_512_result(state, addr)
free(state->foo, M_TEMP);
}
+static int
+ah_hmac_ripemd160_init(state, sav)
+ struct ah_algorithm_state *state;
+ struct secasvar *sav;
+{
+ u_char *ipad;
+ u_char *opad;
+ RMD160_CTX *ctxt;
+ u_char tk[RIPEMD160_RESULTLEN];
+ u_char *key;
+ size_t keylen;
+ size_t i;
+
+ if (!state)
+ panic("ah_hmac_ripemd160_init: what?");
+
+ state->sav = sav;
+ state->foo = (void *)malloc(64 + 64 + sizeof(RMD160_CTX),
+ M_TEMP, M_NOWAIT);
+ if (!state->foo)
+ return ENOBUFS;
+ bzero(state->foo, 64 + 64 + sizeof(RMD160_CTX));
+
+ ipad = (u_char *)state->foo;
+ opad = (u_char *)(ipad + 64);
+ ctxt = (RMD160_CTX *)(opad + 64);
+
+ /* compress the key if necessery */
+ if (64 < _KEYLEN(state->sav->key_auth)) {
+ bzero(tk, sizeof(tk));
+ bzero(ctxt, sizeof(*ctxt));
+ RMD160Init(ctxt);
+ RMD160Update(ctxt, _KEYBUF(state->sav->key_auth),
+ _KEYLEN(state->sav->key_auth));
+ RMD160Final(&tk[0], ctxt);
+ key = &tk[0];
+ keylen = sizeof(tk) < 64 ? sizeof(tk) : 64;
+ } else {
+ key = _KEYBUF(state->sav->key_auth);
+ keylen = _KEYLEN(state->sav->key_auth);
+ }
+
+ bzero(ipad, 64);
+ bzero(opad, 64);
+ bcopy(key, ipad, keylen);
+ bcopy(key, opad, keylen);
+ for (i = 0; i < 64; i++) {
+ ipad[i] ^= 0x36;
+ opad[i] ^= 0x5c;
+ }
+
+ bzero(ctxt, sizeof(*ctxt));
+ RMD160Init(ctxt);
+ RMD160Update(ctxt, ipad, 64);
+
+ return 0;
+}
+
+static void
+ah_hmac_ripemd160_loop(state, addr, len)
+ struct ah_algorithm_state *state;
+ caddr_t addr;
+ size_t len;
+{
+ RMD160_CTX *ctxt;
+
+ if (!state || !state->foo)
+ panic("ah_hmac_ripemd160_loop: what?");
+
+ ctxt = (RMD160_CTX *)(((u_char *)state->foo) + 128);
+ RMD160Update(ctxt, (caddr_t)addr, (size_t)len);
+}
+
+static void
+ah_hmac_ripemd160_result(state, addr, l)
+ struct ah_algorithm_state *state;
+ caddr_t addr;
+ size_t l;
+{
+ u_char digest[RIPEMD160_RESULTLEN];
+ u_char *ipad;
+ u_char *opad;
+ RMD160_CTX *ctxt;
+
+ if (!state || !state->foo)
+ panic("ah_hmac_ripemd160_result: what?");
+
+ ipad = (u_char *)state->foo;
+ opad = (u_char *)(ipad + 64);
+ ctxt = (RMD160_CTX *)(opad + 64);
+
+ RMD160Final((caddr_t)digest, ctxt);
+
+ bzero(ctxt, sizeof(*ctxt));
+ RMD160Init(ctxt);
+ RMD160Update(ctxt, opad, 64);
+ RMD160Update(ctxt, (caddr_t)digest, sizeof(digest));
+ RMD160Final((caddr_t)digest, ctxt);
+
+ bcopy(digest, addr, sizeof(digest) > l ? l : sizeof(digest));
+
+ free(state->foo, M_TEMP);
+}
+
/*------------------------------------------------------------*/
/*
@@ -1401,7 +1383,7 @@ again:
goto fail;
}
- (algo->result)(&algos, &sumbuf[0]);
+ (algo->result)(&algos, sumbuf, sizeof(sumbuf));
bcopy(&sumbuf[0], ahdat, (*algo->sumsiz)(sav));
if (n)
@@ -1628,7 +1610,7 @@ ah6_calccksum(m, ahdat, len, algo, sav)
goto fail;
}
- (algo->result)(&algos, &sumbuf[0]);
+ (algo->result)(&algos, sumbuf, sizeof(sumbuf));
bcopy(&sumbuf[0], ahdat, (*algo->sumsiz)(sav));
/* just in case */
OpenPOWER on IntegriCloud