Skip to content

Commit

Permalink
cifs: fork arc4 and add a private copy in fs/cifs
Browse files Browse the repository at this point in the history
SMB supports two authentication modes, a modified krb5 mode which contains
ActiveDirectory extensions and accound information for the tickets and
NTLMSSP.

For NTLMSSP in SMB1/2/3 authentication uses a combination of all three of
md4/md5/arc4.

Fork/copy the ARC4 implementation from the crypto library into fs/cifs
so that we have a private version for NTLMSSP once ARC4 is removed from the
kernel crypto libraries.

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
  • Loading branch information
Ronnie Sahlberg authored and intel-lab-lkp committed Aug 19, 2021
1 parent 1c2809b commit 370a85a
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 3 deletions.
1 change: 0 additions & 1 deletion fs/cifs/Kconfig
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
2 changes: 1 addition & 1 deletion fs/cifs/Makefile
Expand Up @@ -7,7 +7,7 @@ obj-$(CONFIG_CIFS) += cifs.o

cifs-y := trace.o cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o \
inode.o link.o misc.o netmisc.o smbencrypt.o transport.o \
cifs_unicode.o nterr.o cifsencrypt.o \
arc4.o cifs_unicode.o nterr.o cifsencrypt.o \
readdir.o ioctl.o sess.o export.o unc.o winucase.o \
smb2ops.o smb2maperror.o smb2transport.o \
smb2misc.o smb2pdu.o smb2inode.o smb2file.o cifsacl.o fs_context.o \
Expand Down
69 changes: 69 additions & 0 deletions fs/cifs/arc4.c
@@ -0,0 +1,69 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Cryptographic API
*
* ARC4 Cipher Algorithm
*
* Jon Oberheide <jon@oberheide.org>
*/

#include "arc4.h"

int 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;
}

void 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;
}
23 changes: 23 additions & 0 deletions fs/cifs/arc4.h
@@ -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 arc4_setkey(struct arc4_ctx *ctx, const u8 *in_key, unsigned int key_len);
void arc4_crypt(struct arc4_ctx *ctx, u8 *out, const u8 *in, unsigned int len);

#endif /* _CRYPTO_ARC4_H */
2 changes: 1 addition & 1 deletion fs/cifs/cifsencrypt.c
Expand Up @@ -22,7 +22,7 @@
#include <linux/random.h>
#include <linux/highmem.h>
#include <linux/fips.h>
#include <crypto/arc4.h>
#include "arc4.h"
#include <crypto/aead.h>

int __cifs_calc_signature(struct smb_rqst *rqst,
Expand Down

0 comments on commit 370a85a

Please sign in to comment.