Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ksmbd: Use AES-CMAC library for SMB3 signature calculation

Now that AES-CMAC has a library API, convert ksmbd_sign_smb3_pdu() to
use it instead of a "cmac(aes)" crypto_shash.

The result is simpler and faster code. With the library there's no need
to dynamically allocate memory, no need to handle errors, and the
AES-CMAC code is accessed directly without inefficient indirect calls
and other unnecessary API overhead.

Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>

authored by

Eric Biggers and committed by
Steve French
cc92b479 def036ef

+19 -117
+1 -1
fs/smb/server/Kconfig
··· 7 7 select NLS_UTF8 8 8 select NLS_UCS2_UTILS 9 9 select CRYPTO 10 + select CRYPTO_LIB_AES_CBC_MACS 10 11 select CRYPTO_LIB_ARC4 11 12 select CRYPTO_LIB_DES 12 13 select CRYPTO_LIB_MD5 13 14 select CRYPTO_LIB_SHA256 14 15 select CRYPTO_LIB_SHA512 15 16 select CRYPTO_LIB_UTILS 16 - select CRYPTO_CMAC 17 17 select CRYPTO_AEAD2 18 18 select CRYPTO_CCM 19 19 select CRYPTO_GCM
+13 -38
fs/smb/server/auth.c
··· 11 11 #include <linux/writeback.h> 12 12 #include <linux/uio.h> 13 13 #include <linux/xattr.h> 14 - #include <crypto/hash.h> 15 14 #include <crypto/aead.h> 15 + #include <crypto/aes-cbc-macs.h> 16 16 #include <crypto/md5.h> 17 17 #include <crypto/sha2.h> 18 18 #include <crypto/utils.h> ··· 490 490 * @sig: signature value generated for client request packet 491 491 * 492 492 */ 493 - int ksmbd_sign_smb3_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov, 494 - int n_vec, char *sig) 493 + void ksmbd_sign_smb3_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov, 494 + int n_vec, char *sig) 495 495 { 496 - struct ksmbd_crypto_ctx *ctx; 497 - int rc, i; 496 + struct aes_cmac_key cmac_key; 497 + struct aes_cmac_ctx cmac_ctx; 498 + int i; 498 499 499 - ctx = ksmbd_crypto_ctx_find_cmacaes(); 500 - if (!ctx) { 501 - ksmbd_debug(AUTH, "could not crypto alloc cmac\n"); 502 - return -ENOMEM; 503 - } 500 + /* This cannot fail, since we always pass a valid key length. */ 501 + static_assert(SMB2_CMACAES_SIZE == AES_KEYSIZE_128); 502 + aes_cmac_preparekey(&cmac_key, key, SMB2_CMACAES_SIZE); 504 503 505 - rc = crypto_shash_setkey(CRYPTO_CMACAES_TFM(ctx), 506 - key, 507 - SMB2_CMACAES_SIZE); 508 - if (rc) 509 - goto out; 510 - 511 - rc = crypto_shash_init(CRYPTO_CMACAES(ctx)); 512 - if (rc) { 513 - ksmbd_debug(AUTH, "cmaces init error %d\n", rc); 514 - goto out; 515 - } 516 - 517 - for (i = 0; i < n_vec; i++) { 518 - rc = crypto_shash_update(CRYPTO_CMACAES(ctx), 519 - iov[i].iov_base, 520 - iov[i].iov_len); 521 - if (rc) { 522 - ksmbd_debug(AUTH, "cmaces update error %d\n", rc); 523 - goto out; 524 - } 525 - } 526 - 527 - rc = crypto_shash_final(CRYPTO_CMACAES(ctx), sig); 528 - if (rc) 529 - ksmbd_debug(AUTH, "cmaces generation error %d\n", rc); 530 - out: 531 - ksmbd_release_crypto_ctx(ctx); 532 - return rc; 504 + aes_cmac_init(&cmac_ctx, &cmac_key); 505 + for (i = 0; i < n_vec; i++) 506 + aes_cmac_update(&cmac_ctx, iov[i].iov_base, iov[i].iov_len); 507 + aes_cmac_final(&cmac_ctx, sig); 533 508 } 534 509 535 510 struct derivation {
+2 -2
fs/smb/server/auth.h
··· 54 54 int in_len, char *out_blob, int *out_len); 55 55 void ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov, 56 56 int n_vec, char *sig); 57 - int ksmbd_sign_smb3_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov, 58 - int n_vec, char *sig); 57 + void ksmbd_sign_smb3_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov, 58 + int n_vec, char *sig); 59 59 int ksmbd_gen_smb30_signingkey(struct ksmbd_session *sess, 60 60 struct ksmbd_conn *conn); 61 61 int ksmbd_gen_smb311_signingkey(struct ksmbd_session *sess,
-58
fs/smb/server/crypto_ctx.c
··· 28 28 crypto_free_aead(aead); 29 29 } 30 30 31 - static void free_shash(struct shash_desc *shash) 32 - { 33 - if (shash) { 34 - crypto_free_shash(shash->tfm); 35 - kfree(shash); 36 - } 37 - } 38 - 39 31 static struct crypto_aead *alloc_aead(int id) 40 32 { 41 33 struct crypto_aead *tfm = NULL; ··· 52 60 return tfm; 53 61 } 54 62 55 - static struct shash_desc *alloc_shash_desc(int id) 56 - { 57 - struct crypto_shash *tfm = NULL; 58 - struct shash_desc *shash; 59 - 60 - switch (id) { 61 - case CRYPTO_SHASH_CMACAES: 62 - tfm = crypto_alloc_shash("cmac(aes)", 0, 0); 63 - break; 64 - default: 65 - return NULL; 66 - } 67 - 68 - if (IS_ERR(tfm)) 69 - return NULL; 70 - 71 - shash = kzalloc(sizeof(*shash) + crypto_shash_descsize(tfm), 72 - KSMBD_DEFAULT_GFP); 73 - if (!shash) 74 - crypto_free_shash(tfm); 75 - else 76 - shash->tfm = tfm; 77 - return shash; 78 - } 79 - 80 63 static void ctx_free(struct ksmbd_crypto_ctx *ctx) 81 64 { 82 65 int i; 83 66 84 - for (i = 0; i < CRYPTO_SHASH_MAX; i++) 85 - free_shash(ctx->desc[i]); 86 67 for (i = 0; i < CRYPTO_AEAD_MAX; i++) 87 68 free_aead(ctx->ccmaes[i]); 88 69 kfree(ctx); ··· 116 151 ctx_list.avail_ctx--; 117 152 spin_unlock(&ctx_list.ctx_lock); 118 153 ctx_free(ctx); 119 - } 120 - 121 - static struct ksmbd_crypto_ctx *____crypto_shash_ctx_find(int id) 122 - { 123 - struct ksmbd_crypto_ctx *ctx; 124 - 125 - if (id >= CRYPTO_SHASH_MAX) 126 - return NULL; 127 - 128 - ctx = ksmbd_find_crypto_ctx(); 129 - if (ctx->desc[id]) 130 - return ctx; 131 - 132 - ctx->desc[id] = alloc_shash_desc(id); 133 - if (ctx->desc[id]) 134 - return ctx; 135 - ksmbd_release_crypto_ctx(ctx); 136 - return NULL; 137 - } 138 - 139 - struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_cmacaes(void) 140 - { 141 - return ____crypto_shash_ctx_find(CRYPTO_SHASH_CMACAES); 142 154 } 143 155 144 156 static struct ksmbd_crypto_ctx *____crypto_aead_ctx_find(int id)
-12
fs/smb/server/crypto_ctx.h
··· 6 6 #ifndef __CRYPTO_CTX_H__ 7 7 #define __CRYPTO_CTX_H__ 8 8 9 - #include <crypto/hash.h> 10 9 #include <crypto/aead.h> 11 - 12 - enum { 13 - CRYPTO_SHASH_CMACAES = 0, 14 - CRYPTO_SHASH_MAX, 15 - }; 16 10 17 11 enum { 18 12 CRYPTO_AEAD_AES_GCM = 16, ··· 17 23 struct ksmbd_crypto_ctx { 18 24 struct list_head list; 19 25 20 - struct shash_desc *desc[CRYPTO_SHASH_MAX]; 21 26 struct crypto_aead *ccmaes[CRYPTO_AEAD_MAX]; 22 27 }; 23 - 24 - #define CRYPTO_CMACAES(c) ((c)->desc[CRYPTO_SHASH_CMACAES]) 25 - 26 - #define CRYPTO_CMACAES_TFM(c) ((c)->desc[CRYPTO_SHASH_CMACAES]->tfm) 27 28 28 29 #define CRYPTO_GCM(c) ((c)->ccmaes[CRYPTO_AEAD_AES_GCM]) 29 30 #define CRYPTO_CCM(c) ((c)->ccmaes[CRYPTO_AEAD_AES_CCM]) 30 31 31 32 void ksmbd_release_crypto_ctx(struct ksmbd_crypto_ctx *ctx); 32 - struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_cmacaes(void); 33 33 struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_gcm(void); 34 34 struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_ccm(void); 35 35 void ksmbd_crypto_destroy(void);
-1
fs/smb/server/server.c
··· 631 631 MODULE_LICENSE("GPL"); 632 632 MODULE_SOFTDEP("pre: nls"); 633 633 MODULE_SOFTDEP("pre: aes"); 634 - MODULE_SOFTDEP("pre: cmac"); 635 634 MODULE_SOFTDEP("pre: aead2"); 636 635 MODULE_SOFTDEP("pre: ccm"); 637 636 MODULE_SOFTDEP("pre: gcm");
+3 -5
fs/smb/server/smb2pdu.c
··· 9066 9066 iov[0].iov_base = (char *)&hdr->ProtocolId; 9067 9067 iov[0].iov_len = len; 9068 9068 9069 - if (ksmbd_sign_smb3_pdu(conn, signing_key, iov, 1, signature)) 9070 - return 0; 9069 + ksmbd_sign_smb3_pdu(conn, signing_key, iov, 1, signature); 9071 9070 9072 9071 if (crypto_memneq(signature, signature_req, SMB2_SIGNATURE_SIZE)) { 9073 9072 pr_err("bad smb2 signature\n"); ··· 9117 9118 iov = &work->iov[work->iov_idx]; 9118 9119 } 9119 9120 9120 - if (!ksmbd_sign_smb3_pdu(conn, signing_key, iov, n_vec, 9121 - signature)) 9122 - memcpy(hdr->Signature, signature, SMB2_SIGNATURE_SIZE); 9121 + ksmbd_sign_smb3_pdu(conn, signing_key, iov, n_vec, signature); 9122 + memcpy(hdr->Signature, signature, SMB2_SIGNATURE_SIZE); 9123 9123 } 9124 9124 9125 9125 /**