Skip to content

Commit

Permalink
cifs: fork arc4 and create a separate module for it for cifs and othe…
Browse files Browse the repository at this point in the history
…r users

We can not drop ARC4 and basically destroy CIFS connectivity for
almost all CIFS users so create a new forked ARC4 module that CIFS and other
subsystems that have a hard dependency on ARC4 can use.

Signed-off-by: Ronnie Sahlberg <[email protected]>
Signed-off-by: Steve French <[email protected]>
  • Loading branch information
Ronnie Sahlberg authored and Steve French committed Aug 25, 2021
1 parent 76a3c92 commit 71c0286
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 5 deletions.
7 changes: 7 additions & 0 deletions fs/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,14 @@ config NFS_V4_2_SSC_HELPER

source "net/sunrpc/Kconfig"
source "fs/ceph/Kconfig"

source "fs/cifs/Kconfig"

config CIFS_COMMON
tristate
default y if CIFS=y
default m if CIFS=m

source "fs/coda/Kconfig"
source "fs/afs/Kconfig"
source "fs/9p/Kconfig"
Expand Down
1 change: 1 addition & 0 deletions fs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ obj-$(CONFIG_LOCKD) += lockd/
obj-$(CONFIG_NLS) += nls/
obj-$(CONFIG_UNICODE) += unicode/
obj-$(CONFIG_SYSV_FS) += sysv/
obj-$(CONFIG_CIFS_COMMON) += cifs_common/
obj-$(CONFIG_CIFS) += cifs/
obj-$(CONFIG_HPFS_FS) += hpfs/
obj-$(CONFIG_NTFS_FS) += ntfs/
Expand Down
1 change: 0 additions & 1 deletion fs/cifs/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ config CIFS
select CRYPTO_SHA512
select CRYPTO_CMAC
select CRYPTO_HMAC
select CRYPTO_LIB_ARC4
select CRYPTO_AEAD2
select CRYPTO_CCM
select CRYPTO_GCM
Expand Down
8 changes: 4 additions & 4 deletions fs/cifs/cifsencrypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
#include <linux/random.h>
#include <linux/highmem.h>
#include <linux/fips.h>
#include <crypto/arc4.h>
#include "../cifs_common/arc4.h"
#include <crypto/aead.h>

int __cifs_calc_signature(struct smb_rqst *rqst,
Expand Down Expand Up @@ -699,9 +699,9 @@ calc_seckey(struct cifs_ses *ses)
return -ENOMEM;
}

arc4_setkey(ctx_arc4, ses->auth_key.response, CIFS_SESS_KEY_SIZE);
arc4_crypt(ctx_arc4, ses->ntlmssp->ciphertext, sec_key,
CIFS_CPHTXT_SIZE);
cifs_arc4_setkey(ctx_arc4, ses->auth_key.response, CIFS_SESS_KEY_SIZE);
cifs_arc4_crypt(ctx_arc4, ses->ntlmssp->ciphertext, sec_key,
CIFS_CPHTXT_SIZE);

/* make secondary_key/nonce as session key */
memcpy(ses->auth_key.response, sec_key, CIFS_SESS_KEY_SIZE);
Expand Down
6 changes: 6 additions & 0 deletions fs/cifs_common/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# Makefile for Linux filesystem routines that are shared by client and server.
#

obj-$(CONFIG_CIFS_COMMON) += cifs_arc4.o
23 changes: 23 additions & 0 deletions fs/cifs_common/arc4.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Common values for ARC4 Cipher Algorithm
*/

#ifndef _CRYPTO_ARC4_H
#define _CRYPTO_ARC4_H

#include <linux/types.h>

#define ARC4_MIN_KEY_SIZE 1
#define ARC4_MAX_KEY_SIZE 256
#define ARC4_BLOCK_SIZE 1

struct arc4_ctx {
u32 S[256];
u32 x, y;
};

int cifs_arc4_setkey(struct arc4_ctx *ctx, const u8 *in_key, unsigned int key_len);
void cifs_arc4_crypt(struct arc4_ctx *ctx, u8 *out, const u8 *in, unsigned int len);

#endif /* _CRYPTO_ARC4_H */
87 changes: 87 additions & 0 deletions fs/cifs_common/cifs_arc4.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Cryptographic API
*
* ARC4 Cipher Algorithm
*
* Jon Oberheide <[email protected]>
*/

#include <linux/module.h>
#include "arc4.h"

MODULE_LICENSE("GPL");

int cifs_arc4_setkey(struct arc4_ctx *ctx, const u8 *in_key, unsigned int key_len)
{
int i, j = 0, k = 0;

ctx->x = 1;
ctx->y = 0;

for (i = 0; i < 256; i++)
ctx->S[i] = i;

for (i = 0; i < 256; i++) {
u32 a = ctx->S[i];

j = (j + in_key[k] + a) & 0xff;
ctx->S[i] = ctx->S[j];
ctx->S[j] = a;
if (++k >= key_len)
k = 0;
}

return 0;
}
EXPORT_SYMBOL_GPL(cifs_arc4_setkey);

void cifs_arc4_crypt(struct arc4_ctx *ctx, u8 *out, const u8 *in, unsigned int len)
{
u32 *const S = ctx->S;
u32 x, y, a, b;
u32 ty, ta, tb;

if (len == 0)
return;

x = ctx->x;
y = ctx->y;

a = S[x];
y = (y + a) & 0xff;
b = S[y];

do {
S[y] = a;
a = (a + b) & 0xff;
S[x] = b;
x = (x + 1) & 0xff;
ta = S[x];
ty = (y + ta) & 0xff;
tb = S[ty];
*out++ = *in++ ^ S[a];
if (--len == 0)
break;
y = ty;
a = ta;
b = tb;
} while (true);

ctx->x = x;
ctx->y = y;
}
EXPORT_SYMBOL_GPL(cifs_arc4_crypt);

static int __init
init_cifs_common(void)
{
return 0;
}
static void __init
exit_cifs_common(void)
{
}

module_init(init_cifs_common)
module_exit(exit_cifs_common)

0 comments on commit 71c0286

Please sign in to comment.