X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fptlrpc%2Fgss%2Fgss_crypto.c;h=a07fac77ef8efdff0daadf5cc0f7ec2d33f46a5b;hb=b45169276ce1ab09dae7a733859f89a6c92808e5;hp=17fd9cf3c00c17473e53e1833571ac9d11f36a37;hpb=d10200a80770f0029d1d665af954187b9ad883df;p=fs%2Flustre-release.git diff --git a/lustre/ptlrpc/gss/gss_crypto.c b/lustre/ptlrpc/gss/gss_crypto.c index 17fd9cf..a07fac7 100644 --- a/lustre/ptlrpc/gss/gss_crypto.c +++ b/lustre/ptlrpc/gss/gss_crypto.c @@ -48,19 +48,18 @@ #define DEBUG_SUBSYSTEM S_SEC -#include #include #include #include "gss_internal.h" #include "gss_crypto.h" -int gss_keyblock_init(struct gss_keyblock *kb, char *alg_name, +int gss_keyblock_init(struct gss_keyblock *kb, const char *alg_name, const int alg_mode) { int rc; - kb->kb_tfm = crypto_alloc_blkcipher(alg_name, alg_mode, 0); + kb->kb_tfm = crypto_alloc_sync_skcipher(alg_name, alg_mode, 0); if (IS_ERR(kb->kb_tfm)) { rc = PTR_ERR(kb->kb_tfm); kb->kb_tfm = NULL; @@ -69,8 +68,8 @@ int gss_keyblock_init(struct gss_keyblock *kb, char *alg_name, return rc; } - rc = crypto_blkcipher_setkey(kb->kb_tfm, kb->kb_key.data, - kb->kb_key.len); + rc = crypto_sync_skcipher_setkey(kb->kb_tfm, kb->kb_key.data, + kb->kb_key.len); if (rc) { CERROR("failed to set %s key, len %d, rc = %d\n", alg_name, kb->kb_key.len, rc); @@ -84,7 +83,7 @@ void gss_keyblock_free(struct gss_keyblock *kb) { rawobj_free(&kb->kb_key); if (kb->kb_tfm) - crypto_free_blkcipher(kb->kb_tfm); + crypto_free_sync_skcipher(kb->kb_tfm); } int gss_keyblock_dup(struct gss_keyblock *new, struct gss_keyblock *kb) @@ -226,180 +225,158 @@ void gss_teardown_sgtable(struct sg_table *sgt) sg_free_table(sgt); } -int gss_crypt_generic(struct crypto_blkcipher *tfm, int decrypt, const void *iv, - const void *in, void *out, size_t length) +int gss_crypt_generic(struct crypto_sync_skcipher *tfm, int decrypt, + const void *iv, const void *in, void *out, size_t length) { - struct blkcipher_desc desc; struct scatterlist sg; struct sg_table sg_out; __u8 local_iv[16] = {0}; __u32 ret = -EINVAL; + SYNC_SKCIPHER_REQUEST_ON_STACK(req, tfm); LASSERT(tfm); - desc.tfm = tfm; - desc.info = local_iv; - desc.flags = 0; - if (length % crypto_blkcipher_blocksize(tfm) != 0) { + if (length % crypto_sync_skcipher_blocksize(tfm) != 0) { CERROR("output length %zu mismatch blocksize %d\n", - length, crypto_blkcipher_blocksize(tfm)); + length, crypto_sync_skcipher_blocksize(tfm)); goto out; } - if (crypto_blkcipher_ivsize(tfm) > ARRAY_SIZE(local_iv)) { - CERROR("iv size too large %d\n", crypto_blkcipher_ivsize(tfm)); + if (crypto_sync_skcipher_ivsize(tfm) > ARRAY_SIZE(local_iv)) { + CERROR("iv size too large %d\n", + crypto_sync_skcipher_ivsize(tfm)); goto out; } if (iv) - memcpy(local_iv, iv, crypto_blkcipher_ivsize(tfm)); + memcpy(local_iv, iv, crypto_sync_skcipher_ivsize(tfm)); - memcpy(out, in, length); + if (in != out) + memmove(out, in, length); ret = gss_setup_sgtable(&sg_out, &sg, out, length); if (ret != 0) goto out; + skcipher_request_set_sync_tfm(req, tfm); + skcipher_request_set_callback(req, 0, NULL, NULL); + skcipher_request_set_crypt(req, &sg, &sg, length, local_iv); + if (decrypt) - ret = crypto_blkcipher_decrypt_iv(&desc, &sg, &sg, length); + ret = crypto_skcipher_decrypt_iv(req, &sg, &sg, length); else - ret = crypto_blkcipher_encrypt_iv(&desc, &sg, &sg, length); + ret = crypto_skcipher_encrypt_iv(req, &sg, &sg, length); + skcipher_request_zero(req); gss_teardown_sgtable(&sg_out); out: return ret; } -int gss_digest_hmac(struct crypto_hash *tfm, - rawobj_t *key, - rawobj_t *hdr, - int msgcnt, rawobj_t *msgs, - int iovcnt, lnet_kiov_t *iovs, - rawobj_t *cksum) +int gss_digest_hash(struct ahash_request *req, + rawobj_t *hdr, int msgcnt, rawobj_t *msgs, + int iovcnt, struct bio_vec *iovs) { - struct hash_desc desc = { - .tfm = tfm, - .flags = 0, - }; struct scatterlist sg[1]; struct sg_table sgt; + int rc = 0; int i; - int rc; - - rc = crypto_hash_setkey(tfm, key->data, key->len); - if (rc) - return rc; - - rc = crypto_hash_init(&desc); - if (rc) - return rc; for (i = 0; i < msgcnt; i++) { if (msgs[i].len == 0) continue; rc = gss_setup_sgtable(&sgt, sg, msgs[i].data, msgs[i].len); - if (rc != 0) - return rc; - rc = crypto_hash_update(&desc, sg, msgs[i].len); if (rc) return rc; + ahash_request_set_crypt(req, sg, NULL, msgs[i].len); + rc = crypto_ahash_update(req); gss_teardown_sgtable(&sgt); + if (rc) + return rc; } for (i = 0; i < iovcnt; i++) { - if (iovs[i].kiov_len == 0) + if (iovs[i].bv_len == 0) continue; sg_init_table(sg, 1); - sg_set_page(&sg[0], iovs[i].kiov_page, iovs[i].kiov_len, - iovs[i].kiov_offset); - rc = crypto_hash_update(&desc, sg, iovs[i].kiov_len); + sg_set_page(&sg[0], iovs[i].bv_page, iovs[i].bv_len, + iovs[i].bv_offset); + + ahash_request_set_crypt(req, sg, NULL, iovs[i].bv_len); + rc = crypto_ahash_update(req); if (rc) return rc; } if (hdr) { - rc = gss_setup_sgtable(&sgt, sg, hdr, sizeof(*hdr)); - if (rc != 0) - return rc; - rc = crypto_hash_update(&desc, sg, sizeof(hdr->len)); + rc = gss_setup_sgtable(&sgt, sg, hdr->data, hdr->len); if (rc) return rc; + ahash_request_set_crypt(req, sg, NULL, hdr->len); + rc = crypto_ahash_update(req); gss_teardown_sgtable(&sgt); + if (rc) + return rc; } - return crypto_hash_final(&desc, cksum->data); + return rc; } -int gss_digest_norm(struct crypto_hash *tfm, - struct gss_keyblock *kb, - rawobj_t *hdr, - int msgcnt, rawobj_t *msgs, - int iovcnt, lnet_kiov_t *iovs, - rawobj_t *cksum) +int gss_digest_hash_compat(struct ahash_request *req, + rawobj_t *hdr, int msgcnt, rawobj_t *msgs, + int iovcnt, struct bio_vec *iovs) { - struct hash_desc desc; struct scatterlist sg[1]; struct sg_table sgt; - int i; - int rc; - - LASSERT(kb->kb_tfm); - desc.tfm = tfm; - desc.flags = 0; - - rc = crypto_hash_init(&desc); - if (rc) - return rc; + int rc = 0; + int i; for (i = 0; i < msgcnt; i++) { if (msgs[i].len == 0) continue; rc = gss_setup_sgtable(&sgt, sg, msgs[i].data, msgs[i].len); - if (rc != 0) - return rc; - - rc = crypto_hash_update(&desc, sg, msgs[i].len); if (rc) return rc; + ahash_request_set_crypt(req, sg, NULL, msgs[i].len); + rc = crypto_ahash_update(req); gss_teardown_sgtable(&sgt); + if (rc) + return rc; } for (i = 0; i < iovcnt; i++) { - if (iovs[i].kiov_len == 0) + if (iovs[i].bv_len == 0) continue; sg_init_table(sg, 1); - sg_set_page(&sg[0], iovs[i].kiov_page, iovs[i].kiov_len, - iovs[i].kiov_offset); - rc = crypto_hash_update(&desc, sg, iovs[i].kiov_len); + sg_set_page(&sg[0], iovs[i].bv_page, iovs[i].bv_len, + iovs[i].bv_offset); + + ahash_request_set_crypt(req, sg, NULL, iovs[i].bv_len); + rc = crypto_ahash_update(req); if (rc) return rc; } if (hdr) { - rc = gss_setup_sgtable(&sgt, sg, hdr, sizeof(*hdr)); - if (rc != 0) - return rc; - - rc = crypto_hash_update(&desc, sg, sizeof(*hdr)); + rc = gss_setup_sgtable(&sgt, sg, &(hdr->len), sizeof(hdr->len)); if (rc) return rc; + ahash_request_set_crypt(req, sg, NULL, sizeof(hdr->len)); + rc = crypto_ahash_update(req); gss_teardown_sgtable(&sgt); + if (rc) + return rc; } - rc = crypto_hash_final(&desc, cksum->data); - if (rc) - return rc; - - return gss_crypt_generic(kb->kb_tfm, 0, NULL, cksum->data, - cksum->data, cksum->len); + return rc; } int gss_add_padding(rawobj_t *msg, int msg_buflen, int blocksize) @@ -422,11 +399,10 @@ int gss_add_padding(rawobj_t *msg, int msg_buflen, int blocksize) return 0; } -int gss_crypt_rawobjs(struct crypto_blkcipher *tfm, __u8 *iv, +int gss_crypt_rawobjs(struct crypto_sync_skcipher *tfm, __u8 *iv, int inobj_cnt, rawobj_t *inobjs, rawobj_t *outobj, int enc) { - struct blkcipher_desc desc; struct scatterlist src; struct scatterlist dst; struct sg_table sg_dst; @@ -434,12 +410,13 @@ int gss_crypt_rawobjs(struct crypto_blkcipher *tfm, __u8 *iv, __u8 *buf; __u32 datalen = 0; int i, rc; + SYNC_SKCIPHER_REQUEST_ON_STACK(req, tfm); + ENTRY; buf = outobj->data; - desc.tfm = tfm; - desc.info = iv; - desc.flags = 0; + skcipher_request_set_sync_tfm(req, tfm); + skcipher_request_set_callback(req, 0, NULL, NULL); for (i = 0; i < inobj_cnt; i++) { LASSERT(buf + inobjs[i].len <= outobj->data + outobj->len); @@ -456,35 +433,30 @@ int gss_crypt_rawobjs(struct crypto_blkcipher *tfm, __u8 *iv, RETURN(rc); } - if (iv) { - if (enc) - rc = crypto_blkcipher_encrypt_iv(&desc, &dst, - &src, - src.length); - else - rc = crypto_blkcipher_decrypt_iv(&desc, &dst, - &src, - src.length); - } else { - if (enc) - rc = crypto_blkcipher_encrypt(&desc, &dst, &src, - src.length); - else - rc = crypto_blkcipher_decrypt(&desc, &dst, &src, - src.length); - } + skcipher_request_set_crypt(req, &src, &dst, src.length, iv); + if (!iv) + skcipher_request_set_crypt_iv(req); + + if (enc) + rc = crypto_skcipher_encrypt_iv(req, &dst, &src, + src.length); + else + rc = crypto_skcipher_decrypt_iv(req, &dst, &src, + src.length); gss_teardown_sgtable(&sg_src); gss_teardown_sgtable(&sg_dst); if (rc) { CERROR("encrypt error %d\n", rc); + skcipher_request_zero(req); RETURN(rc); } datalen += inobjs[i].len; buf += inobjs[i].len; } + skcipher_request_zero(req); outobj->len = datalen; RETURN(0);