diff options
author | pjd <pjd@FreeBSD.org> | 2006-06-04 14:14:35 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2006-06-04 14:14:35 +0000 |
commit | e17ebb81203ba6d0b6e0ef55a2df5d44e99357be (patch) | |
tree | 26e7a283c94c7f2106eaf5c2b0223a81b8b904a2 /sys/dev/safe | |
parent | 51d59a64a2802d18bbee361cd17f0328ebef778a (diff) | |
download | FreeBSD-src-e17ebb81203ba6d0b6e0ef55a2df5d44e99357be.zip FreeBSD-src-e17ebb81203ba6d0b6e0ef55a2df5d44e99357be.tar.gz |
Add support for the CRD_F_KEY_EXPLICIT flag for both encryption and
authentication operations.
Unfortunately I've no hardware, so I only compiled-tested it.
Diffstat (limited to 'sys/dev/safe')
-rw-r--r-- | sys/dev/safe/safe.c | 140 |
1 files changed, 75 insertions, 65 deletions
diff --git a/sys/dev/safe/safe.c b/sys/dev/safe/safe.c index 0c0b6ef..080955d 100644 --- a/sys/dev/safe/safe.c +++ b/sys/dev/safe/safe.c @@ -640,6 +640,68 @@ safe_feed(struct safe_softc *sc, struct safe_ringentry *re) WRITE_REG(sc, SAFE_HI_RD_DESCR, 0); } +#define N(a) (sizeof(a) / sizeof (a[0])) +static void +safe_setup_enckey(struct safe_session *ses, caddr_t key) +{ + int i; + + bcopy(key, ses->ses_key, ses->ses_klen / 8); + + /* PE is little-endian, insure proper byte order */ + for (i = 0; i < N(ses->ses_key); i++) + ses->ses_key[i] = htole32(ses->ses_key[i]); +} + +static void +safe_setup_mackey(struct safe_session *ses, int algo, caddr_t key, int klen) +{ + MD5_CTX md5ctx; + SHA1_CTX sha1ctx; + int i; + + + for (i = 0; i < klen; i++) + key[i] ^= HMAC_IPAD_VAL; + + if (algo == CRYPTO_MD5_HMAC) { + MD5Init(&md5ctx); + MD5Update(&md5ctx, key, klen); + MD5Update(&md5ctx, hmac_ipad_buffer, HMAC_BLOCK_LEN - klen); + bcopy(md5ctx.state, ses->ses_hminner, sizeof(md5ctx.state)); + } else { + SHA1Init(&sha1ctx); + SHA1Update(&sha1ctx, key, klen); + SHA1Update(&sha1ctx, hmac_ipad_buffer, HMAC_BLOCK_LEN - klen); + bcopy(sha1ctx.h.b32, ses->ses_hminner, sizeof(sha1ctx.h.b32)); + } + + for (i = 0; i < klen; i++) + key[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL); + + if (algo == CRYPTO_MD5_HMAC) { + MD5Init(&md5ctx); + MD5Update(&md5ctx, key, klen); + MD5Update(&md5ctx, hmac_opad_buffer, HMAC_BLOCK_LEN - klen); + bcopy(md5ctx.state, ses->ses_hmouter, sizeof(md5ctx.state)); + } else { + SHA1Init(&sha1ctx); + SHA1Update(&sha1ctx, key, klen); + SHA1Update(&sha1ctx, hmac_opad_buffer, HMAC_BLOCK_LEN - klen); + bcopy(sha1ctx.h.b32, ses->ses_hmouter, sizeof(sha1ctx.h.b32)); + } + + for (i = 0; i < klen; i++) + key[i] ^= HMAC_OPAD_VAL; + + /* PE is little-endian, insure proper byte order */ + for (i = 0; i < N(ses->ses_hminner); i++) { + ses->ses_hminner[i] = htole32(ses->ses_hminner[i]); + ses->ses_hmouter[i] = htole32(ses->ses_hmouter[i]); + } +} +#undef N + /* * Allocate a new 'session' and return an encoded session id. 'sidp' * contains our registration id, and should contain an encoded session @@ -648,13 +710,10 @@ safe_feed(struct safe_softc *sc, struct safe_ringentry *re) static int safe_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri) { -#define N(a) (sizeof(a) / sizeof (a[0])) struct cryptoini *c, *encini = NULL, *macini = NULL; struct safe_softc *sc = arg; struct safe_session *ses = NULL; - MD5_CTX md5ctx; - SHA1_CTX sha1ctx; - int i, sesn; + int sesn; if (sidp == NULL || cri == NULL || sc == NULL) return (EINVAL); @@ -738,11 +797,8 @@ safe_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri) read_random(ses->ses_iv, sizeof(ses->ses_iv)); ses->ses_klen = encini->cri_klen; - bcopy(encini->cri_key, ses->ses_key, ses->ses_klen / 8); - - /* PE is little-endian, insure proper byte order */ - for (i = 0; i < N(ses->ses_key); i++) - ses->ses_key[i] = htole32(ses->ses_key[i]); + if (encini->cri_key != NULL) + safe_setup_enckey(ses, encini->cri_key); } if (macini) { @@ -754,61 +810,14 @@ safe_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri) ses->ses_mlen = SHA1_RESULTLEN; } - for (i = 0; i < macini->cri_klen / 8; i++) - macini->cri_key[i] ^= HMAC_IPAD_VAL; - - if (macini->cri_alg == CRYPTO_MD5_HMAC) { - MD5Init(&md5ctx); - MD5Update(&md5ctx, macini->cri_key, - macini->cri_klen / 8); - MD5Update(&md5ctx, hmac_ipad_buffer, - HMAC_BLOCK_LEN - (macini->cri_klen / 8)); - bcopy(md5ctx.state, ses->ses_hminner, - sizeof(md5ctx.state)); - } else { - SHA1Init(&sha1ctx); - SHA1Update(&sha1ctx, macini->cri_key, - macini->cri_klen / 8); - SHA1Update(&sha1ctx, hmac_ipad_buffer, - HMAC_BLOCK_LEN - (macini->cri_klen / 8)); - bcopy(sha1ctx.h.b32, ses->ses_hminner, - sizeof(sha1ctx.h.b32)); - } - - for (i = 0; i < macini->cri_klen / 8; i++) - macini->cri_key[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL); - - if (macini->cri_alg == CRYPTO_MD5_HMAC) { - MD5Init(&md5ctx); - MD5Update(&md5ctx, macini->cri_key, - macini->cri_klen / 8); - MD5Update(&md5ctx, hmac_opad_buffer, - HMAC_BLOCK_LEN - (macini->cri_klen / 8)); - bcopy(md5ctx.state, ses->ses_hmouter, - sizeof(md5ctx.state)); - } else { - SHA1Init(&sha1ctx); - SHA1Update(&sha1ctx, macini->cri_key, + if (macini->cri_key != NULL) { + safe_setup_mackey(ses, macini->cri_alg, macini->cri_key, macini->cri_klen / 8); - SHA1Update(&sha1ctx, hmac_opad_buffer, - HMAC_BLOCK_LEN - (macini->cri_klen / 8)); - bcopy(sha1ctx.h.b32, ses->ses_hmouter, - sizeof(sha1ctx.h.b32)); - } - - for (i = 0; i < macini->cri_klen / 8; i++) - macini->cri_key[i] ^= HMAC_OPAD_VAL; - - /* PE is little-endian, insure proper byte order */ - for (i = 0; i < N(ses->ses_hminner); i++) { - ses->ses_hminner[i] = htole32(ses->ses_hminner[i]); - ses->ses_hmouter[i] = htole32(ses->ses_hmouter[i]); } } *sidp = SAFE_SID(device_get_unit(sc->sc_dev), sesn); return (0); -#undef N } /* @@ -911,13 +920,6 @@ safe_process(void *arg, struct cryptop *crp, int hint) } crd2 = crd1->crd_next; - if ((crd1->crd_flags & CRD_F_KEY_EXPLICIT) || - (crd2 != NULL && (crd2->crd_flags & CRD_F_KEY_EXPLICIT))) { - safestats.st_badflags++; - err = EINVAL; - goto errout; - } - cmd0 = SAFE_SA_CMD0_BASIC; /* basic group operation */ cmd1 = 0; if (crd2 == NULL) { @@ -969,6 +971,9 @@ safe_process(void *arg, struct cryptop *crp, int hint) } if (enccrd) { + if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT) + safe_setup_enckey(ses, enccrd->crd_key); + if (enccrd->crd_alg == CRYPTO_DES_CBC) { cmd0 |= SAFE_SA_CMD0_DES; cmd1 |= SAFE_SA_CMD1_CBC; @@ -1050,6 +1055,11 @@ safe_process(void *arg, struct cryptop *crp, int hint) } if (maccrd) { + if (maccrd->crd_flags & CRD_F_KEY_EXPLICIT) { + safe_setup_mackey(ses, maccrd->crd_alg, + maccrd->crd_key, maccrd->crd_klen / 8); + } + if (maccrd->crd_alg == CRYPTO_MD5_HMAC) { cmd0 |= SAFE_SA_CMD0_MD5; cmd1 |= SAFE_SA_CMD1_HMAC; /* NB: enable HMAC */ |