iPXE
md5.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25FILE_SECBOOT ( PERMITTED );
26
27/** @file
28 *
29 * MD5 algorithm
30 *
31 */
32
33#include <stdint.h>
34#include <assert.h>
35#include <ipxe/rotate.h>
36#include <ipxe/crypto.h>
37#include <ipxe/md5.h>
38
39/** MD5 variables */
41 /* This layout matches that of struct md5_digest_data */
47} __attribute__ (( packed ));
48
49/** MD5 constants */
50static const uint32_t k[64] = {
51 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a,
52 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
53 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340,
54 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
55 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8,
56 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
57 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa,
58 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
59 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92,
60 0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
61 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
62};
63
64/** MD5 shift amounts */
65static const uint8_t r[4][4] = {
66 { 7, 12, 17, 22 },
67 { 5, 9, 14, 20 },
68 { 4, 11, 16, 23 },
69 { 6, 10, 15, 21 },
70};
71
72/**
73 * f(b,c,d) for steps 0 to 15
74 *
75 * @v v MD5 variables
76 * @ret f f(b,c,d)
77 */
78static uint32_t md5_f_0_15 ( struct md5_variables *v ) {
79 return ( v->d ^ ( v->b & ( v->c ^ v->d ) ) );
80}
81
82/**
83 * f(b,c,d) for steps 16 to 31
84 *
85 * @v v MD5 variables
86 * @ret f f(b,c,d)
87 */
88static uint32_t md5_f_16_31 ( struct md5_variables *v ) {
89 return ( v->c ^ ( v->d & ( v->b ^ v->c ) ) );
90}
91
92/**
93 * f(b,c,d) for steps 32 to 47
94 *
95 * @v v MD5 variables
96 * @ret f f(b,c,d)
97 */
98static uint32_t md5_f_32_47 ( struct md5_variables *v ) {
99 return ( v->b ^ v->c ^ v->d );
100}
101
102/**
103 * f(b,c,d) for steps 48 to 63
104 *
105 * @v v MD5 variables
106 * @ret f f(b,c,d)
107 */
108static uint32_t md5_f_48_63 ( struct md5_variables *v ) {
109 return ( v->c ^ ( v->b | (~v->d) ) );
110}
111
112/** An MD5 step function */
113struct md5_step {
114 /**
115 * Calculate f(b,c,d)
116 *
117 * @v v MD5 variables
118 * @ret f f(b,c,d)
119 */
120 uint32_t ( * f ) ( struct md5_variables *v );
121 /** Coefficient of i in g=ni+m */
123 /** Constant term in g=ni+m */
125};
126
127/** MD5 steps */
128static const struct md5_step md5_steps[4] = {
129 /** 0 to 15 */
130 { .f = md5_f_0_15, .coefficient = 1, .constant = 0 },
131 /** 16 to 31 */
132 { .f = md5_f_16_31, .coefficient = 5, .constant = 1 },
133 /** 32 to 47 */
134 { .f = md5_f_32_47, .coefficient = 3, .constant = 5 },
135 /** 48 to 63 */
136 { .f = md5_f_48_63, .coefficient = 7, .constant = 0 },
137};
138
139/** MD5 initial digest values */
140static const struct md5_digest md5_init = {
141 .h = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }
142};
143
144/**
145 * Calculate MD5 digest of accumulated data
146 *
147 * @v dd Digest and data block
148 * @v digest Copy of current digest value
149 */
150static void md5_compress ( struct md5_digest_data *dd,
151 const struct md5_digest *digest ) {
152 union {
153 struct md5_digest_data dd;
154 struct md5_variables v;
155 } *u = container_of ( dd, typeof ( *u ), dd );
156 struct md5_variables *v = &u->v;
157 const struct md5_step *step;
158 uint32_t *a = &v->a;
159 uint32_t *b = &v->b;
160 uint32_t *c = &v->c;
161 uint32_t *d = &v->d;
162 uint32_t *w = v->w;
163 uint32_t f;
164 uint32_t g;
165 uint32_t temp;
166 unsigned int round;
167 unsigned int i;
168
169 /* Sanity checks */
170 build_assert ( &u->dd.digest.h[0] == a );
171 build_assert ( &u->dd.digest.h[1] == b );
172 build_assert ( &u->dd.digest.h[2] == c );
173 build_assert ( &u->dd.digest.h[3] == d );
174 build_assert ( &u->dd.data.dword[0] == w );
175 build_assert ( sizeof ( u->dd ) == sizeof ( u->v ) );
176
177 /* Main loop */
178 for ( i = 0 ; i < 64 ; i++ ) {
179 round = ( i / 16 );
180 step = &md5_steps[round];
181 f = step->f ( v );
182 g = ( ( ( step->coefficient * i ) + step->constant ) % 16 );
183 temp = *d;
184 *d = *c;
185 *c = *b;
186 *b = ( *b + rol32 ( ( *a + f + k[i] + w[g] ),
187 r[round][ i % 4 ] ) );
188 *a = temp;
189 DBGC2 ( &md5_algorithm, "%2d : %08x %08x %08x %08x\n",
190 i, *a, *b, *c, *d );
191 }
192
193 /* Add chunk to hash */
194 for ( i = 0 ; i < 4 ; i++ )
195 dd->digest.h[i] += digest->h[i];
196}
197
198/** MD5 algorithm */
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition acpi.c:48
unsigned int uint32_t
Definition stdint.h:12
unsigned char uint8_t
Definition stdint.h:10
Assertions.
#define build_assert(condition)
Assert a condition at build time (after dead code elimination).
Definition assert.h:88
union @104331263140136355135267063077374276003064103115 u
#define DBGC2(...)
Definition compiler.h:547
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:921
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:951
#define __attribute__(x)
Definition compiler.h:10
#define __LITTLE_ENDIAN
Constant representing little-endian byte order.
Definition endian.h:13
Cryptographic API.
static const uint8_t r[3][4]
MD4 shift amounts.
Definition md4.c:50
static const struct md5_digest md5_init
MD5 initial digest values.
Definition md5.c:140
static const struct md5_step md5_steps[4]
MD5 steps.
Definition md5.c:128
static uint32_t md5_f_0_15(struct md5_variables *v)
f(b,c,d) for steps 0 to 15
Definition md5.c:78
static uint32_t md5_f_32_47(struct md5_variables *v)
f(b,c,d) for steps 32 to 47
Definition md5.c:98
static void md5_compress(struct md5_digest_data *dd, const struct md5_digest *digest)
Calculate MD5 digest of accumulated data.
Definition md5.c:150
static uint32_t md5_f_48_63(struct md5_variables *v)
f(b,c,d) for steps 48 to 63
Definition md5.c:108
static uint32_t md5_f_16_31(struct md5_variables *v)
f(b,c,d) for steps 16 to 31
Definition md5.c:88
static const uint32_t k[64]
MD5 constants.
Definition md5.c:50
MD5 algorithm.
struct digest_algorithm md5_algorithm
#define MD5_DIGEST_SIZE
MD5 digest size.
Definition md5.h:57
#define MDHASH_ALGORITHM(_name, _digest, _compress, _byteorder, _dd, _init, _digestsize)
Define a Merkle-Damgård hash algorithm.
Definition mdhash.h:137
void step(void)
Single-step a single process.
Definition process.c:99
Bit operations.
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
MD5 digest and data block.
Definition md5.h:43
struct md5_digest digest
Digest of data already processed.
Definition md5.h:45
An MD5 digest.
Definition md5.h:18
uint32_t h[4]
Hash output.
Definition md5.h:20
An MD5 step function.
Definition md5.c:113
uint8_t constant
Constant term in g=ni+m.
Definition md5.c:124
uint32_t(* f)(struct md5_variables *v)
Calculate f(b,c,d).
Definition md5.c:120
uint8_t coefficient
Coefficient of i in g=ni+m.
Definition md5.c:122
MD5 variables.
Definition md5.c:40
uint32_t d
Definition md5.c:45
uint32_t w[16]
Definition md5.c:46
uint32_t b
Definition md5.c:43
uint32_t a
Definition md5.c:42
uint32_t c
Definition md5.c:44
static u32 rol32(u32 v, int bits)
Rotate 32-bit value left.
Definition wpa_tkip.c:174