Skip to content

Commit cc92b47

Browse files
Eric Biggerssmfrench
authored andcommitted
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 <[email protected]> Reviewed-by: Ard Biesheuvel <[email protected]> Signed-off-by: Eric Biggers <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent def036e commit cc92b47

7 files changed

Lines changed: 19 additions & 117 deletions

File tree

fs/smb/server/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ config SMB_SERVER
77
select NLS_UTF8
88
select NLS_UCS2_UTILS
99
select CRYPTO
10+
select CRYPTO_LIB_AES_CBC_MACS
1011
select CRYPTO_LIB_ARC4
1112
select CRYPTO_LIB_DES
1213
select CRYPTO_LIB_MD5
1314
select CRYPTO_LIB_SHA256
1415
select CRYPTO_LIB_SHA512
1516
select CRYPTO_LIB_UTILS
16-
select CRYPTO_CMAC
1717
select CRYPTO_AEAD2
1818
select CRYPTO_CCM
1919
select CRYPTO_GCM

fs/smb/server/auth.c

Lines changed: 13 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
#include <linux/writeback.h>
1212
#include <linux/uio.h>
1313
#include <linux/xattr.h>
14-
#include <crypto/hash.h>
1514
#include <crypto/aead.h>
15+
#include <crypto/aes-cbc-macs.h>
1616
#include <crypto/md5.h>
1717
#include <crypto/sha2.h>
1818
#include <crypto/utils.h>
@@ -490,46 +490,21 @@ void ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
490490
* @sig: signature value generated for client request packet
491491
*
492492
*/
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)
495495
{
496-
struct ksmbd_crypto_ctx *ctx;
497-
int rc, i;
498-
499-
ctx = ksmbd_crypto_ctx_find_cmacaes();
500-
if (!ctx) {
501-
ksmbd_debug(AUTH, "could not crypto alloc cmac\n");
502-
return -ENOMEM;
503-
}
504-
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-
}
496+
struct aes_cmac_key cmac_key;
497+
struct aes_cmac_ctx cmac_ctx;
498+
int i;
516499

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-
}
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);
526503

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);
533508
}
534509

535510
struct derivation {

fs/smb/server/auth.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
5454
int in_len, char *out_blob, int *out_len);
5555
void ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
5656
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);
5959
int ksmbd_gen_smb30_signingkey(struct ksmbd_session *sess,
6060
struct ksmbd_conn *conn);
6161
int ksmbd_gen_smb311_signingkey(struct ksmbd_session *sess,

fs/smb/server/crypto_ctx.c

Lines changed: 0 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,6 @@ static inline void free_aead(struct crypto_aead *aead)
2828
crypto_free_aead(aead);
2929
}
3030

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-
3931
static struct crypto_aead *alloc_aead(int id)
4032
{
4133
struct crypto_aead *tfm = NULL;
@@ -60,37 +52,10 @@ static struct crypto_aead *alloc_aead(int id)
6052
return tfm;
6153
}
6254

63-
static struct shash_desc *alloc_shash_desc(int id)
64-
{
65-
struct crypto_shash *tfm = NULL;
66-
struct shash_desc *shash;
67-
68-
switch (id) {
69-
case CRYPTO_SHASH_CMACAES:
70-
tfm = crypto_alloc_shash("cmac(aes)", 0, 0);
71-
break;
72-
default:
73-
return NULL;
74-
}
75-
76-
if (IS_ERR(tfm))
77-
return NULL;
78-
79-
shash = kzalloc(sizeof(*shash) + crypto_shash_descsize(tfm),
80-
KSMBD_DEFAULT_GFP);
81-
if (!shash)
82-
crypto_free_shash(tfm);
83-
else
84-
shash->tfm = tfm;
85-
return shash;
86-
}
87-
8855
static void ctx_free(struct ksmbd_crypto_ctx *ctx)
8956
{
9057
int i;
9158

92-
for (i = 0; i < CRYPTO_SHASH_MAX; i++)
93-
free_shash(ctx->desc[i]);
9459
for (i = 0; i < CRYPTO_AEAD_MAX; i++)
9560
free_aead(ctx->ccmaes[i]);
9661
kfree(ctx);
@@ -153,29 +118,6 @@ void ksmbd_release_crypto_ctx(struct ksmbd_crypto_ctx *ctx)
153118
ctx_free(ctx);
154119
}
155120

