Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
d02509cd
Commit
d02509cd
authored
Oct 26, 2002
by
David S. Miller
Committed by
James Morris
Oct 26, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[CRYPTO]: Forgotten file add in previous commit.
parent
dd26a14c
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
252 additions
and
0 deletions
+252
-0
crypto/md4.c
crypto/md4.c
+252
-0
No files found.
crypto/md4.c
0 → 100644
View file @
d02509cd
/*
* Cryptographic API.
*
* MD4 Message Digest Algorithm (RFC1320).
*
* Implementation derived from Andrew Tridgell and Steve French's
* CIFS MD4 implementation, and the cryptoapi implementation
* originally based on the public domain implementation written
* by Colin Plumb in 1993.
*
* Copyright (c) Andrew Tridgell 1997-1998.
* Modified by Steve French (sfrench@us.ibm.com) 2002
* Copyright (c) Cryptoapi developers.
* Copyright (c) 2002 David S. Miller (davem@redhat.com)
* Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/crypto.h>
#include <asm/byteorder.h>
#define MD4_DIGEST_SIZE 16
#define MD4_HMAC_BLOCK_SIZE 64
#define MD4_BLOCK_WORDS 16
#define MD4_HASH_WORDS 4
struct
md4_ctx
{
u32
hash
[
MD4_HASH_WORDS
];
u32
block
[
MD4_BLOCK_WORDS
];
u64
byte_count
;
};
static
u32
lshift
(
u32
x
,
int
s
)
{
x
&=
0xFFFFFFFF
;
return
((
x
<<
s
)
&
0xFFFFFFFF
)
|
(
x
>>
(
32
-
s
));
}
static
inline
u32
F
(
u32
x
,
u32
y
,
u32
z
)
{
return
(
x
&
y
)
|
((
~
x
)
&
z
);
}
static
inline
u32
G
(
u32
x
,
u32
y
,
u32
z
)
{
return
(
x
&
y
)
|
(
x
&
z
)
|
(
y
&
z
);
}
static
inline
u32
H
(
u32
x
,
u32
y
,
u32
z
)
{
return
x
^
y
^
z
;
}
#define ROUND1(a,b,c,d,k,s) (a = lshift(a + F(b,c,d) + k, s))
#define ROUND2(a,b,c,d,k,s) (a = lshift(a + G(b,c,d) + k + (u32)0x5A827999,s))
#define ROUND3(a,b,c,d,k,s) (a = lshift(a + H(b,c,d) + k + (u32)0x6ED9EBA1,s))
/* XXX: this stuff can be optimized */
static
inline
void
le32_to_cpu_array
(
u32
*
buf
,
unsigned
words
)
{
while
(
words
--
)
{
__le32_to_cpus
(
buf
);
buf
++
;
}
}
static
inline
void
cpu_to_le32_array
(
u32
*
buf
,
unsigned
words
)
{
while
(
words
--
)
{
__cpu_to_le32s
(
buf
);
buf
++
;
}
}
static
inline
void
md4_transform
(
u32
*
hash
,
u32
const
*
in
)
{
u32
a
,
b
,
c
,
d
;
a
=
hash
[
0
];
b
=
hash
[
1
];
c
=
hash
[
2
];
d
=
hash
[
3
];
ROUND1
(
a
,
b
,
c
,
d
,
in
[
0
],
3
);
ROUND1
(
d
,
a
,
b
,
c
,
in
[
1
],
7
);
ROUND1
(
c
,
d
,
a
,
b
,
in
[
2
],
11
);
ROUND1
(
b
,
c
,
d
,
a
,
in
[
3
],
19
);
ROUND1
(
a
,
b
,
c
,
d
,
in
[
4
],
3
);
ROUND1
(
d
,
a
,
b
,
c
,
in
[
5
],
7
);
ROUND1
(
c
,
d
,
a
,
b
,
in
[
6
],
11
);
ROUND1
(
b
,
c
,
d
,
a
,
in
[
7
],
19
);
ROUND1
(
a
,
b
,
c
,
d
,
in
[
8
],
3
);
ROUND1
(
d
,
a
,
b
,
c
,
in
[
9
],
7
);
ROUND1
(
c
,
d
,
a
,
b
,
in
[
10
],
11
);
ROUND1
(
b
,
c
,
d
,
a
,
in
[
11
],
19
);
ROUND1
(
a
,
b
,
c
,
d
,
in
[
12
],
3
);
ROUND1
(
d
,
a
,
b
,
c
,
in
[
13
],
7
);
ROUND1
(
c
,
d
,
a
,
b
,
in
[
14
],
11
);
ROUND1
(
b
,
c
,
d
,
a
,
in
[
15
],
19
);
ROUND2
(
a
,
b
,
c
,
d
,
in
[
0
],
3
);
ROUND2
(
d
,
a
,
b
,
c
,
in
[
4
],
5
);
ROUND2
(
c
,
d
,
a
,
b
,
in
[
8
],
9
);
ROUND2
(
b
,
c
,
d
,
a
,
in
[
12
],
13
);
ROUND2
(
a
,
b
,
c
,
d
,
in
[
1
],
3
);
ROUND2
(
d
,
a
,
b
,
c
,
in
[
5
],
5
);
ROUND2
(
c
,
d
,
a
,
b
,
in
[
9
],
9
);
ROUND2
(
b
,
c
,
d
,
a
,
in
[
13
],
13
);
ROUND2
(
a
,
b
,
c
,
d
,
in
[
2
],
3
);
ROUND2
(
d
,
a
,
b
,
c
,
in
[
6
],
5
);
ROUND2
(
c
,
d
,
a
,
b
,
in
[
10
],
9
);
ROUND2
(
b
,
c
,
d
,
a
,
in
[
14
],
13
);
ROUND2
(
a
,
b
,
c
,
d
,
in
[
3
],
3
);
ROUND2
(
d
,
a
,
b
,
c
,
in
[
7
],
5
);
ROUND2
(
c
,
d
,
a
,
b
,
in
[
11
],
9
);
ROUND2
(
b
,
c
,
d
,
a
,
in
[
15
],
13
);
ROUND3
(
a
,
b
,
c
,
d
,
in
[
0
],
3
);
ROUND3
(
d
,
a
,
b
,
c
,
in
[
8
],
9
);
ROUND3
(
c
,
d
,
a
,
b
,
in
[
4
],
11
);
ROUND3
(
b
,
c
,
d
,
a
,
in
[
12
],
15
);
ROUND3
(
a
,
b
,
c
,
d
,
in
[
2
],
3
);
ROUND3
(
d
,
a
,
b
,
c
,
in
[
10
],
9
);
ROUND3
(
c
,
d
,
a
,
b
,
in
[
6
],
11
);
ROUND3
(
b
,
c
,
d
,
a
,
in
[
14
],
15
);
ROUND3
(
a
,
b
,
c
,
d
,
in
[
1
],
3
);
ROUND3
(
d
,
a
,
b
,
c
,
in
[
9
],
9
);
ROUND3
(
c
,
d
,
a
,
b
,
in
[
5
],
11
);
ROUND3
(
b
,
c
,
d
,
a
,
in
[
13
],
15
);
ROUND3
(
a
,
b
,
c
,
d
,
in
[
3
],
3
);
ROUND3
(
d
,
a
,
b
,
c
,
in
[
11
],
9
);
ROUND3
(
c
,
d
,
a
,
b
,
in
[
7
],
11
);
ROUND3
(
b
,
c
,
d
,
a
,
in
[
15
],
15
);
hash
[
0
]
+=
a
;
hash
[
1
]
+=
b
;
hash
[
2
]
+=
c
;
hash
[
3
]
+=
d
;
}
static
inline
void
md4_transform_helper
(
struct
md4_ctx
*
ctx
)
{
le32_to_cpu_array
(
ctx
->
block
,
sizeof
(
ctx
->
block
)
/
sizeof
(
u32
));
md4_transform
(
ctx
->
hash
,
ctx
->
block
);
}
static
void
md4_init
(
void
*
ctx
)
{
struct
md4_ctx
*
mctx
=
ctx
;
mctx
->
hash
[
0
]
=
0x67452301
;
mctx
->
hash
[
1
]
=
0xefcdab89
;
mctx
->
hash
[
2
]
=
0x98badcfe
;
mctx
->
hash
[
3
]
=
0x10325476
;
mctx
->
byte_count
=
0
;
}
static
void
md4_update
(
void
*
ctx
,
const
u8
*
data
,
size_t
len
)
{
struct
md4_ctx
*
mctx
=
ctx
;
const
u32
avail
=
sizeof
(
mctx
->
block
)
-
(
mctx
->
byte_count
&
0x3f
);
mctx
->
byte_count
+=
len
;
if
(
avail
>
len
)
{
memcpy
((
char
*
)
mctx
->
block
+
(
sizeof
(
mctx
->
block
)
-
avail
),
data
,
len
);
return
;
}
memcpy
((
char
*
)
mctx
->
block
+
(
sizeof
(
mctx
->
block
)
-
avail
),
data
,
avail
);
md4_transform_helper
(
mctx
);
data
+=
avail
;
len
-=
avail
;
while
(
len
>=
sizeof
(
mctx
->
block
))
{
memcpy
(
mctx
->
block
,
data
,
sizeof
(
mctx
->
block
));
md4_transform_helper
(
mctx
);
data
+=
sizeof
(
mctx
->
block
);
len
-=
sizeof
(
mctx
->
block
);
}
memcpy
(
mctx
->
block
,
data
,
len
);
}
static
void
md4_final
(
void
*
ctx
,
u8
*
out
)
{
struct
md4_ctx
*
mctx
=
ctx
;
const
int
offset
=
mctx
->
byte_count
&
0x3f
;
char
*
p
=
(
char
*
)
mctx
->
block
+
offset
;
int
padding
=
56
-
(
offset
+
1
);
*
p
++
=
0x80
;
if
(
padding
<
0
)
{
memset
(
p
,
0x00
,
padding
+
sizeof
(
u64
));
md4_transform_helper
(
mctx
);
p
=
(
char
*
)
mctx
->
block
;
padding
=
56
;
}
memset
(
p
,
0
,
padding
);
mctx
->
block
[
14
]
=
mctx
->
byte_count
<<
3
;
mctx
->
block
[
15
]
=
mctx
->
byte_count
>>
29
;
le32_to_cpu_array
(
mctx
->
block
,
(
sizeof
(
mctx
->
block
)
-
sizeof
(
u64
))
/
sizeof
(
u32
));
md4_transform
(
mctx
->
hash
,
mctx
->
block
);
cpu_to_le32_array
(
mctx
->
hash
,
sizeof
(
mctx
->
hash
)
/
sizeof
(
u32
));
memcpy
(
out
,
mctx
->
hash
,
sizeof
(
mctx
->
hash
));
memset
(
mctx
,
0
,
sizeof
(
mctx
));
}
static
struct
crypto_alg
alg
=
{
.
cra_id
=
CRYPTO_ALG_MD4
,
.
cra_name
=
"md4"
,
.
cra_blocksize
=
MD4_HMAC_BLOCK_SIZE
,
.
cra_ctxsize
=
sizeof
(
struct
md4_ctx
),
.
cra_module
=
THIS_MODULE
,
.
cra_u
=
{
.
digest
=
{
.
dia_digestsize
=
MD4_DIGEST_SIZE
,
.
dia_init
=
md4_init
,
.
dia_update
=
md4_update
,
.
dia_final
=
md4_final
}
}
};
static
int
__init
init
(
void
)
{
INIT_LIST_HEAD
(
&
alg
.
cra_list
);
return
crypto_register_alg
(
&
alg
);
}
static
void
__exit
fini
(
void
)
{
crypto_unregister_alg
(
&
alg
);
}
module_init
(
init
);
module_exit
(
fini
);
MODULE_LICENSE
(
"GPL"
);
MODULE_DESCRIPTION
(
"MD4 Message Digest Algorithm"
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment