diff options
author | Marco Peereboom <marco@cvs.openbsd.org> | 2008-02-23 19:38:30 +0000 |
---|---|---|
committer | Marco Peereboom <marco@cvs.openbsd.org> | 2008-02-23 19:38:30 +0000 |
commit | 9dbf599b6abe9c62c5397abe0d544be027d6b3de (patch) | |
tree | 48289ef207694958cc0db27ac2f7606f7c90448f /sys/dev/softraid_crypto.c | |
parent | 085346809bae8bf8ceb3c498680d975d4f7b87dc (diff) |
Backout premature code.
Diffstat (limited to 'sys/dev/softraid_crypto.c')
-rw-r--r-- | sys/dev/softraid_crypto.c | 610 |
1 files changed, 5 insertions, 605 deletions
diff --git a/sys/dev/softraid_crypto.c b/sys/dev/softraid_crypto.c index 078c9df643d..c9438aa0f15 100644 --- a/sys/dev/softraid_crypto.c +++ b/sys/dev/softraid_crypto.c @@ -1,10 +1,5 @@ -/* $OpenBSD: softraid_crypto.c,v 1.16 2008/02/22 23:00:04 hshoexer Exp $ */ +/* $OpenBSD: softraid_crypto.c,v 1.17 2008/02/23 19:38:29 marco Exp $ */ /* - * Copyright (c) 2007 Ted Unangst <tedu@openbsd.org> - * Copyright (c) 2008 Marco Peereboom <marco@openbsd.org> - * Copyright (c) 2008 Chris Kuethe <ckuethe@openbsd.org> - * Copyright (c) 2008 Hans-Joerg Hoexer <hshoexer@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. @@ -41,8 +36,6 @@ #include <crypto/cryptodev.h> #include <crypto/cryptosoft.h> -#include <crypto/sha1.h> -#include <crypto/rijndael.h> #include <scsi/scsi_all.h> #include <scsi/scsiconf.h> @@ -51,194 +44,23 @@ #include <dev/softraidvar.h> #include <dev/rndvar.h> -struct cryptop * sr_crypto_getcryptop(struct sr_workunit *, int); -void *sr_crypto_putcryptop(struct cryptop *); int sr_crypto_decrypt_key(struct sr_discipline *); int sr_crypto_encrypt_key(struct sr_discipline *); -int sr_crypto_write(struct cryptop *); -int sr_crypto_rw2(struct sr_workunit *, struct cryptop *); -void sr_crypto_intr(struct buf *); -int sr_crypto_read(struct cryptop *); -void sr_crypto_finish_io(struct sr_workunit *); -void sr_crypto_prf(const u_int8_t *, int, const u_int8_t *, - int, u_int8_t *); -void sr_crypto_xor(const u_int8_t *, u_int8_t *, int); -void sr_crypto_prf_iterate(const u_int8_t *, int, const - u_int8_t *, int, int, int, u_int8_t *); -int sr_crypto_pbkdf2(const u_int8_t *, int, const - u_int8_t *, int, int, int, u_int8_t **); - -struct cryptop * -sr_crypto_getcryptop(struct sr_workunit *wu, int encrypt) -{ - struct scsi_xfer *xs = wu->swu_xs; - struct sr_discipline *sd = wu->swu_dis; - struct cryptop *crp; - struct cryptodesc *crd; - struct uio *uio; - int flags, i, n; - daddr64_t blk[2]; - rijndael_ctx ctx; - - DNPRINTF(SR_D_DIS, "%s: sr_crypto_getcryptop wu: %p encrypt: %d\n", - DEVNAME(sd->sd_sc), wu, encrypt); - - /* XXX eliminate all malloc here, make either pool or pre-alloc */ - uio = malloc(sizeof(*uio), M_DEVBUF, M_NOWAIT | M_ZERO); - uio->uio_iov = malloc(sizeof(*uio->uio_iov), M_DEVBUF, M_NOWAIT); - uio->uio_iovcnt = 1; - uio->uio_iov->iov_len = xs->datalen; - if (xs->flags & SCSI_DATA_OUT) { - uio->uio_iov->iov_base = malloc(xs->datalen, M_DEVBUF, - M_NOWAIT); - bcopy(xs->data, uio->uio_iov->iov_base, xs->datalen); - } else - uio->uio_iov->iov_base = xs->data; - - blk[0] = 0; - if (xs->cmdlen == 10) - blk[1] = _4btol(((struct scsi_rw_big *)xs->cmd)->addr); - else if (xs->cmdlen == 16) - blk[1] = _8btol(((struct scsi_rw_16 *)xs->cmd)->addr); - else if (xs->cmdlen == 6) - blk[1] = _3btol(((struct scsi_rw *)xs->cmd)->addr); - - n = xs->datalen >> DEV_BSHIFT; - flags = (encrypt ? CRD_F_ENCRYPT : 0) | - CRD_F_IV_PRESENT | CRD_F_IV_EXPLICIT; - - crp = crypto_getreq(n); - if (crp == NULL) - goto unwind; - - if (rijndael_set_key_enc_only(&ctx, - sd->mds.mdd_crypto.scr_key1[blk[1] % SR_CRYPTO_MAXKEYS], - SR_CRYPTO_KEYBITS) != 0) - goto unwind; - - crp->crp_sid = sd->mds.mdd_crypto.scr_sid; - crp->crp_ilen = xs->datalen; - crp->crp_alloctype = M_DEVBUF; - crp->crp_buf = uio; - for (i = 0, crd = crp->crp_desc; crd; i++, blk[1]++, crd = crd->crd_next) { - crd->crd_skip = i << DEV_BSHIFT; - crd->crd_len = DEV_BSIZE; - crd->crd_inject = 0; - crd->crd_flags = flags; - crd->crd_alg = CRYPTO_AES_CBC; - crd->crd_klen = SR_CRYPTO_KEYBITS; - crd->crd_rnd = SR_CRYPTO_ROUNDS; - crd->crd_key = - sd->mds.mdd_crypto.scr_key2[blk[1] % SR_CRYPTO_MAXKEYS]; - - rijndael_encrypt(&ctx, (u_char *)blk, crd->crd_iv); - } - bzero(&ctx, sizeof(ctx)); - - return (crp); -unwind: - if (wu->swu_xs->flags & SCSI_DATA_OUT) - free(uio->uio_iov->iov_base, M_DEVBUF); - free(uio->uio_iov, M_DEVBUF); - free(uio, M_DEVBUF); - return (NULL); -} - -void * -sr_crypto_putcryptop(struct cryptop *crp) -{ - struct uio *uio = crp->crp_buf; - struct sr_workunit *wu = crp->crp_opaque; - - DNPRINTF(SR_D_DIS, "%s: sr_crypto_putcryptop crp: %p\n", - DEVNAME(wu->swu_dis->sd_sc), crp); - - if (wu->swu_xs->flags & SCSI_DATA_OUT) - free(uio->uio_iov->iov_base, M_DEVBUF); - free(uio->uio_iov, M_DEVBUF); - free(uio, M_DEVBUF); - crypto_freereq(crp); - - return (wu); -} int sr_crypto_decrypt_key(struct sr_discipline *sd) { - rijndael_ctx ctx; - u_int8_t *dkkey, *pk1, *ck1, *pk2, *ck2; - int i, error = 0; - DNPRINTF(SR_D_DIS, "%s: sr_crypto_decrypt_key\n", DEVNAME(sd->sd_sc)); - /* derive key from passphrase */ - if ((error = sr_crypto_pbkdf2(sd->mds.mdd_crypto.scr_meta[1].scm_passphrase, - strlen(sd->mds.mdd_crypto.scr_meta[1].scm_passphrase), - sd->mds.mdd_crypto.scr_meta[0].scm_salt, - sizeof(sd->mds.mdd_crypto.scr_meta[0].scm_salt), - SR_CRYPTO_PBKDF2_ROUNDS, SR_CRYPTO_KEYBYTES, &dkkey)) != 0) - goto out; - - if ((error = rijndael_set_key(&ctx, dkkey, SR_CRYPTO_KEYBITS)) != 0) - goto out; - - /* recover key */ - for (i = 0; i < SR_CRYPTO_MAXKEYS; i++) { - pk1 = sd->mds.mdd_crypto.scr_key1[i]; - pk2 = sd->mds.mdd_crypto.scr_key2[i]; - ck1 = sd->mds.mdd_crypto.scr_meta[0].scm_key1[i]; - ck2 = sd->mds.mdd_crypto.scr_meta[0].scm_key2[i]; - - /* note: with aes-128 blocksize == keysize */ - rijndael_decrypt(&ctx, (u_char *)ck1, (u_char *)pk1); - rijndael_decrypt(&ctx, (u_char *)ck2, (u_char *)pk2); - } -out: - bzero(&ctx, sizeof(ctx)); - bzero(dkkey, SR_CRYPTO_KEYBYTES); - free(dkkey, M_DEVBUF); - - return (error); + return (1); } int sr_crypto_encrypt_key(struct sr_discipline *sd) { - rijndael_ctx ctx; - u_int8_t *dkkey, *pk1, *pk2, *ck1, *ck2; - int i, error = 0; - DNPRINTF(SR_D_DIS, "%s: sr_crypto_encrypt_key\n", DEVNAME(sd->sd_sc)); - /* derive key from passphrase */ - if ((error = sr_crypto_pbkdf2(sd->mds.mdd_crypto.scr_meta[1].scm_passphrase, - strlen(sd->mds.mdd_crypto.scr_meta[1].scm_passphrase), - sd->mds.mdd_crypto.scr_meta[0].scm_salt, - sizeof(sd->mds.mdd_crypto.scr_meta[0].scm_salt), - SR_CRYPTO_PBKDF2_ROUNDS, SR_CRYPTO_KEYBYTES, &dkkey)) != 0) - goto out; - - if ((error = rijndael_set_key_enc_only(&ctx, dkkey, - SR_CRYPTO_KEYBITS)) != 0) - goto out; - - /* encrypt keys */ - for (i = 0; i < SR_CRYPTO_MAXKEYS; i++) { - pk1 = sd->mds.mdd_crypto.scr_key1[i]; - pk2 = sd->mds.mdd_crypto.scr_key2[i]; - ck1 = sd->mds.mdd_crypto.scr_meta[0].scm_key1[i]; - ck2 = sd->mds.mdd_crypto.scr_meta[0].scm_key2[i]; - - /* note: with aes-128 blocksize == keysize */ - rijndael_encrypt(&ctx, (u_char *)pk1, (u_char *)ck1); - rijndael_encrypt(&ctx, (u_char *)pk2, (u_char *)ck2); - } -out: - bzero(&ctx, sizeof(ctx)); - bzero(dkkey, SR_CRYPTO_KEYBYTES); - free(dkkey, M_DEVBUF); - - return (error); + return (1); } void @@ -280,448 +102,26 @@ sr_crypto_create_keys(struct sr_discipline *sd) int sr_crypto_alloc_resources(struct sr_discipline *sd) { - struct cryptoini cri; - - if (!sd) - return (EINVAL); - DNPRINTF(SR_D_DIS, "%s: sr_crypto_alloc_resources\n", DEVNAME(sd->sd_sc)); - if (sr_alloc_wu(sd)) - return (ENOMEM); - if (sr_alloc_ccb(sd)) - return (ENOMEM); - - if (sr_crypto_decrypt_key(sd)) { - return (1); - } - - bzero(&cri, sizeof(cri)); - cri.cri_alg = CRYPTO_AES_CBC; - cri.cri_klen = SR_CRYPTO_KEYBITS; - cri.cri_rnd = SR_CRYPTO_ROUNDS; - cri.cri_key = sd->mds.mdd_crypto.scr_key2[0]; - - /* - * XXX maybe we need to revisit the fact that we are only using one - * session even though we have 64 keys. - */ - return (crypto_newsession(&sd->mds.mdd_crypto.scr_sid, &cri, 0)); + return (EINVAL); } int sr_crypto_free_resources(struct sr_discipline *sd) { - int rv = EINVAL; - - if (!sd) - return (rv); - DNPRINTF(SR_D_DIS, "%s: sr_crypto_free_resources\n", DEVNAME(sd->sd_sc)); - sr_free_wu(sd); - sr_free_ccb(sd); - - if (sd->sd_meta) { - bzero(sd->mds.mdd_crypto.scr_key1, - sizeof(sd->mds.mdd_crypto.scr_key1)); - bzero(sd->mds.mdd_crypto.scr_key2, - sizeof(sd->mds.mdd_crypto.scr_key2)); - free(sd->sd_meta, M_DEVBUF); - } - - rv = 0; - return (rv); + return (EINVAL); } int sr_crypto_rw(struct sr_workunit *wu) { - struct cryptop *crp; - int s, rv = 0; - DNPRINTF(SR_D_DIS, "%s: sr_crypto_rw wu: %p\n", DEVNAME(wu->swu_dis->sd_sc), wu); - if (wu->swu_xs->flags & SCSI_DATA_OUT) { - crp = sr_crypto_getcryptop(wu, 1); - crp->crp_callback = sr_crypto_write; - crp->crp_opaque = wu; - s = splvm(); - if (crypto_invoke(crp)) - rv = 1; - splx(s); - } else - rv = sr_crypto_rw2(wu, NULL); - - return (rv); -} - -int -sr_crypto_write(struct cryptop *crp) -{ - int s; -#ifdef SR_DEBUG - struct sr_workunit *wu = crp->crp_opaque; -#endif /* SR_DEBUG */ - - DNPRINTF(SR_D_INTR, "%s: sr_crypto_write: wu %x xs: %x\n", - DEVNAME(wu->swu_dis->sd_sc), wu, wu->swu_xs); - - if (crp->crp_etype) { - /* fail io */ - ((struct sr_workunit *)(crp->crp_opaque))->swu_xs->error = - XS_DRIVER_STUFFUP; - s = splbio(); - sr_crypto_finish_io(crp->crp_opaque); - splx(s); - } - - return (sr_crypto_rw2(crp->crp_opaque, crp)); -} - -int -sr_crypto_rw2(struct sr_workunit *wu, struct cryptop *crp) -{ - struct sr_discipline *sd = wu->swu_dis; - struct scsi_xfer *xs = wu->swu_xs; - struct sr_ccb *ccb; - struct uio *uio; - int s; - daddr64_t blk; - - /* blk and scsi error will be handled by sr_validate_io */ - if (sr_validate_io(wu, &blk, "sr_crypto_rw2")) - goto bad; - - /* calculate physical block */ - blk += SR_META_SIZE + SR_META_OFFSET; - - wu->swu_io_count = 1; - - ccb = sr_get_ccb(sd); - if (!ccb) { - /* should never happen but handle more gracefully */ - printf("%s: %s: too many ccbs queued\n", - DEVNAME(sd->sd_sc), - sd->sd_vol.sv_meta.svm_devname); - goto bad; - } - - ccb->ccb_buf.b_flags = B_CALL; - ccb->ccb_buf.b_iodone = sr_crypto_intr; - ccb->ccb_buf.b_blkno = blk; - ccb->ccb_buf.b_bcount = xs->datalen; - ccb->ccb_buf.b_bufsize = xs->datalen; - ccb->ccb_buf.b_resid = xs->datalen; - - if (xs->flags & SCSI_DATA_IN) { - ccb->ccb_buf.b_flags |= B_READ; - ccb->ccb_buf.b_data = xs->data; - } else { - uio = crp->crp_buf; - ccb->ccb_buf.b_flags |= B_WRITE; - ccb->ccb_buf.b_data = uio->uio_iov->iov_base; - ccb->ccb_opaque = crp; - } - - ccb->ccb_buf.b_error = 0; - ccb->ccb_buf.b_proc = curproc; - ccb->ccb_wu = wu; - ccb->ccb_target = 0; - ccb->ccb_buf.b_dev = sd->sd_vol.sv_chunks[0]->src_dev_mm; - ccb->ccb_buf.b_vp = NULL; - - LIST_INIT(&ccb->ccb_buf.b_dep); - - TAILQ_INSERT_TAIL(&wu->swu_ccb, ccb, ccb_link); - - DNPRINTF(SR_D_DIS, "%s: %s: sr_crypto_rw2: b_bcount: %d " - "b_blkno: %x b_flags 0x%0x b_data %p\n", - DEVNAME(sd->sd_sc), sd->sd_vol.sv_meta.svm_devname, - ccb->ccb_buf.b_bcount, ccb->ccb_buf.b_blkno, - ccb->ccb_buf.b_flags, ccb->ccb_buf.b_data); - - - s = splbio(); - - if (sr_check_io_collision(wu)) - goto queued; - - sr_raid_startwu(wu); - -queued: - splx(s); - return (0); -bad: - /* wu is unwound by sr_put_wu */ return (1); } - -void -sr_crypto_intr(struct buf *bp) -{ - struct sr_ccb *ccb = (struct sr_ccb *)bp; - struct sr_workunit *wu = ccb->ccb_wu, *wup; - struct sr_discipline *sd = wu->swu_dis; - struct scsi_xfer *xs = wu->swu_xs; - struct sr_softc *sc = sd->sd_sc; - struct cryptop *crp; - int s, s2, pend; - - DNPRINTF(SR_D_INTR, "%s: sr_crypto_intr bp: %x xs: %x\n", - DEVNAME(sc), bp, wu->swu_xs); - - DNPRINTF(SR_D_INTR, "%s: sr_crypto_intr: b_bcount: %d b_resid: %d" - " b_flags: 0x%0x\n", DEVNAME(sc), ccb->ccb_buf.b_bcount, - ccb->ccb_buf.b_resid, ccb->ccb_buf.b_flags); - - s = splbio(); - - if (ccb->ccb_buf.b_flags & B_ERROR) { - printf("%s: i/o error on block %lld\n", DEVNAME(sc), - ccb->ccb_buf.b_blkno); - wu->swu_ios_failed++; - ccb->ccb_state = SR_CCB_FAILED; - if (ccb->ccb_target != -1) - sd->sd_set_chunk_state(sd, ccb->ccb_target, - BIOC_SDOFFLINE); - else - panic("%s: invalid target on wu: %p", DEVNAME(sc), wu); - } else { - ccb->ccb_state = SR_CCB_OK; - wu->swu_ios_succeeded++; - } - wu->swu_ios_complete++; - - DNPRINTF(SR_D_INTR, "%s: sr_crypto_intr: comp: %d count: %d\n", - DEVNAME(sc), wu->swu_ios_complete, wu->swu_io_count); - - if (wu->swu_ios_complete == wu->swu_io_count) { - if (wu->swu_ios_failed == wu->swu_ios_complete) - xs->error = XS_DRIVER_STUFFUP; - else - xs->error = XS_NOERROR; - - pend = 0; - TAILQ_FOREACH(wup, &sd->sd_wu_pendq, swu_link) { - if (wu == wup) { - /* wu on pendq, remove */ - TAILQ_REMOVE(&sd->sd_wu_pendq, wu, swu_link); - pend = 1; - - if (wu->swu_collider) { - /* restart deferred wu */ - wu->swu_collider->swu_state = - SR_WU_INPROGRESS; - TAILQ_REMOVE(&sd->sd_wu_defq, - wu->swu_collider, swu_link); - sr_raid_startwu(wu->swu_collider); - } - break; - } - } - - if (!pend) - printf("%s: wu: %p not on pending queue\n", - DEVNAME(sc), wu); - - /* do this after restarting other wus to shorten latency */ - if ((xs->flags & SCSI_DATA_IN) && (xs->error == XS_NOERROR)) { - crp = sr_crypto_getcryptop(wu, 0); - ccb->ccb_opaque = crp; - crp->crp_callback = sr_crypto_read; - crp->crp_opaque = wu; - DNPRINTF(SR_D_INTR, "%s: sr_crypto_intr: crypto_invoke " - "%p\n", DEVNAME(sc), crp); - s2 = splvm(); - crypto_invoke(crp); - splx(s2); - goto done; - } - - sr_crypto_finish_io(wu); - } - -done: - splx(s); -} - -void -sr_crypto_finish_io(struct sr_workunit *wu) -{ - struct sr_discipline *sd = wu->swu_dis; - struct scsi_xfer *xs = wu->swu_xs; - struct sr_ccb *ccb; -#ifdef SR_DEBUG - struct sr_softc *sc = sd->sd_sc; -#endif /* SR_DEBUG */ - splassert(IPL_BIO); - - DNPRINTF(SR_D_INTR, "%s: sr_crypto_finish_io: wu %x xs: %x\n", - DEVNAME(sc), wu, xs); - - xs->resid = 0; - xs->flags |= ITSDONE; - - TAILQ_FOREACH(ccb, &wu->swu_ccb, ccb_link) { - if (ccb->ccb_opaque == NULL) - continue; - sr_crypto_putcryptop(ccb->ccb_opaque); - } - - /* do not change the order of these 2 functions */ - sr_put_wu(wu); - scsi_done(xs); - - if (sd->sd_sync && sd->sd_wu_pending == 0) - wakeup(sd); -} - -int -sr_crypto_read(struct cryptop *crp) -{ - int s; - struct sr_workunit *wu = crp->crp_opaque; - - DNPRINTF(SR_D_INTR, "%s: sr_crypto_read: wu %x xs: %x\n", - DEVNAME(wu->swu_dis->sd_sc), wu, wu->swu_xs); - - if (crp->crp_etype) - wu->swu_xs->error = XS_DRIVER_STUFFUP; - - s = splbio(); - sr_crypto_finish_io(crp->crp_opaque); - splx(s); - - return (0); -} - -void -sr_crypto_prf(const u_int8_t *p, int plen, const u_int8_t *data, int datalen, - u_int8_t *output) -{ - SHA1_CTX ictx, octx; - u_int8_t tmp[SHA1_DIGEST_LENGTH]; - u_int8_t *buf; - int i; - - /* Calculate a 160bit HMAC using SHA1 */ - - buf = malloc(plen, M_DEVBUF, M_NOWAIT); - - /* apply ipad */ - for (i = 0; i < plen; i++) - buf[i] = p[i] ^ HMAC_IPAD_VAL; - - /* inner hash */ - SHA1Init(&ictx); - SHA1Update(&ictx, buf, plen); - SHA1Update(&ictx, hmac_ipad_buffer, HMAC_BLOCK_LEN - plen); - - /* apply inner hash on text */ - SHA1Update(&ictx, data, datalen); - SHA1Final(tmp, &ictx); - - /* apply opad, undo ipad */ - for (i = 0; i < plen; i++) - buf[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL); - - /* outer hash */ - SHA1Init(&octx); - SHA1Update(&octx, buf, plen); - SHA1Update(&octx, hmac_opad_buffer, HMAC_BLOCK_LEN - plen); - - bzero(buf, plen); - free(buf, M_DEVBUF); - - /* apply outer hash on result of inner hash */ - SHA1Update(&octx, tmp, sizeof(tmp)); - SHA1Final(output, &octx); - - bzero(tmp, sizeof(tmp)); -} - -void -sr_crypto_xor(const u_int8_t *src, u_int8_t *dst, int len) -{ - int i; - - for (i = 0; i < len; i++) - dst[i] ^= src[i]; -} - -void -sr_crypto_prf_iterate(const u_int8_t *p, int plen, const u_int8_t *s, int slen, - int c, int i, u_int8_t *dk) -{ - int j, len; - u_int8_t buffer[SHA1_DIGEST_LENGTH]; - u_int8_t *data; - - /* - * Concatenate salt with msb-encoded index i - */ - len = slen + sizeof(u_int32_t); - data = malloc(slen + sizeof(int), M_DEVBUF, M_NOWAIT); - bcopy(s, data, slen); - *(u_int32_t *)(data + slen) = htonl(i); - - /* - * Calculate U1..c. U1 is PRF(P, s||htonl(i)). All other are - * Ux = PRF(P, Ux-1). Return block T is U1 xor U2 xor ... Uc. - */ - for (j = 0; j < c; j++) { - sr_crypto_prf(p, plen, data, len, buffer); - - if (j == 0) { - bcopy(buffer, dk, SHA1_DIGEST_LENGTH); - bzero(data, sizeof(data)); - free(data, M_DEVBUF); - len = SHA1_DIGEST_LENGTH; - data = malloc(len, M_DEVBUF, M_NOWAIT); - } else - sr_crypto_xor(buffer, dk, SHA1_DIGEST_LENGTH); - bcopy(buffer, data, SHA1_DIGEST_LENGTH); - } - bzero(data, len); - bzero(buffer, sizeof(buffer)); - free(data, M_DEVBUF); -} - -int -sr_crypto_pbkdf2(const u_int8_t *p, int plen, const u_int8_t *s, int slen, - int c, int dklen, u_int8_t **dk) -{ - int l, i, rv = EINVAL; - - DNPRINTF(SR_D_DIS, "softraid0: sr_crypto_pbkdf2\n"); - - if (dklen > HMAC_BLOCK_LEN) { - DNPRINTF(SR_D_DIS, "softraid0: sr_crypto_pbkdf2: invalid " - "dklen\n"); - goto out; - } - - /* - * Get a large enough buffer for the key, ie. - * dklen <= l * SHA1_DIGEST_LENGTH < dklen + SHA1_DIGEST_LENGTH - * This adds some extra bytes to *dk, which will be zeroed out, - * see below. - */ - l = (dklen + SHA1_DIGEST_LENGTH - 1) / SHA1_DIGEST_LENGTH; - *dk = malloc(l * SHA1_DIGEST_LENGTH, M_DEVBUF, M_NOWAIT | M_ZERO); - - for (i = 0; i < l; i++) - sr_crypto_prf_iterate(p, plen, s, slen, c, i, *dk + - i * SHA1_DIGEST_LENGTH); - - /* Zero out the extra bytes */ - bzero(*dk + dklen, l * SHA1_DIGEST_LENGTH - dklen); - - rv = 0; -out: - return (rv); -} |