Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
labs
BIRD Internet Routing Daemon
Commits
33b4f40a
Commit
33b4f40a
authored
Nov 13, 2015
by
Pavel Tvrdík
Committed by
Ondřej Zajíček
Nov 24, 2015
Browse files
MD5: Mormalize naming style
parent
90f78507
Changes
4
Hide whitespace changes
Inline
Side-by-side
lib/md5.c
View file @
33b4f40a
/*
* This code implements the MD5 message-digest algorithm.
* The algorithm is due to Ron Rivest. This code was
* written by Colin Plumb in 1993, no copyright is claimed.
* This code is in the public domain; do with it what you wish.
* BIRD Library -- MD5 Hash Function and HMAC-MD5 Function
*
* Equivalent code is available from RSA Data Security, Inc.
* This code has been tested against that, and is equivalent,
* except that you don't need to include two pages of legalese
* with every copy.
* (c) 2015 CZ.NIC z.s.p.o.
*
* To compute the message digest of a chunk of bytes, declare an
* MD5Context structure, pass it to MD5Init, call MD5Update as
* needed on buffers full of bytes, and then call MD5Final, which
* will fill a supplied 16-byte array with the digest.
*/
/*
* Adapted for BIRD by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
* The code was written by Colin Plumb in 1993, no copyright is claimed.
*
* Adapted for BIRD by Martin Mares <mj@ucw.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
#include "nest/bird.h"
#include "lib/string.h"
#include "md5.h"
#include "lib/md5.h"
#ifdef CPU_LITTLE_ENDIAN
#define byteReverse(buf, len)
/* Nothing */
#else
void
byteReverse
(
unsigned
char
*
buf
,
u
nsigned
longs
);
void
byteReverse
(
byte
*
buf
,
u
int
longs
);
/*
* Note: this code is harmless on little-endian machines.
*/
void
byteReverse
(
unsigned
char
*
buf
,
u
nsigned
longs
)
void
byteReverse
(
byte
*
buf
,
u
int
longs
)
{
u32
t
;
do
{
t
=
(
u32
)
((
u
nsigned
)
buf
[
3
]
<<
8
|
buf
[
2
])
<<
16
|
((
unsigned
)
buf
[
1
]
<<
8
|
buf
[
0
]);
*
(
u32
*
)
buf
=
t
;
buf
+=
4
;
}
while
(
--
longs
);
u32
t
;
do
{
t
=
(
u32
)
((
u
int
)
buf
[
3
]
<<
8
|
buf
[
2
])
<<
16
|
((
uint
)
buf
[
1
]
<<
8
|
buf
[
0
]);
*
(
u32
*
)
buf
=
t
;
buf
+=
4
;
}
while
(
--
longs
);
}
#endif
static
void
md5_transform
(
u32
buf
[
4
],
u32
const
in
[
16
]);
/*
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
* initialization constants.
*/
void
MD5Init
(
struct
MD5Context
*
ctx
)
void
md5_init
(
struct
md5_context
*
ctx
)
{
ctx
->
buf
[
0
]
=
0x67452301
;
ctx
->
buf
[
1
]
=
0xefcdab89
;
ctx
->
buf
[
2
]
=
0x98badcfe
;
ctx
->
buf
[
3
]
=
0x10325476
;
ctx
->
buf
[
0
]
=
0x67452301
;
ctx
->
buf
[
1
]
=
0xefcdab89
;
ctx
->
buf
[
2
]
=
0x98badcfe
;
ctx
->
buf
[
3
]
=
0x10325476
;
ctx
->
bits
[
0
]
=
0
;
ctx
->
bits
[
1
]
=
0
;
ctx
->
bits
[
0
]
=
0
;
ctx
->
bits
[
1
]
=
0
;
}
/*
* Update context to reflect the concatenation of another buffer full
* of bytes.
*/
void
MD5Update
(
struct
MD5Context
*
ctx
,
unsigned
char
const
*
buf
,
unsigned
len
)
void
md5_update
(
struct
md5_context
*
ctx
,
const
byte
*
buf
,
uint
len
)
{
u32
t
;
u32
t
;
/* Update bitcount */
/* Update bitcount */
t
=
ctx
->
bits
[
0
];
if
((
ctx
->
bits
[
0
]
=
t
+
((
u32
)
len
<<
3
))
<
t
)
ctx
->
bits
[
1
]
++
;
/* Carry from low to high */
ctx
->
bits
[
1
]
+=
len
>>
29
;
t
=
ctx
->
bits
[
0
];
if
((
ctx
->
bits
[
0
]
=
t
+
((
u32
)
len
<<
3
))
<
t
)
ctx
->
bits
[
1
]
++
;
/* Carry from low to high */
ctx
->
bits
[
1
]
+=
len
>>
29
;
t
=
(
t
>>
3
)
&
0x3f
;
/* Bytes already in shsInfo->data */
t
=
(
t
>>
3
)
&
0x3f
;
/* Bytes already in shsInfo->data */
/* Handle any leading odd-sized chunks */
/* Handle any leading odd-sized chunks */
if
(
t
)
{
byte
*
p
=
(
byte
*
)
ctx
->
in
+
t
;
if
(
t
)
{
unsigned
char
*
p
=
(
unsigned
char
*
)
ctx
->
in
+
t
;
t
=
64
-
t
;
if
(
len
<
t
)
{
memcpy
(
p
,
buf
,
len
);
return
;
}
memcpy
(
p
,
buf
,
t
);
byteReverse
(
ctx
->
in
,
16
);
MD5Transform
(
ctx
->
buf
,
(
u32
*
)
ctx
->
in
);
buf
+=
t
;
len
-=
t
;
}
/* Process data in 64-byte chunks */
while
(
len
>=
64
)
{
memcpy
(
ctx
->
in
,
buf
,
64
);
byteReverse
(
ctx
->
in
,
16
);
MD5Transform
(
ctx
->
buf
,
(
u32
*
)
ctx
->
in
);
buf
+=
64
;
len
-=
64
;
t
=
64
-
t
;
if
(
len
<
t
)
{
memcpy
(
p
,
buf
,
len
);
return
;
}
/* Handle any remaining bytes of data. */
memcpy
(
ctx
->
in
,
buf
,
len
);
memcpy
(
p
,
buf
,
t
);
byteReverse
(
ctx
->
in
,
16
);
md5_transform
(
ctx
->
buf
,
(
u32
*
)
ctx
->
in
);
buf
+=
t
;
len
-=
t
;
}
/* Process data in 64-byte chunks */
while
(
len
>=
64
)
{
memcpy
(
ctx
->
in
,
buf
,
64
);
byteReverse
(
ctx
->
in
,
16
);
md5_transform
(
ctx
->
buf
,
(
u32
*
)
ctx
->
in
);
buf
+=
64
;
len
-=
64
;
}
/* Handle any remaining bytes of data. */
memcpy
(
ctx
->
in
,
buf
,
len
);
}
/*
* Final wrapup - pad to 64-byte boundary with the bit pattern
* Final wrapup - pad to 64-byte boundary with the bit pattern
* 1 0* (64-bit count of bits processed, MSB-first)
*/
void
MD5Final
(
unsigned
char
digest
[
16
],
struct
MD5Context
*
ctx
)
byte
*
md5_final
(
struct
md5_context
*
ctx
)
{
u
nsigned
count
;
unsigned
char
*
p
;
u
int
count
;
byte
*
p
;
/* Compute number of bytes mod 64 */
count
=
(
ctx
->
bits
[
0
]
>>
3
)
&
0x3F
;
/* Compute number of bytes mod 64 */
count
=
(
ctx
->
bits
[
0
]
>>
3
)
&
0x3F
;
/* Set the first char of padding to 0x80. This is safe since there is
/* Set the first char of padding to 0x80. This is safe since there is
always at least one byte free */
p
=
ctx
->
in
+
count
;
*
p
++
=
0x80
;
/* Bytes of padding needed to make 64 bytes */
count
=
64
-
1
-
count
;
/* Pad out to 56 mod 64 */
if
(
count
<
8
)
{
/* Two lots of padding: Pad the first block to 64 bytes */
memset
(
p
,
0
,
count
);
byteReverse
(
ctx
->
in
,
16
);
MD5Transform
(
ctx
->
buf
,
(
u32
*
)
ctx
->
in
);
/* Now fill the next block with 56 bytes */
memset
(
ctx
->
in
,
0
,
56
);
}
else
{
/* Pad block to 56 bytes */
memset
(
p
,
0
,
count
-
8
);
}
byteReverse
(
ctx
->
in
,
14
);
/* Append length in bits and transform */
((
u32
*
)
ctx
->
in
)[
14
]
=
ctx
->
bits
[
0
];
((
u32
*
)
ctx
->
in
)[
15
]
=
ctx
->
bits
[
1
];
p
=
ctx
->
in
+
count
;
*
p
++
=
0x80
;
/* Bytes of padding needed to make 64 bytes */
count
=
64
-
1
-
count
;
/* Pad out to 56 mod 64 */
if
(
count
<
8
)
{
/* Two lots of padding: Pad the first block to 64 bytes */
memset
(
p
,
0
,
count
);
byteReverse
(
ctx
->
in
,
16
);
md5_transform
(
ctx
->
buf
,
(
u32
*
)
ctx
->
in
);
/* Now fill the next block with 56 bytes */
memset
(
ctx
->
in
,
0
,
56
);
}
else
{
/* Pad block to 56 bytes */
memset
(
p
,
0
,
count
-
8
);
}
byteReverse
(
ctx
->
in
,
14
);
/* Append length in bits and transform */
((
u32
*
)
ctx
->
in
)[
14
]
=
ctx
->
bits
[
0
];
((
u32
*
)
ctx
->
in
)[
15
]
=
ctx
->
bits
[
1
];
md5_transform
(
ctx
->
buf
,
(
u32
*
)
ctx
->
in
);
byteReverse
((
byte
*
)
ctx
->
buf
,
4
);
return
(
byte
*
)
ctx
->
buf
;
}
MD5Transform
(
ctx
->
buf
,
(
u32
*
)
ctx
->
in
);
byteReverse
((
unsigned
char
*
)
ctx
->
buf
,
4
);
memcpy
(
digest
,
ctx
->
buf
,
16
);
memset
((
char
*
)
ctx
,
0
,
sizeof
(
ctx
));
/* In case it's sensitive */
/* I am a hard paranoid */
void
md5_erase_ctx
(
struct
md5_context
*
ctx
)
{
memset
((
char
*
)
ctx
,
0
,
sizeof
(
*
ctx
));
/* In case it's sensitive */
}
/* The four core functions - F1 is optimized somewhat */
...
...
@@ -161,92 +166,157 @@ void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
/* This is the central step in the MD5 algorithm. */
#define MD5STEP(f, w, x, y, z, data, s) \
( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
/*
* The core of the MD5 algorithm, this alters an existing MD5 hash to
* reflect the addition of 16 longwords of new data. MD5Update blocks
* the data and converts bytes into longwords for this routine.
*/
void
MD5Transform
(
u32
buf
[
4
],
u32
const
in
[
16
])
void
md5_transform
(
u32
buf
[
4
],
u32
const
in
[
16
])
{
register
u32
a
,
b
,
c
,
d
;
a
=
buf
[
0
];
b
=
buf
[
1
];
c
=
buf
[
2
];
d
=
buf
[
3
];
MD5STEP
(
F1
,
a
,
b
,
c
,
d
,
in
[
0
]
+
0xd76aa478
,
7
);
MD5STEP
(
F1
,
d
,
a
,
b
,
c
,
in
[
1
]
+
0xe8c7b756
,
12
);
MD5STEP
(
F1
,
c
,
d
,
a
,
b
,
in
[
2
]
+
0x242070db
,
17
);
MD5STEP
(
F1
,
b
,
c
,
d
,
a
,
in
[
3
]
+
0xc1bdceee
,
22
);
MD5STEP
(
F1
,
a
,
b
,
c
,
d
,
in
[
4
]
+
0xf57c0faf
,
7
);
MD5STEP
(
F1
,
d
,
a
,
b
,
c
,
in
[
5
]
+
0x4787c62a
,
12
);
MD5STEP
(
F1
,
c
,
d
,
a
,
b
,
in
[
6
]
+
0xa8304613
,
17
);
MD5STEP
(
F1
,
b
,
c
,
d
,
a
,
in
[
7
]
+
0xfd469501
,
22
);
MD5STEP
(
F1
,
a
,
b
,
c
,
d
,
in
[
8
]
+
0x698098d8
,
7
);
MD5STEP
(
F1
,
d
,
a
,
b
,
c
,
in
[
9
]
+
0x8b44f7af
,
12
);
MD5STEP
(
F1
,
c
,
d
,
a
,
b
,
in
[
10
]
+
0xffff5bb1
,
17
);
MD5STEP
(
F1
,
b
,
c
,
d
,
a
,
in
[
11
]
+
0x895cd7be
,
22
);
MD5STEP
(
F1
,
a
,
b
,
c
,
d
,
in
[
12
]
+
0x6b901122
,
7
);
MD5STEP
(
F1
,
d
,
a
,
b
,
c
,
in
[
13
]
+
0xfd987193
,
12
);
MD5STEP
(
F1
,
c
,
d
,
a
,
b
,
in
[
14
]
+
0xa679438e
,
17
);
MD5STEP
(
F1
,
b
,
c
,
d
,
a
,
in
[
15
]
+
0x49b40821
,
22
);
MD5STEP
(
F2
,
a
,
b
,
c
,
d
,
in
[
1
]
+
0xf61e2562
,
5
);
MD5STEP
(
F2
,
d
,
a
,
b
,
c
,
in
[
6
]
+
0xc040b340
,
9
);
MD5STEP
(
F2
,
c
,
d
,
a
,
b
,
in
[
11
]
+
0x265e5a51
,
14
);
MD5STEP
(
F2
,
b
,
c
,
d
,
a
,
in
[
0
]
+
0xe9b6c7aa
,
20
);
MD5STEP
(
F2
,
a
,
b
,
c
,
d
,
in
[
5
]
+
0xd62f105d
,
5
);
MD5STEP
(
F2
,
d
,
a
,
b
,
c
,
in
[
10
]
+
0x02441453
,
9
);
MD5STEP
(
F2
,
c
,
d
,
a
,
b
,
in
[
15
]
+
0xd8a1e681
,
14
);
MD5STEP
(
F2
,
b
,
c
,
d
,
a
,
in
[
4
]
+
0xe7d3fbc8
,
20
);
MD5STEP
(
F2
,
a
,
b
,
c
,
d
,
in
[
9
]
+
0x21e1cde6
,
5
);
MD5STEP
(
F2
,
d
,
a
,
b
,
c
,
in
[
14
]
+
0xc33707d6
,
9
);
MD5STEP
(
F2
,
c
,
d
,
a
,
b
,
in
[
3
]
+
0xf4d50d87
,
14
);
MD5STEP
(
F2
,
b
,
c
,
d
,
a
,
in
[
8
]
+
0x455a14ed
,
20
);
MD5STEP
(
F2
,
a
,
b
,
c
,
d
,
in
[
13
]
+
0xa9e3e905
,
5
);
MD5STEP
(
F2
,
d
,
a
,
b
,
c
,
in
[
2
]
+
0xfcefa3f8
,
9
);
MD5STEP
(
F2
,
c
,
d
,
a
,
b
,
in
[
7
]
+
0x676f02d9
,
14
);
MD5STEP
(
F2
,
b
,
c
,
d
,
a
,
in
[
12
]
+
0x8d2a4c8a
,
20
);
MD5STEP
(
F3
,
a
,
b
,
c
,
d
,
in
[
5
]
+
0xfffa3942
,
4
);
MD5STEP
(
F3
,
d
,
a
,
b
,
c
,
in
[
8
]
+
0x8771f681
,
11
);
MD5STEP
(
F3
,
c
,
d
,
a
,
b
,
in
[
11
]
+
0x6d9d6122
,
16
);
MD5STEP
(
F3
,
b
,
c
,
d
,
a
,
in
[
14
]
+
0xfde5380c
,
23
);
MD5STEP
(
F3
,
a
,
b
,
c
,
d
,
in
[
1
]
+
0xa4beea44
,
4
);
MD5STEP
(
F3
,
d
,
a
,
b
,
c
,
in
[
4
]
+
0x4bdecfa9
,
11
);
MD5STEP
(
F3
,
c
,
d
,
a
,
b
,
in
[
7
]
+
0xf6bb4b60
,
16
);
MD5STEP
(
F3
,
b
,
c
,
d
,
a
,
in
[
10
]
+
0xbebfbc70
,
23
);
MD5STEP
(
F3
,
a
,
b
,
c
,
d
,
in
[
13
]
+
0x289b7ec6
,
4
);
MD5STEP
(
F3
,
d
,
a
,
b
,
c
,
in
[
0
]
+
0xeaa127fa
,
11
);
MD5STEP
(
F3
,
c
,
d
,
a
,
b
,
in
[
3
]
+
0xd4ef3085
,
16
);
MD5STEP
(
F3
,
b
,
c
,
d
,
a
,
in
[
6
]
+
0x04881d05
,
23
);
MD5STEP
(
F3
,
a
,
b
,
c
,
d
,
in
[
9
]
+
0xd9d4d039
,
4
);
MD5STEP
(
F3
,
d
,
a
,
b
,
c
,
in
[
12
]
+
0xe6db99e5
,
11
);
MD5STEP
(
F3
,
c
,
d
,
a
,
b
,
in
[
15
]
+
0x1fa27cf8
,
16
);
MD5STEP
(
F3
,
b
,
c
,
d
,
a
,
in
[
2
]
+
0xc4ac5665
,
23
);
MD5STEP
(
F4
,
a
,
b
,
c
,
d
,
in
[
0
]
+
0xf4292244
,
6
);
MD5STEP
(
F4
,
d
,
a
,
b
,
c
,
in
[
7
]
+
0x432aff97
,
10
);
MD5STEP
(
F4
,
c
,
d
,
a
,
b
,
in
[
14
]
+
0xab9423a7
,
15
);
MD5STEP
(
F4
,
b
,
c
,
d
,
a
,
in
[
5
]
+
0xfc93a039
,
21
);
MD5STEP
(
F4
,
a
,
b
,
c
,
d
,
in
[
12
]
+
0x655b59c3
,
6
);
MD5STEP
(
F4
,
d
,
a
,
b
,
c
,
in
[
3
]
+
0x8f0ccc92
,
10
);
MD5STEP
(
F4
,
c
,
d
,
a
,
b
,
in
[
10
]
+
0xffeff47d
,
15
);
MD5STEP
(
F4
,
b
,
c
,
d
,
a
,
in
[
1
]
+
0x85845dd1
,
21
);
MD5STEP
(
F4
,
a
,
b
,
c
,
d
,
in
[
8
]
+
0x6fa87e4f
,
6
);
MD5STEP
(
F4
,
d
,
a
,
b
,
c
,
in
[
15
]
+
0xfe2ce6e0
,
10
);
MD5STEP
(
F4
,
c
,
d
,
a
,
b
,
in
[
6
]
+
0xa3014314
,
15
);
MD5STEP
(
F4
,
b
,
c
,
d
,
a
,
in
[
13
]
+
0x4e0811a1
,
21
);
MD5STEP
(
F4
,
a
,
b
,
c
,
d
,
in
[
4
]
+
0xf7537e82
,
6
);
MD5STEP
(
F4
,
d
,
a
,
b
,
c
,
in
[
11
]
+
0xbd3af235
,
10
);
MD5STEP
(
F4
,
c
,
d
,
a
,
b
,
in
[
2
]
+
0x2ad7d2bb
,
15
);
MD5STEP
(
F4
,
b
,
c
,
d
,
a
,
in
[
9
]
+
0xeb86d391
,
21
);
buf
[
0
]
+=
a
;
buf
[
1
]
+=
b
;
buf
[
2
]
+=
c
;
buf
[
3
]
+=
d
;
}
/*
* MD5-HMAC
*/
static
void
md5_hash_buffer
(
byte
*
outbuf
,
const
byte
*
buffer
,
size_t
length
)
{
struct
md5_context
hd_tmp
;
md5_init
(
&
hd_tmp
);
md5_update
(
&
hd_tmp
,
buffer
,
length
);
memcpy
(
outbuf
,
md5_final
(
&
hd_tmp
),
MD5_SIZE
);
}
void
md5_hmac_init
(
struct
md5_hmac_context
*
ctx
,
const
byte
*
key
,
size_t
keylen
)
{
byte
keybuf
[
MD5_BLOCK_SIZE
],
buf
[
MD5_BLOCK_SIZE
];
/* Hash the key if necessary */
if
(
keylen
<=
MD5_BLOCK_SIZE
)
{
memcpy
(
keybuf
,
key
,
keylen
);
bzero
(
keybuf
+
keylen
,
MD5_BLOCK_SIZE
-
keylen
);
}
else
{
md5_hash_buffer
(
keybuf
,
key
,
keylen
);
bzero
(
keybuf
+
MD5_SIZE
,
MD5_BLOCK_SIZE
-
MD5_SIZE
);
}
/* Initialize the inner digest */
md5_init
(
&
ctx
->
ictx
);
int
i
;
for
(
i
=
0
;
i
<
MD5_BLOCK_SIZE
;
i
++
)
buf
[
i
]
=
keybuf
[
i
]
^
0x36
;
md5_update
(
&
ctx
->
ictx
,
buf
,
MD5_BLOCK_SIZE
);
/* Initialize the outer digest */
md5_init
(
&
ctx
->
octx
);
for
(
i
=
0
;
i
<
MD5_BLOCK_SIZE
;
i
++
)
buf
[
i
]
=
keybuf
[
i
]
^
0x5c
;
md5_update
(
&
ctx
->
octx
,
buf
,
MD5_BLOCK_SIZE
);
}
void
md5_hmac_update
(
struct
md5_hmac_context
*
ctx
,
const
byte
*
buf
,
size_t
buflen
)
{
register
u32
a
,
b
,
c
,
d
;
a
=
buf
[
0
];
b
=
buf
[
1
];
c
=
buf
[
2
];
d
=
buf
[
3
];
MD5STEP
(
F1
,
a
,
b
,
c
,
d
,
in
[
0
]
+
0xd76aa478
,
7
);
MD5STEP
(
F1
,
d
,
a
,
b
,
c
,
in
[
1
]
+
0xe8c7b756
,
12
);
MD5STEP
(
F1
,
c
,
d
,
a
,
b
,
in
[
2
]
+
0x242070db
,
17
);
MD5STEP
(
F1
,
b
,
c
,
d
,
a
,
in
[
3
]
+
0xc1bdceee
,
22
);
MD5STEP
(
F1
,
a
,
b
,
c
,
d
,
in
[
4
]
+
0xf57c0faf
,
7
);
MD5STEP
(
F1
,
d
,
a
,
b
,
c
,
in
[
5
]
+
0x4787c62a
,
12
);
MD5STEP
(
F1
,
c
,
d
,
a
,
b
,
in
[
6
]
+
0xa8304613
,
17
);
MD5STEP
(
F1
,
b
,
c
,
d
,
a
,
in
[
7
]
+
0xfd469501
,
22
);
MD5STEP
(
F1
,
a
,
b
,
c
,
d
,
in
[
8
]
+
0x698098d8
,
7
);
MD5STEP
(
F1
,
d
,
a
,
b
,
c
,
in
[
9
]
+
0x8b44f7af
,
12
);
MD5STEP
(
F1
,
c
,
d
,
a
,
b
,
in
[
10
]
+
0xffff5bb1
,
17
);
MD5STEP
(
F1
,
b
,
c
,
d
,
a
,
in
[
11
]
+
0x895cd7be
,
22
);
MD5STEP
(
F1
,
a
,
b
,
c
,
d
,
in
[
12
]
+
0x6b901122
,
7
);
MD5STEP
(
F1
,
d
,
a
,
b
,
c
,
in
[
13
]
+
0xfd987193
,
12
);
MD5STEP
(
F1
,
c
,
d
,
a
,
b
,
in
[
14
]
+
0xa679438e
,
17
);
MD5STEP
(
F1
,
b
,
c
,
d
,
a
,
in
[
15
]
+
0x49b40821
,
22
);
MD5STEP
(
F2
,
a
,
b
,
c
,
d
,
in
[
1
]
+
0xf61e2562
,
5
);
MD5STEP
(
F2
,
d
,
a
,
b
,
c
,
in
[
6
]
+
0xc040b340
,
9
);
MD5STEP
(
F2
,
c
,
d
,
a
,
b
,
in
[
11
]
+
0x265e5a51
,
14
);
MD5STEP
(
F2
,
b
,
c
,
d
,
a
,
in
[
0
]
+
0xe9b6c7aa
,
20
);
MD5STEP
(
F2
,
a
,
b
,
c
,
d
,
in
[
5
]
+
0xd62f105d
,
5
);
MD5STEP
(
F2
,
d
,
a
,
b
,
c
,
in
[
10
]
+
0x02441453
,
9
);
MD5STEP
(
F2
,
c
,
d
,
a
,
b
,
in
[
15
]
+
0xd8a1e681
,
14
);
MD5STEP
(
F2
,
b
,
c
,
d
,
a
,
in
[
4
]
+
0xe7d3fbc8
,
20
);
MD5STEP
(
F2
,
a
,
b
,
c
,
d
,
in
[
9
]
+
0x21e1cde6
,
5
);
MD5STEP
(
F2
,
d
,
a
,
b
,
c
,
in
[
14
]
+
0xc33707d6
,
9
);
MD5STEP
(
F2
,
c
,
d
,
a
,
b
,
in
[
3
]
+
0xf4d50d87
,
14
);
MD5STEP
(
F2
,
b
,
c
,
d
,
a
,
in
[
8
]
+
0x455a14ed
,
20
);
MD5STEP
(
F2
,
a
,
b
,
c
,
d
,
in
[
13
]
+
0xa9e3e905
,
5
);
MD5STEP
(
F2
,
d
,
a
,
b
,
c
,
in
[
2
]
+
0xfcefa3f8
,
9
);
MD5STEP
(
F2
,
c
,
d
,
a
,
b
,
in
[
7
]
+
0x676f02d9
,
14
);
MD5STEP
(
F2
,
b
,
c
,
d
,
a
,
in
[
12
]
+
0x8d2a4c8a
,
20
);
MD5STEP
(
F3
,
a
,
b
,
c
,
d
,
in
[
5
]
+
0xfffa3942
,
4
);
MD5STEP
(
F3
,
d
,
a
,
b
,
c
,
in
[
8
]
+
0x8771f681
,
11
);
MD5STEP
(
F3
,
c
,
d
,
a
,
b
,
in
[
11
]
+
0x6d9d6122
,
16
);
MD5STEP
(
F3
,
b
,
c
,
d
,
a
,
in
[
14
]
+
0xfde5380c
,
23
);
MD5STEP
(
F3
,
a
,
b
,
c
,
d
,
in
[
1
]
+
0xa4beea44
,
4
);
MD5STEP
(
F3
,
d
,
a
,
b
,
c
,
in
[
4
]
+
0x4bdecfa9
,
11
);
MD5STEP
(
F3
,
c
,
d
,
a
,
b
,
in
[
7
]
+
0xf6bb4b60
,
16
);
MD5STEP
(
F3
,
b
,
c
,
d
,
a
,
in
[
10
]
+
0xbebfbc70
,
23
);
MD5STEP
(
F3
,
a
,
b
,
c
,
d
,
in
[
13
]
+
0x289b7ec6
,
4
);
MD5STEP
(
F3
,
d
,
a
,
b
,
c
,
in
[
0
]
+
0xeaa127fa
,
11
);
MD5STEP
(
F3
,
c
,
d
,
a
,
b
,
in
[
3
]
+
0xd4ef3085
,
16
);
MD5STEP
(
F3
,
b
,
c
,
d
,
a
,
in
[
6
]
+
0x04881d05
,
23
);
MD5STEP
(
F3
,
a
,
b
,
c
,
d
,
in
[
9
]
+
0xd9d4d039
,
4
);
MD5STEP
(
F3
,
d
,
a
,
b
,
c
,
in
[
12
]
+
0xe6db99e5
,
11
);
MD5STEP
(
F3
,
c
,
d
,
a
,
b
,
in
[
15
]
+
0x1fa27cf8
,
16
);
MD5STEP
(
F3
,
b
,
c
,
d
,
a
,
in
[
2
]
+
0xc4ac5665
,
23
);
MD5STEP
(
F4
,
a
,
b
,
c
,
d
,
in
[
0
]
+
0xf4292244
,
6
);
MD5STEP
(
F4
,
d
,
a
,
b
,
c
,
in
[
7
]
+
0x432aff97
,
10
);
MD5STEP
(
F4
,
c
,
d
,
a
,
b
,
in
[
14
]
+
0xab9423a7
,
15
);
MD5STEP
(
F4
,
b
,
c
,
d
,
a
,
in
[
5
]
+
0xfc93a039
,
21
);
MD5STEP
(
F4
,
a
,
b
,
c
,
d
,
in
[
12
]
+
0x655b59c3
,
6
);
MD5STEP
(
F4
,
d
,
a
,
b
,
c
,
in
[
3
]
+
0x8f0ccc92
,
10
);
MD5STEP
(
F4
,
c
,
d
,
a
,
b
,
in
[
10
]
+
0xffeff47d
,
15
);
MD5STEP
(
F4
,
b
,
c
,
d
,
a
,
in
[
1
]
+
0x85845dd1
,
21
);
MD5STEP
(
F4
,
a
,
b
,
c
,
d
,
in
[
8
]
+
0x6fa87e4f
,
6
);
MD5STEP
(
F4
,
d
,
a
,
b
,
c
,
in
[
15
]
+
0xfe2ce6e0
,
10
);
MD5STEP
(
F4
,
c
,
d
,
a
,
b
,
in
[
6
]
+
0xa3014314
,
15
);
MD5STEP
(
F4
,
b
,
c
,
d
,
a
,
in
[
13
]
+
0x4e0811a1
,
21
);
MD5STEP
(
F4
,
a
,
b
,
c
,
d
,
in
[
4
]
+
0xf7537e82
,
6
);
MD5STEP
(
F4
,
d
,
a
,
b
,
c
,
in
[
11
]
+
0xbd3af235
,
10
);
MD5STEP
(
F4
,
c
,
d
,
a
,
b
,
in
[
2
]
+
0x2ad7d2bb
,
15
);
MD5STEP
(
F4
,
b
,
c
,
d
,
a
,
in
[
9
]
+
0xeb86d391
,
21
);
buf
[
0
]
+=
a
;
buf
[
1
]
+=
b
;
buf
[
2
]
+=
c
;
buf
[
3
]
+=
d
;
/* Just update the inner digest */
md5_update
(
&
ctx
->
ictx
,
buf
,
buflen
);
}
byte
*
md5_hmac_final
(
struct
md5_hmac_context
*
ctx
)
{
/* Finish the inner digest */
byte
*
isha
=
md5_final
(
&
ctx
->
ictx
);
/* Finish the outer digest */
md5_update
(
&
ctx
->
octx
,
isha
,
MD5_SIZE
);
return
md5_final
(
&
ctx
->
octx
);
}
lib/md5.h
View file @
33b4f40a
#ifndef MD5_H
#define MD5_H
/*
* BIRD Library -- MD5 Hash Function and HMAC-MD5 Function
*
* (c) 2015 CZ.NIC z.s.p.o.
*
* Adapted for BIRD by Martin Mares <mj@ucw.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
struct
MD5Context
{
u32
buf
[
4
];
u32
bits
[
2
];
unsigned
char
in
[
64
];
#ifndef _BIRD_MD5_H_
#define _BIRD_MD5_H_
#include "nest/bird.h"
#define MD5_SIZE 16
#define MD5_HEX_SIZE 33
#define MD5_BLOCK_SIZE 64
struct
md5_context
{
u32
buf
[
4
];
u32
bits
[
2
];
byte
in
[
64
];
};
void
MD5Init
(
struct
MD5Context
*
context
);
void
MD5Update
(
struct
MD5Context
*
context
,
unsigned
char
const
*
buf
,
unsigned
len
);
void
MD5Final
(
unsigned
char
digest
[
16
],
struct
MD5Context
*
context
);
void
MD5Transform
(
u32
buf
[
4
],
u32
const
in
[
16
]);
void
md5_init
(
struct
md5_context
*
ctx
);
void
md5_update
(
struct
md5_context
*
ctx
,
const
byte
*
buf
,
uint
len
);
byte
*
md5_final
(
struct
md5_context
*
ctx
);
/*
* HMAC-MD5
*/
struct
md5_hmac_context
{
struct
md5_context
ictx
;
struct
md5_context
octx
;
};
void
md5_hmac_init
(
struct
md5_hmac_context
*
ctx
,
const
byte
*
key
,
size_t
keylen
);
void
md5_hmac_update
(
struct
md5_hmac_context
*
ctx
,
const
byte
*
buf
,
size_t
buflen
);
byte
*
md5_hmac_final
(
struct
md5_hmac_context
*
ctx
);
#endif
/*
!
MD5_H */
#endif
/*
_BIRD_
MD5_H
_
*/
proto/ospf/packet.c
View file @
33b4f40a
...
...
@@ -11,6 +11,7 @@
#include "ospf.h"
#include "nest/password.h"
#include "lib/md5.h"
#include "lib/socket.h"
void
ospf_pkt_fill_hdr
(
struct
ospf_iface
*
ifa
,
void
*
buf
,
u8
h_type
)
...
...
@@ -108,11 +109,11 @@ ospf_pkt_finalize(struct ospf_iface *ifa, struct ospf_packet *pkt)
char
password
[
OSPF_AUTH_CRYPT_SIZE
];
strncpy
(
password
,
passwd
->
password
,
sizeof
(
password
));
struct
MD5C
ontext
ctx
t
;
MD5I
nit
(
&
ctx
t
);
MD5U
pdate
(
&
ctx
t
,
(
char
*
)
pkt
,
plen
);
MD5U
pdate
(
&
ctx
t
,
password
,
OSPF_AUTH_CRYPT_SIZE
);
MD5Final
(
tail
,
&
ctxt
);
struct
md5_c
ontext
ctx
;
md5_i
nit
(
&
ctx
);
md5_u
pdate
(
&
ctx
,
(
char
*
)
pkt
,
plen
);
md5_u
pdate
(
&
ctx
,
password
,
OSPF_AUTH_CRYPT_SIZE
);
memcpy
((
byte
*
)
tail
,
md5_final
(
&
ctx
),
MD5_SIZE
);
break
;
default:
...
...
@@ -174,19 +175,17 @@ ospf_pkt_checkauth(struct ospf_neighbor *n, struct ospf_iface *ifa, struct ospf_
if
(
!
pass
)
DROP
(
"no suitable password found"
,
auth
->
md5
.
keyid
);
void
*
tail
=
((
void
*
)
pkt
)
+
plen
;
char
passwd
[
OSPF_AUTH_CRYPT_SIZE
];
char
md5sum
[
OSPF_AUTH_CRYPT_SIZE
];