156-
static struct ksmbd_crypto_ctx *____crypto_shash_ctx_find(int id)
157-
{
158-
struct ksmbd_crypto_ctx *ctx;
159-
160-
if (id >= CRYPTO_SHASH_MAX)
161-
return NULL;
162-
163-
ctx = ksmbd_find_crypto_ctx();
164-
if (ctx->desc[id])
165-
return ctx;
166-
167-
ctx->desc[id] = alloc_shash_desc(id);
168-
if (ctx->desc[id])
169-
return ctx;
170-
ksmbd_release_crypto_ctx(ctx);
171-
return NULL;
172-
}
173-
174-
struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_cmacaes(void)
175-
{
176-
return ____crypto_shash_ctx_find(CRYPTO_SHASH_CMACAES);
177-
}
178-
179121
static struct ksmbd_crypto_ctx *____crypto_aead_ctx_find(int id)
180122
{
181123
struct ksmbd_crypto_ctx *ctx;

fs/smb/server/crypto_ctx.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,8 @@
66
#ifndef __CRYPTO_CTX_H__
77
#define __CRYPTO_CTX_H__
88

9-
#include <crypto/hash.h>
109
#include <crypto/aead.h>
1110

12-
enum {
13-
CRYPTO_SHASH_CMACAES = 0,
14-
CRYPTO_SHASH_MAX,
15-
};
16-
1711
enum {
1812
CRYPTO_AEAD_AES_GCM = 16,
1913
CRYPTO_AEAD_AES_CCM,
@@ -23,19 +17,13 @@ enum {
2317
struct ksmbd_crypto_ctx {
2418
struct list_head list;
2519

26-
struct shash_desc *desc[CRYPTO_SHASH_MAX];
2720
struct crypto_aead *ccmaes[CRYPTO_AEAD_MAX];
2821
};
2922

30-
#define CRYPTO_CMACAES(c) ((c)->desc[CRYPTO_SHASH_CMACAES])
31-
32-
#define CRYPTO_CMACAES_TFM(c) ((c)->desc[CRYPTO_SHASH_CMACAES]->tfm)
33-
3423
#define CRYPTO_GCM(c) ((c)->ccmaes[CRYPTO_AEAD_AES_GCM])
3524
#define CRYPTO_CCM(c) ((c)->ccmaes[CRYPTO_AEAD_AES_CCM])
3625

3726
void ksmbd_release_crypto_ctx(struct ksmbd_crypto_ctx *ctx);
38-
struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_cmacaes(void);
3927
struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_gcm(void);
4028
struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_ccm(void);
4129
void ksmbd_crypto_destroy(void);

fs/smb/server/server.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,6 @@ MODULE_DESCRIPTION("Linux kernel CIFS/SMB SERVER");
631631
MODULE_LICENSE("GPL");
632632
MODULE_SOFTDEP("pre: nls");
633633
MODULE_SOFTDEP("pre: aes");
634-
MODULE_SOFTDEP("pre: cmac");
635634
MODULE_SOFTDEP("pre: aead2");
636635
MODULE_SOFTDEP("pre: ccm");
637636
MODULE_SOFTDEP("pre: gcm");

fs/smb/server/smb2pdu.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9066,8 +9066,7 @@ int smb3_check_sign_req(struct ksmbd_work *work)
90669066
iov[0].iov_base = (char *)&hdr->ProtocolId;
90679067
iov[0].iov_len = len;
90689068

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);
90719070

90729071
if (crypto_memneq(signature, signature_req, SMB2_SIGNATURE_SIZE)) {
90739072
pr_err("bad smb2 signature\n");
@@ -9118,9 +9117,8 @@ void smb3_set_sign_rsp(struct ksmbd_work *work)
91189117
iov = &work->iov[work->iov_idx];
91199118
}
91209119

9121-
if (!ksmbd_sign_smb3_pdu(conn, signing_key, iov, n_vec,
9122-
signature))
9123-
memcpy(hdr->Signature, signature, SMB2_SIGNATURE_SIZE);
9120+
ksmbd_sign_smb3_pdu(conn, signing_key, iov, n_vec, signature);
9121+
memcpy(hdr->Signature, signature, SMB2_SIGNATURE_SIZE);
91249122
}
91259123

91269124
/**

0 commit comments

Comments
 (0)