iPXE
sha1.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 * SHA-1 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/sha1.h>
38
39/** SHA-1 variables */
41 /* This layout matches that of struct sha1_digest_data */
47 /* We reuse w[0..15] to construct w[16..79] on demand */
49} __attribute__ (( packed ));
50
51/**
52 * f(a,b,c,d) for steps 0 to 19
53 *
54 * @v v SHA-1 variables
55 * @ret f f(a,b,c,d)
56 */
57static uint32_t sha1_f_0_19 ( struct sha1_variables *v ) {
58 return ( ( v->b & v->c ) | ( (~v->b) & v->d ) );
59}
60
61/**
62 * f(a,b,c,d) for steps 20 to 39 and 60 to 79
63 *
64 * @v v SHA-1 variables
65 * @ret f f(a,b,c,d)
66 */
68 return ( v->b ^ v->c ^ v->d );
69}
70
71/**
72 * f(a,b,c,d) for steps 40 to 59
73 *
74 * @v v SHA-1 variables
75 * @ret f f(a,b,c,d)
76 */
77static uint32_t sha1_f_40_59 ( struct sha1_variables *v ) {
78 return ( ( v->b & v->c ) | ( v->b & v->d ) | ( v->c & v->d ) );
79}
80
81/** An SHA-1 step function */
82struct sha1_step {
83 /**
84 * Calculate f(a,b,c,d)
85 *
86 * @v v SHA-1 variables
87 * @ret f f(a,b,c,d)
88 */
89 uint32_t ( * f ) ( struct sha1_variables *v );
90 /** Constant k */
92};
93
94/** SHA-1 steps */
95static const struct sha1_step sha1_steps[4] = {
96 /** 0 to 19 */
97 { .f = sha1_f_0_19, .k = 0x5a827999 },
98 /** 20 to 39 */
99 { .f = sha1_f_20_39_60_79, .k = 0x6ed9eba1 },
100 /** 40 to 59 */
101 { .f = sha1_f_40_59, .k = 0x8f1bbcdc },
102 /** 60 to 79 */
103 { .f = sha1_f_20_39_60_79, .k = 0xca62c1d6 },
104};
105
106/** SHA-1 initial digest values */
107static const struct sha1_digest sha1_init = {
108 .h = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 }
109};
110
111/**
112 * Calculate SHA-1 digest of accumulated data
113 *
114 * @v dd Digest and data block
115 * @v digest Copy of current digest value
116 */
117static void sha1_compress ( struct sha1_digest_data *dd,
118 const struct sha1_digest *digest ) {
119 union {
120 struct sha1_digest_data dd;
121 struct sha1_variables v;
122 } *u = container_of ( dd, typeof ( *u ), dd );
123 struct sha1_variables *v = &u->v;
124 const struct sha1_step *step;
125 uint32_t *a = &v->a;
126 uint32_t *b = &v->b;
127 uint32_t *c = &v->c;
128 uint32_t *d = &v->d;
129 uint32_t *e = &v->e;
130 uint32_t *w = v->w;
131 uint32_t f;
132 uint32_t k;
133 uint32_t temp;
134 unsigned int i;
135
136 /* Sanity checks */
137 build_assert ( &u->dd.digest.h[0] == a );
138 build_assert ( &u->dd.digest.h[1] == b );
139 build_assert ( &u->dd.digest.h[2] == c );
140 build_assert ( &u->dd.digest.h[3] == d );
141 build_assert ( &u->dd.digest.h[4] == e );
142 build_assert ( &u->dd.data.dword[0] == w );
143 build_assert ( sizeof ( u->dd ) == sizeof ( u->v ) );
144
145 /* Main loop */
146 for ( i = 0 ; i < 80 ; i++ ) {
147 step = &sha1_steps[ i / 20 ];
148 f = step->f ( v );
149 k = step->k;
150 temp = ( rol32 ( *a, 5 ) + f + *e + k + w[ i % 16 ] );
151 *e = *d;
152 *d = *c;
153 *c = rol32 ( *b, 30 );
154 *b = *a;
155 *a = temp;
156 w[ i % 16 ] = rol32 ( ( w[ ( i - 3 ) % 16 ] ^
157 w[ ( i - 8 ) % 16 ] ^
158 w[ ( i - 14 ) % 16 ] ^
159 w[ ( i - 16 ) % 16 ] ), 1 );
160 DBGC2 ( &sha1_algorithm, "%2d : %08x %08x %08x %08x %08x\n",
161 i, *a, *b, *c, *d, *e );
162 }
163
164 /* Add chunk to hash */
165 for ( i = 0 ; i < 5 ; i++ )
166 dd->digest.h[i] += digest->h[i];
167}
168
169/** SHA-1 algorithm */
#define SHA1_DIGEST_SIZE
Definition Tpm20.h:25
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition acpi.c:48
unsigned int uint32_t
Definition stdint.h:12
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 __BIG_ENDIAN
Constant representing big-endian byte order.
Definition endian.h:22
Cryptographic API.
static const uint32_t k[64]
MD5 constants.
Definition md5.c:50
#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.
static uint32_t sha1_f_40_59(struct sha1_variables *v)
f(a,b,c,d) for steps 40 to 59
Definition sha1.c:77
static const struct sha1_step sha1_steps[4]
SHA-1 steps.
Definition sha1.c:95
static uint32_t sha1_f_0_19(struct sha1_variables *v)
f(a,b,c,d) for steps 0 to 19
Definition sha1.c:57
static const struct sha1_digest sha1_init
SHA-1 initial digest values.
Definition sha1.c:107
static uint32_t sha1_f_20_39_60_79(struct sha1_variables *v)
f(a,b,c,d) for steps 20 to 39 and 60 to 79
Definition sha1.c:67
static void sha1_compress(struct sha1_digest_data *dd, const struct sha1_digest *digest)
Calculate SHA-1 digest of accumulated data.
Definition sha1.c:117
SHA-1 algorithm.
struct digest_algorithm sha1_algorithm
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
SHA-1 digest and data block.
Definition sha1.h:43
struct sha1_digest digest
Digest of data already processed.
Definition sha1.h:45
An SHA-1 digest.
Definition sha1.h:18
uint32_t h[5]
Hash output.
Definition sha1.h:20
An SHA-1 step function.
Definition sha1.c:82
uint32_t k
Constant k.
Definition sha1.c:91
uint32_t(* f)(struct sha1_variables *v)
Calculate f(a,b,c,d).
Definition sha1.c:89
SHA-1 variables.
Definition sha1.c:40
uint32_t d
Definition sha1.c:45
uint32_t c
Definition sha1.c:44
uint32_t e
Definition sha1.c:46
uint32_t b
Definition sha1.c:43
uint32_t w[16]
Definition sha1.c:48
uint32_t a
Definition sha1.c:42
static u32 rol32(u32 v, int bits)
Rotate 32-bit value left.
Definition wpa_tkip.c:174