diff options
author | Niels Provos <provos@cvs.openbsd.org> | 1997-11-04 09:11:18 +0000 |
---|---|---|
committer | Niels Provos <provos@cvs.openbsd.org> | 1997-11-04 09:11:18 +0000 |
commit | 99655e667eb6f6f401a446b7c40091b28014ae9b (patch) | |
tree | 5874363a52f49f43149aa8792a34d9f0bef8e63b /sys/netinet/ip_esp_new.c | |
parent | b5f0a5904ec6fadc4a3b9c6135c788a2fc280740 (diff) |
make it easier to add additional transforms. add blowfish and cast
encryption. some more info for kernfs/ipsec.
Diffstat (limited to 'sys/netinet/ip_esp_new.c')
-rw-r--r-- | sys/netinet/ip_esp_new.c | 542 |
1 files changed, 239 insertions, 303 deletions
diff --git a/sys/netinet/ip_esp_new.c b/sys/netinet/ip_esp_new.c index 53fe1a8b454..b26e0e9c4da 100644 --- a/sys/netinet/ip_esp_new.c +++ b/sys/netinet/ip_esp_new.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_esp_new.c,v 1.9 1997/10/02 02:31:04 deraadt Exp $ */ +/* $OpenBSD: ip_esp_new.c,v 1.10 1997/11/04 09:11:11 provos Exp $ */ /* * The author of this code is John Ioannidis, ji@tla.org, @@ -9,7 +9,11 @@ * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, * by Angelos D. Keromytis, kermit@forthnet.gr. * - * Copyright (C) 1995, 1996, 1997 by John Ioannidis and Angelos D. Keromytis. + * Additional transforms and features in 1997 by Angelos D. Keromytis and + * Niels Provos. + * + * Copyright (C) 1995, 1996, 1997 by John Ioannidis, Angelos D. Keromytis + * and Niels Provos. * * Permission to use, copy, and modify this software without fee * is hereby granted, provided that this entire notice is included in @@ -66,6 +70,121 @@ extern void des_ecb3_encrypt(caddr_t, caddr_t, caddr_t, caddr_t, caddr_t, int); extern void des_ecb_encrypt(caddr_t, caddr_t, caddr_t, int); extern void des_set_key(caddr_t, caddr_t); +static void des1_encrypt(void *, u_int8_t *); +static void des3_encrypt(void *, u_int8_t *); +static void blf_encrypt(void *, u_int8_t *); +static void cast5_encrypt(void *, u_int8_t *); +static void des1_decrypt(void *, u_int8_t *); +static void des3_decrypt(void *, u_int8_t *); +static void blf_decrypt(void *, u_int8_t *); +static void cast5_decrypt(void *, u_int8_t *); + +struct esp_hash esp_new_hash[] = { + { ALG_AUTH_MD5, "HMAC-MD5-96", + AH_MD5_ALEN, + sizeof(MD5_CTX), + (void (*)(void *))MD5Init, + (void (*)(void *, u_int8_t *, u_int16_t))MD5Update, + (void (*)(u_int8_t *, void *))MD5Final + }, + { ALG_AUTH_SHA1, "HMAC-SHA1-96", + AH_SHA1_ALEN, + sizeof(SHA1_CTX), + (void (*)(void *))SHA1Init, + (void (*)(void *, u_int8_t *, u_int16_t))SHA1Update, + (void (*)(u_int8_t *, void *))SHA1Final + } +}; + +struct esp_xform esp_new_xform[] = { + { ALG_ENC_DES, "Data Encryption Standard (DES)", + ESP_DES_BLKS, ESP_DES_IVS, + 8, 8, 8 | 1, + des1_encrypt, + des1_decrypt + }, + { ALG_ENC_3DES, "Tripple DES (3DES)", + ESP_3DES_BLKS, ESP_3DES_IVS, + 24, 24, 8 | 1, + des3_encrypt, + des3_decrypt + }, + { ALG_ENC_BLF, "Blowfish", + ESP_BLF_BLKS, ESP_BLF_IVS, + 5, BLF_MAXKEYLEN, 8, + blf_encrypt, + blf_decrypt + }, + { ALG_ENC_CAST, "CAST", + ESP_CAST_BLKS, ESP_CAST_IVS, + 5, 16, 8, + cast5_encrypt, + cast5_decrypt + } +}; + +static void +des1_encrypt(void *pxd, u_int8_t *blk) +{ + struct esp_new_xdata *xd = pxd; + des_ecb_encrypt(blk, blk, (caddr_t) (xd->edx_eks[0]), 1); +} + +static void +des1_decrypt(void *pxd, u_int8_t *blk) +{ + struct esp_new_xdata *xd = pxd; + des_ecb_encrypt(blk, blk, (caddr_t) (xd->edx_eks[0]), 0); +} + +static void +des3_encrypt(void *pxd, u_int8_t *blk) +{ + struct esp_new_xdata *xd = pxd; + des_ecb3_encrypt(blk, blk, (caddr_t) (xd->edx_eks[2]), + (caddr_t) (xd->edx_eks[1]), + (caddr_t) (xd->edx_eks[0]), 1); +} + +static void +des3_decrypt(void *pxd, u_int8_t *blk) +{ + struct esp_new_xdata *xd = pxd; + des_ecb3_encrypt(blk, blk, (caddr_t) (xd->edx_eks[2]), + (caddr_t) (xd->edx_eks[1]), + (caddr_t) (xd->edx_eks[0]), 0); +} + +static void +blf_encrypt(void *pxd, u_int8_t *blk) +{ + struct esp_new_xdata *xd = pxd; + Blowfish_encipher(&xd->edx_bks, (u_int32_t *)blk, + (u_int32_t *)(blk+4)); +} + +static void +blf_decrypt(void *pxd, u_int8_t *blk) +{ + struct esp_new_xdata *xd = pxd; + Blowfish_decipher(&xd->edx_bks, (u_int32_t *)blk, + (u_int32_t *)(blk+4)); +} + +static void +cast5_encrypt(void *pxd, u_int8_t *blk) +{ + struct esp_new_xdata *xd = pxd; + cast_encrypt(&xd->edx_cks, blk, blk); +} + +static void +cast5_decrypt(void *pxd, u_int8_t *blk) +{ + struct esp_new_xdata *xd = pxd; + cast_decrypt(&xd->edx_cks, blk, blk); +} + /* * esp_new_attach() is called from the transformation initialization code. * It just returns. @@ -93,9 +212,11 @@ esp_new_init(struct tdb *tdbp, struct xformsw *xsp, struct mbuf *m) struct esp_new_xdata *xd; struct esp_new_xencap txd; struct encap_msghdr *em; + struct esp_xform *txform; + struct esp_hash *thash; caddr_t buffer = NULL; - int blocklen, i, enc_keylen, auth_keylen; - u_int32_t rk[6]; + int blocklen, i; + u_int32_t rk[14]; if (m->m_len < ENCAP_MSG_FIXED_LEN) { @@ -121,91 +242,73 @@ esp_new_init(struct tdb *tdbp, struct xformsw *xsp, struct mbuf *m) m_copydata(m, EMT_SETSPI_FLEN, ESP_NEW_XENCAP_LEN, (caddr_t) &txd); /* Check whether the encryption algorithm is supported */ - switch (txd.edx_enc_algorithm) + for (i=sizeof(esp_new_xform)/sizeof(struct esp_xform)-1; i >= 0; i--) + if (txd.edx_enc_algorithm == esp_new_xform[i].type) + break; + if (i < 0) { - case ALG_ENC_DES: - case ALG_ENC_3DES: + if (encdebug) + log(LOG_WARNING, "esp_new_init(): unsupported encryption algorithm %d specified\n", txd.edx_enc_algorithm); + return EINVAL; + } + + txform = &esp_new_xform[i]; #ifdef ENCDEBUG - if (encdebug) - printf("esp_new_init(): initialized TDB with enc algorithm %d\n", - txd.edx_enc_algorithm); + if (encdebug) + printf("esp_new_init(): initialized TDB with enc algorithm %d: %s\n", + txd.edx_enc_algorithm, esp_new_xform[i].name); #endif /* ENCDEBUG */ - break; - default: - if (encdebug) - log(LOG_WARNING, "esp_new_init(): unsupported encryption algorithm %d specified\n", txd.edx_enc_algorithm); + /* Check whether the authentication algorithm is supported */ + if (txd.edx_flags & ESP_NEW_FLAG_AUTH) + { + for (i=sizeof(esp_new_hash)/sizeof(struct esp_hash)-1; i >= 0; i--) + if (txd.edx_hash_algorithm == esp_new_hash[i].type) + break; + if (i < 0) + { + if (encdebug) + log(LOG_WARNING, "esp_new_init(): unsupported authentication algorithm %d specified\n", txd.edx_hash_algorithm); return EINVAL; - } + } - /* Check whether the authentication algorithm is supported */ - if (txd.edx_flags & ESP_NEW_FLAG_AUTH) - switch (txd.edx_hash_algorithm) - { - case ALG_AUTH_MD5: - case ALG_AUTH_SHA1: #ifdef ENCDEBUG - if (encdebug) - printf("esp_new_init(): initialized TDB with hash algorithm %d\n", txd.edx_hash_algorithm); + if (encdebug) + printf("esp_new_init(): initialized TDB with hash algorithm %d: %s\n", + txd.edx_hash_algorithm, esp_new_hash[i].name); #endif /* ENCDEBUG */ - blocklen = HMAC_BLOCK_LEN; - break; - - default: - if (encdebug) - log(LOG_WARNING, "esp_new_init(): unsupported authentication algorithm %d specified\n", txd.edx_enc_algorithm); - return EINVAL; + blocklen = HMAC_BLOCK_LEN; + thash = &esp_new_hash[i]; } - if (txd.edx_ivlen + txd.edx_keylen + EMT_SETSPI_FLEN + ESP_NEW_XENCAP_LEN - != em->em_msglen) + if (txd.edx_ivlen + txd.edx_confkeylen + txd.edx_authkeylen + + EMT_SETSPI_FLEN + ESP_NEW_XENCAP_LEN != em->em_msglen) { if (encdebug) log(LOG_WARNING, "esp_new_init(): message length (%d) doesn't match\n", em->em_msglen); return EINVAL; } - switch (txd.edx_enc_algorithm) + /* Check the IV length */ + if (((txd.edx_ivlen == 0) && !(txform->ivmask&1)) || + ((txd.edx_ivlen != 0) && ( + !(txd.edx_ivlen & txform->ivmask) || + (txd.edx_ivlen & (txd.edx_ivlen-1))))) { - case ALG_ENC_DES: - if ((txd.edx_ivlen != 0) && (txd.edx_ivlen != 8)) - { - if (encdebug) - log(LOG_WARNING, "esp_new_init(): unsupported IV length %d\n", - txd.edx_ivlen); - return EINVAL; - } - - if (txd.edx_keylen < 8) - { - if (encdebug) - log(LOG_WARNING, "esp_new_init(): bad key length\n", - txd.edx_keylen); - return EINVAL; - } - - enc_keylen = 8; - break; + if (encdebug) + log(LOG_WARNING, "esp_new_init(): unsupported IV length %d\n", + txd.edx_ivlen); + return EINVAL; + } - case ALG_ENC_3DES: - if ((txd.edx_ivlen != 0) && (txd.edx_ivlen != 8)) - { - if (encdebug) - log(LOG_WARNING, "esp_new_init(): unsupported IV length %d\n", - txd.edx_ivlen); - return EINVAL; - } - - if (txd.edx_keylen < 24) - { - if (encdebug) - log(LOG_WARNING, "esp_new_init(): bad key length\n", - txd.edx_keylen); - return EINVAL; - } - - enc_keylen = 24; - break; + /* Check the key length */ + if (txd.edx_confkeylen < txform->minkey || + txd.edx_confkeylen > txform->maxkey) + { + if (encdebug) + log(LOG_WARNING, "esp_new_init(): bad key length %d\n", + txd.edx_confkeylen); + return EINVAL; } MALLOC(tdbp->tdb_xdata, caddr_t, sizeof(struct esp_new_xdata), @@ -231,6 +334,10 @@ esp_new_init(struct tdb *tdbp, struct xformsw *xsp, struct mbuf *m) xd->edx_flags = txd.edx_flags; xd->edx_hash_algorithm = txd.edx_hash_algorithm; xd->edx_bitmap = 0; + xd->edx_xform = txform; + + /* Pass name of enc algorithm for kernfs */ + tdbp->tdb_confname = xd->edx_xform->name; /* Replay counters are mandatory, even without auth */ xd->edx_rpl = AH_HMAC_INITIAL_RPL; @@ -239,39 +346,43 @@ esp_new_init(struct tdb *tdbp, struct xformsw *xsp, struct mbuf *m) m_copydata(m, EMT_SETSPI_FLEN + ESP_NEW_XENCAP_LEN, xd->edx_ivlen, (caddr_t) xd->edx_iv); + /* Copy the key material */ + m_copydata(m, EMT_SETSPI_FLEN + ESP_NEW_XENCAP_LEN + xd->edx_ivlen, + txd.edx_confkeylen, (caddr_t) rk); switch (xd->edx_enc_algorithm) { case ALG_ENC_DES: - /* Copy the key material */ - m_copydata(m, EMT_SETSPI_FLEN + ESP_NEW_XENCAP_LEN + xd->edx_ivlen, - enc_keylen, (caddr_t) rk); - des_set_key((caddr_t) rk, (caddr_t) (xd->edx_eks[0])); break; case ALG_ENC_3DES: - /* Copy the key material */ - m_copydata(m, EMT_SETSPI_FLEN + ESP_NEW_XENCAP_LEN + xd->edx_ivlen, - enc_keylen, (caddr_t) rk); - des_set_key((caddr_t) rk, (caddr_t) (xd->edx_eks[0])); des_set_key((caddr_t) (rk + 2), (caddr_t) (xd->edx_eks[1])); des_set_key((caddr_t) (rk + 4), (caddr_t) (xd->edx_eks[2])); break; + case ALG_ENC_BLF: + blf_key(&xd->edx_bks, (caddr_t) rk, txd.edx_confkeylen); + break; + case ALG_ENC_CAST: + cast_setkey(&xd->edx_cks, (caddr_t) rk, txd.edx_confkeylen); + break; } if (txd.edx_flags & ESP_NEW_FLAG_AUTH) { - auth_keylen = txd.edx_keylen - enc_keylen; + xd->edx_hash = thash; + + /* Pass name of auth algorithm for kernfs */ + tdbp->tdb_authname = xd->edx_hash->name; #ifdef ENCDEBUG if (encdebug) printf("esp_new_init(): using %d bytes of authentication key\n", - auth_keylen); + txd.edx_authkeylen); #endif MALLOC(buffer, caddr_t, - auth_keylen < blocklen ? blocklen : auth_keylen, + txd.edx_authkeylen < blocklen ? blocklen : txd.edx_authkeylen, M_TEMP, M_WAITOK); if (buffer == NULL) { @@ -283,73 +394,41 @@ esp_new_init(struct tdb *tdbp, struct xformsw *xsp, struct mbuf *m) return ENOBUFS; } - bzero(buffer, auth_keylen < blocklen ? blocklen : auth_keylen); + bzero(buffer, txd.edx_authkeylen < blocklen ? + blocklen : txd.edx_authkeylen); /* Copy the key to the buffer */ m_copydata(m, EMT_SETSPI_FLEN + ESP_NEW_XENCAP_LEN + xd->edx_ivlen + - enc_keylen, auth_keylen, buffer); + txd.edx_confkeylen, txd.edx_authkeylen, buffer); /* Shorten the key if necessary */ - if (auth_keylen > blocklen) + if (txd.edx_authkeylen > blocklen) { - switch (xd->edx_hash_algorithm) - { - case ALG_AUTH_MD5: - MD5Init(&(xd->edx_md5_ictx)); - MD5Update(&(xd->edx_md5_ictx), buffer, auth_keylen); - bzero(buffer, - auth_keylen < blocklen ? blocklen : auth_keylen); - MD5Final(buffer, &(xd->edx_md5_ictx)); - break; - - case ALG_AUTH_SHA1: - SHA1Init(&(xd->edx_sha1_ictx)); - SHA1Update(&(xd->edx_sha1_ictx), buffer, auth_keylen); - bzero(buffer, - auth_keylen < blocklen ? blocklen : auth_keylen); - SHA1Final(buffer, &(xd->edx_sha1_ictx)); - break; - } + xd->edx_hash->Init(&(xd->edx_ictx)); + xd->edx_hash->Update(&(xd->edx_ictx), buffer, txd.edx_authkeylen); + bzero(buffer, txd.edx_authkeylen < blocklen ? + blocklen : txd.edx_authkeylen); + xd->edx_hash->Final(buffer, &(xd->edx_ictx)); } /* Precompute the I and O pads of the HMAC */ for (i = 0; i < blocklen; i++) buffer[i] ^= HMAC_IPAD_VAL; - switch (xd->edx_hash_algorithm) - { - case ALG_AUTH_MD5: - MD5Init(&(xd->edx_md5_ictx)); - MD5Update(&(xd->edx_md5_ictx), buffer, blocklen); - break; - - case ALG_AUTH_SHA1: - SHA1Init(&(xd->edx_sha1_ictx)); - SHA1Update(&(xd->edx_sha1_ictx), buffer, blocklen); - break; - } + xd->edx_hash->Init(&(xd->edx_ictx)); + xd->edx_hash->Update(&(xd->edx_ictx), buffer, blocklen); for (i = 0; i < blocklen; i++) buffer[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL); - switch (xd->edx_hash_algorithm) - { - case ALG_AUTH_MD5: - MD5Init(&(xd->edx_md5_octx)); - MD5Update(&(xd->edx_md5_octx), buffer, blocklen); - break; - - case ALG_AUTH_SHA1: - SHA1Init(&(xd->edx_sha1_octx)); - SHA1Update(&(xd->edx_sha1_octx), buffer, blocklen); - break; - } + xd->edx_hash->Init(&(xd->edx_octx)); + xd->edx_hash->Update(&(xd->edx_octx), buffer, blocklen); bzero(buffer, blocklen); free(buffer, M_TEMP); } - bzero(rk, 6 * sizeof(u_int32_t)); /* paranoid */ + bzero(rk, 14 * sizeof(u_int32_t)); /* paranoid */ bzero(ipseczeroes, IPSEC_ZEROES_SIZE); /* paranoid */ return 0; @@ -372,7 +451,7 @@ esp_new_input(struct mbuf *m, struct tdb *tdb) { struct esp_new_xdata *xd; struct ip *ip, ipo; - u_char iv[ESP_3DES_IVS], niv[ESP_3DES_IVS], blk[ESP_3DES_BLKS], opts[40]; + u_char iv[ESP_MAX_IVS], niv[ESP_MAX_IVS], blk[ESP_MAX_BLKS], opts[40]; u_char *idat, *odat; struct esp_new *esp; struct ifnet *rcvif; @@ -380,47 +459,18 @@ esp_new_input(struct mbuf *m, struct tdb *tdb) int count, off, errc; u_int32_t btsx; struct mbuf *mi, *mo; - MD5_CTX md5ctx; - SHA1_CTX sha1ctx; + union { + MD5_CTX md5ctx; + SHA1_CTX sha1ctx; + } ctx; u_char buf[AH_ALEN_MAX], buf2[AH_ALEN_MAX]; xd = (struct esp_new_xdata *)tdb->tdb_xdata; - switch (xd->edx_enc_algorithm) - { - case ALG_ENC_DES: - blks = ESP_DES_BLKS; - break; - - case ALG_ENC_3DES: - blks = ESP_3DES_BLKS; - break; - - default: - if (encdebug) - log(LOG_ALERT, - "esp_new_input(): unsupported algorithm %d in SA %x/%08x\n", - xd->edx_enc_algorithm, tdb->tdb_dst, ntohl(tdb->tdb_spi)); - m_freem(m); - return NULL; - } + blks = xd->edx_xform->blocksize; if (xd->edx_flags & ESP_NEW_FLAG_AUTH) - { - switch (xd->edx_hash_algorithm) - { - case ALG_AUTH_MD5: - case ALG_AUTH_SHA1: - alen = AH_HMAC_HASHLEN; - break; - - default: - if (encdebug) - log(LOG_ALERT, "esp_new_input(): unsupported algorithm %d in SA %x/%08x\n", xd->edx_hash_algorithm, tdb->tdb_dst, ntohl(tdb->tdb_spi)); - m_freem(m); - return NULL; - } - } + alen = AH_HMAC_HASHLEN; else alen = 0; @@ -514,16 +564,7 @@ esp_new_input(struct mbuf *m, struct tdb *tdb) if (xd->edx_flags & ESP_NEW_FLAG_AUTH) { - switch (xd->edx_hash_algorithm) - { - case ALG_AUTH_MD5: - md5ctx = xd->edx_md5_ictx; - break; - - case ALG_AUTH_SHA1: - sha1ctx = xd->edx_sha1_ictx; - break; - } + bcopy(&(xd->edx_ictx), &ctx, xd->edx_hash->ctxsize); /* Auth covers SPI + SN + IV*/ oplen = plen + 2 * sizeof(u_int32_t) + xd->edx_ivlen; @@ -537,19 +578,7 @@ esp_new_input(struct mbuf *m, struct tdb *tdb) count = min(mo->m_len - off, oplen); - switch (xd->edx_hash_algorithm) - { - case ALG_AUTH_MD5: - MD5Update(&md5ctx, mtod(mo, unsigned char *) + off, - count); - break; - - case ALG_AUTH_SHA1: - SHA1Update(&sha1ctx, mtod(mo, unsigned char *) + off, - count); - break; - } - + xd->edx_hash->Update(&ctx, mtod(mo, unsigned char *) + off, count); oplen -= count; if (oplen == 0) { @@ -581,22 +610,10 @@ esp_new_input(struct mbuf *m, struct tdb *tdb) mo = mo->m_next; } - switch (xd->edx_hash_algorithm) - { - case ALG_AUTH_MD5: - MD5Final(buf2, &md5ctx); - md5ctx = xd->edx_md5_octx; - MD5Update(&md5ctx, buf2, AH_MD5_ALEN); - MD5Final(buf2, &md5ctx); - break; - - case ALG_AUTH_SHA1: - SHA1Final(buf2, &sha1ctx); - sha1ctx = xd->edx_sha1_octx; - SHA1Update(&sha1ctx, buf2, AH_SHA1_ALEN); - SHA1Final(buf2, &sha1ctx); - break; - } + xd->edx_hash->Final(buf2, &ctx); + bcopy(&(xd->edx_octx), &ctx, xd->edx_hash->ctxsize); + xd->edx_hash->Update(&ctx, buf2, xd->edx_hash->hashsize); + xd->edx_hash->Final(buf2, &ctx); if (bcmp(buf2, buf, AH_HMAC_HASHLEN)) { @@ -668,18 +685,7 @@ esp_new_input(struct mbuf *m, struct tdb *tdb) if (i == blks) { - switch (xd->edx_enc_algorithm) - { - case ALG_ENC_DES: - des_ecb_encrypt(blk, blk, (caddr_t) (xd->edx_eks[0]), 0); - break; - - case ALG_ENC_3DES: - des_ecb3_encrypt(blk, blk, (caddr_t) (xd->edx_eks[2]), - (caddr_t) (xd->edx_eks[1]), - (caddr_t) (xd->edx_eks[0]), 0); - break; - } + xd->edx_xform->decrypt(xd, blk); for (i=0; i<8; i++) { @@ -841,51 +847,24 @@ esp_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct mbuf *mi, *mo; u_char *pad, *idat, *odat; u_char iv[ESP_3DES_IVS], blk[ESP_3DES_IVS], auth[AH_ALEN_MAX], opts[40]; - MD5_CTX md5ctx; - SHA1_CTX sha1ctx; + union { + MD5_CTX md5ctx; + SHA1_CTX sha1ctx; + } ctx; int iphlen, blks, alen; xd = (struct esp_new_xdata *) tdb->tdb_xdata; - switch (xd->edx_enc_algorithm) - { - case ALG_ENC_DES: - blks = ESP_DES_BLKS; - break; - - case ALG_ENC_3DES: - blks = ESP_3DES_BLKS; - break; - - default: - if (encdebug) - log(LOG_ALERT, - "esp_new_output(): unsupported algorithm %d in SA %x/%08x\n", - xd->edx_enc_algorithm, tdb->tdb_dst, ntohl(tdb->tdb_spi)); - m_freem(m); - return NULL; - } + blks = xd->edx_xform->blocksize; if (xd->edx_flags & ESP_NEW_FLAG_AUTH) { - switch (xd->edx_hash_algorithm) - { - case ALG_AUTH_MD5: - case ALG_AUTH_SHA1: - alen = AH_HMAC_HASHLEN; + alen = AH_HMAC_HASHLEN; #ifdef ENCDEBUG - if (encdebug) - printf("esp_new_output(): using hash algorithm %d\n", - xd->edx_hash_algorithm); + if (encdebug) + printf("esp_new_output(): using hash algorithm: %s\n", + xd->edx_hash->name); #endif /* ENCDEBUG */ - break; - - default: - if (encdebug) - log(LOG_ALERT, "esp_new_output(): unsupported algorithm %d in SA %x/%08x\n", xd->edx_hash_algorithm, tdb->tdb_dst, ntohl(tdb->tdb_spi)); - m_freem(m); - return NULL; - } } else alen = 0; @@ -997,20 +976,9 @@ esp_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, /* Authenticate the esp header */ if (xd->edx_flags & ESP_NEW_FLAG_AUTH) { - switch (xd->edx_hash_algorithm) - { - case ALG_AUTH_MD5: - md5ctx = xd->edx_md5_ictx; - MD5Update(&md5ctx, (unsigned char *) &espo, - 2 * sizeof(u_int32_t) + xd->edx_ivlen); - break; - - case ALG_AUTH_SHA1: - sha1ctx = xd->edx_sha1_ictx; - SHA1Update(&sha1ctx, (unsigned char *) &espo, - 2 * sizeof(u_int32_t) + xd->edx_ivlen); - break; - } + bcopy(&(xd->edx_ictx), &ctx, xd->edx_hash->ctxsize); + xd->edx_hash->Update(&ctx, (unsigned char *) &espo, + 2 * sizeof(u_int32_t) + xd->edx_ivlen); } /* Encrypt the payload */ @@ -1034,30 +1002,10 @@ esp_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, if (i == blks) { - switch (xd->edx_enc_algorithm) - { - case ALG_ENC_DES: - des_ecb_encrypt(blk, blk, (caddr_t) (xd->edx_eks[0]), 1); - break; - - case ALG_ENC_3DES: - des_ecb3_encrypt(blk, blk, (caddr_t) (xd->edx_eks[0]), - (caddr_t) (xd->edx_eks[1]), - (caddr_t) (xd->edx_eks[2]), 1); - break; - } + xd->edx_xform->encrypt(xd, blk); if (xd->edx_flags & ESP_NEW_FLAG_AUTH) - switch (xd->edx_hash_algorithm) - { - case ALG_AUTH_MD5: - MD5Update(&md5ctx, blk, blks); - break; - - case ALG_AUTH_SHA1: - SHA1Update(&sha1ctx, blk, blks); - break; - } + xd->edx_hash->Update(&ctx, blk, blks); for (i = 0; i < blks; i++) { @@ -1084,22 +1032,10 @@ esp_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, /* Put in authentication data */ if (xd->edx_flags & ESP_NEW_FLAG_AUTH) { - switch (xd->edx_hash_algorithm) - { - case ALG_AUTH_MD5: - MD5Final(auth, &md5ctx); - md5ctx = xd->edx_md5_octx; - MD5Update(&md5ctx, auth, AH_MD5_ALEN); - MD5Final(auth, &md5ctx); - break; - - case ALG_AUTH_SHA1: - SHA1Final(auth, &sha1ctx); - sha1ctx = xd->edx_sha1_octx; - SHA1Update(&sha1ctx, auth, AH_SHA1_ALEN); - SHA1Final(auth, &sha1ctx); - break; - } + xd->edx_hash->Final(auth, &ctx); + bcopy(&(xd->edx_octx), &ctx, xd->edx_hash->ctxsize); + xd->edx_hash->Update(&ctx, auth, xd->edx_hash->hashsize); + xd->edx_hash->Final(auth, &ctx); /* Copy the final authenticator */ bcopy(auth, pad + padding, alen); |