libaaruformat
1.0
Aaru Data Preservation Suite - Format Library
Toggle main menu visibility
Loading...
Searching...
No Matches
sha1.c
Go to the documentation of this file.
1
/*
2
* Public domain / MIT SHA-1 implementation for libaaruformat.
3
*
4
* This implementation is derived from the FIPS PUB 180-1 specification and
5
* other public domain reference implementations; released as public domain.
6
* If public domain dedication is not recognized, you may use it under the
7
* MIT license terms (see header in sha1.h).
8
*/
9
#include <stdbool.h>
10
#include <stdint.h>
11
#include <stdio.h>
12
#include <string.h>
13
14
#include "
decls.h
"
15
#include "
sha1.h
"
16
17
#ifndef AARU_LOCAL
18
#define AARU_LOCAL static
19
#endif
20
21
/* Rotate-left 32-bit */
22
#if defined(_MSC_VER)
23
#define ROTL32(v, n) _rotl(v, n)
24
#else
25
#define ROTL32(v, n) (((v) << (n)) | ((v) >> (32 - (n))))
26
#endif
27
28
/* SHA-1 logical functions */
29
#define F0(b, c, d) (((b) & (c)) | (~(b) & (d)))
30
#define F1(b, c, d) ((b) ^ (c) ^ (d))
31
#define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
32
#define F3(b, c, d) ((b) ^ (c) ^ (d))
33
34
AARU_EXPORT
void
AARU_CALL
aaruf_sha1_init
(
sha1_ctx
*ctx)
35
{
36
ctx->
state
[0] = 0x67452301UL;
37
ctx->
state
[1] = 0xEFCDAB89UL;
38
ctx->
state
[2] = 0x98BADCFEUL;
39
ctx->
state
[3] = 0x10325476UL;
40
ctx->
state
[4] = 0xC3D2E1F0UL;
41
ctx->
count
= 0ULL;
42
memset(ctx->
buffer
, 0,
sizeof
(ctx->
buffer
));
43
}
44
45
AARU_LOCAL
void
sha1_transform
(uint32_t state[5],
const
uint8_t block[64])
46
{
47
uint32_t W[80];
48
49
/* Prepare message schedule */
50
for
(
int
t = 0; t < 16; t++)
51
{
52
W[t] = ((uint32_t)block[t * 4] << 24) | ((uint32_t)block[t * 4 + 1] << 16) | ((uint32_t)block[t * 4 + 2] << 8) |
53
((uint32_t)block[t * 4 + 3]);
54
}
55
for
(
int
t = 16; t < 80; t++) { W[t] =
ROTL32
(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1); }
56
57
uint32_t a = state[0];
58
uint32_t b = state[1];
59
uint32_t c = state[2];
60
uint32_t d = state[3];
61
uint32_t e = state[4];
62
63
for
(
int
t = 0; t < 80; t++)
64
{
65
uint32_t temp;
66
if
(t < 20)
67
temp =
ROTL32
(a, 5) +
F0
(b, c, d) + e + W[t] + 0x5A827999UL;
68
else
if
(t < 40)
69
temp =
ROTL32
(a, 5) +
F1
(b, c, d) + e + W[t] + 0x6ED9EBA1UL;
70
else
if
(t < 60)
71
temp =
ROTL32
(a, 5) +
F2
(b, c, d) + e + W[t] + 0x8F1BBCDCUL;
72
else
73
temp =
ROTL32
(a, 5) +
F3
(b, c, d) + e + W[t] + 0xCA62C1D6UL;
74
75
e = d;
76
d = c;
77
c =
ROTL32
(b, 30);
78
b = a;
79
a = temp;
80
}
81
82
state[0] += a;
83
state[1] += b;
84
state[2] += c;
85
state[3] += d;
86
state[4] += e;
87
}
88
89
AARU_EXPORT
void
AARU_CALL
aaruf_sha1_update
(
sha1_ctx
*ctx,
const
void
*data_ptr,
unsigned
long
len)
90
{
91
const
uint8_t *data = (
const
uint8_t *)data_ptr;
92
if
(len == 0)
return
;
93
94
/* Number of bytes mod 64 currently in buffer */
95
uint32_t buffer_bytes = (uint32_t)((ctx->
count
>> 3) & 0x3F);
96
97
/* Update bit count */
98
ctx->
count
+= (uint64_t)len << 3;
99
100
uint32_t free_bytes = 64 - buffer_bytes;
101
102
if
(len >= free_bytes)
103
{
104
/* Fill buffer and compress */
105
memcpy(ctx->
buffer
+ buffer_bytes, data, free_bytes);
106
sha1_transform
(ctx->
state
, ctx->
buffer
);
107
data += free_bytes;
108
len -= free_bytes;
109
110
/* Process direct blocks */
111
while
(len >= 64)
112
{
113
sha1_transform
(ctx->
state
, data);
114
data += 64;
115
len -= 64;
116
}
117
buffer_bytes = 0;
118
}
119
120
/* Buffer the remaining */
121
if
(len > 0) memcpy(ctx->
buffer
+ buffer_bytes, data, len);
122
}
123
124
AARU_EXPORT
void
AARU_CALL
aaruf_sha1_final
(
sha1_ctx
*ctx,
unsigned
char
*digest)
125
{
126
uint8_t pad[64];
127
memset(pad, 0,
sizeof
(pad));
128
pad[0] = 0x80;
129
130
uint8_t length_be[8];
131
uint64_t bits = ctx->
count
;
132
for
(
int
i = 0; i < 8; i++) { length_be[7 - i] = (uint8_t)(bits >> (i * 8)); }
133
134
/* Current bytes mod 64 */
135
uint32_t buffer_bytes = (uint32_t)((ctx->
count
>> 3) & 0x3F);
136
137
uint32_t pad_len = (buffer_bytes < 56) ? (56 - buffer_bytes) : (120 - buffer_bytes);
138
139
aaruf_sha1_update
(ctx, pad, pad_len);
140
aaruf_sha1_update
(ctx, length_be, 8);
141
142
/* Output digest big-endian */
143
for
(
int
i = 0; i < 5; i++)
144
{
145
digest[i * 4] = (uint8_t)(ctx->
state
[i] >> 24);
146
digest[i * 4 + 1] = (uint8_t)(ctx->
state
[i] >> 16);
147
digest[i * 4 + 2] = (uint8_t)(ctx->
state
[i] >> 8);
148
digest[i * 4 + 3] = (uint8_t)(ctx->
state
[i]);
149
}
150
151
/* Wipe context (except state in case reused) */
152
memset(ctx->
buffer
, 0,
sizeof
(ctx->
buffer
));
153
}
154
155
AARU_EXPORT
void
AARU_CALL
aaruf_sha1_buffer
(
const
void
*data,
unsigned
long
size,
unsigned
char
*result)
156
{
157
sha1_ctx
ctx;
158
aaruf_sha1_init
(&ctx);
159
aaruf_sha1_update
(&ctx, data, size);
160
aaruf_sha1_final
(&ctx, result);
161
}
decls.h
AARU_CALL
#define AARU_CALL
Definition
decls.h:46
aaruf_sha1_final
void aaruf_sha1_final(sha1_ctx *ctx, unsigned char *result)
Definition
sha1.c:124
aaruf_sha1_buffer
void aaruf_sha1_buffer(const void *data, unsigned long size, unsigned char *result)
Definition
sha1.c:155
AARU_LOCAL
#define AARU_LOCAL
Definition
decls.h:56
AARU_EXPORT
#define AARU_EXPORT
Definition
decls.h:55
aaruf_sha1_init
void aaruf_sha1_init(sha1_ctx *ctx)
Definition
sha1.c:34
aaruf_sha1_update
void aaruf_sha1_update(sha1_ctx *ctx, const void *data, unsigned long size)
Definition
sha1.c:89
ROTL32
#define ROTL32(x, s)
Definition
md5.c:132
F2
#define F2(b, c, d)
Definition
sha1.c:31
F1
#define F1(b, c, d)
Definition
sha1.c:30
F3
#define F3(b, c, d)
Definition
sha1.c:32
F0
#define F0(b, c, d)
Definition
sha1.c:29
sha1_transform
static void sha1_transform(uint32_t state[5], const uint8_t block[64])
Definition
sha1.c:45
sha1.h
sha1_ctx
Definition
sha1.h:43
sha1_ctx::count
uint64_t count
Definition
sha1.h:45
sha1_ctx::buffer
uint8_t buffer[64]
Definition
sha1.h:46
sha1_ctx::state
uint32_t state[5]
Definition
sha1.h:44
src
checksum
sha1.c
Generated by
1.18.0