Mercurial > hg > toybox
comparison toys/sha1sum.c @ 192:8c0809cee2b0
Minor cleanups to sha1sum.
author | Rob Landley <rob@landley.net> |
---|---|
date | Mon, 03 Dec 2007 19:59:34 -0600 |
parents | c983a0af6d4e |
children | d4176f3f3835 |
comparison
equal
deleted
inserted
replaced
191:7f55c59f5122 | 192:8c0809cee2b0 |
---|---|
1 /* | 1 /* |
2 * Copyright 2007 Rob Landley <rob@landley.net> | 2 * Copyright 2007 Rob Landley <rob@landley.net> |
3 * | 3 * |
4 * Based on the public domain SHA-1 in C by Steve Reid <steve@edmweb.com> | 4 * Based on the public domain SHA-1 in C by Steve Reid <steve@edmweb.com> |
5 * from http://www.mirrors.wiretapped.net/security/cryptography/hashes/sha1/ | 5 * from http://www.mirrors.wiretapped.net/security/cryptography/hashes/sha1/ |
6 * | |
7 * Not in SUSv3. | |
6 */ | 8 */ |
7 | 9 |
8 #include <toys.h> | 10 #include <toys.h> |
9 | 11 |
10 struct sha1 { | 12 struct sha1 { |
15 unsigned char c[64]; | 17 unsigned char c[64]; |
16 uint32_t i[16]; | 18 uint32_t i[16]; |
17 } buffer; | 19 } buffer; |
18 }; | 20 }; |
19 | 21 |
20 void sha1_init(struct sha1 *this); | 22 static void sha1_init(struct sha1 *this); |
21 void sha1_transform(struct sha1 *this); | 23 static void sha1_transform(struct sha1 *this); |
22 void sha1_update(struct sha1 *this, char *data, unsigned int len); | 24 static void sha1_update(struct sha1 *this, char *data, unsigned int len); |
23 void sha1_final(struct sha1 *this, char digest[20]); | 25 static void sha1_final(struct sha1 *this, char digest[20]); |
24 | 26 |
25 #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) | 27 #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) |
26 | 28 |
27 /* blk0() and blk() perform the initial expand. */ | 29 // blk0() and blk() perform the initial expand. |
28 /* The idea of expanding during the round function comes from SSLeay */ | 30 // The idea of expanding during the round function comes from SSLeay |
29 #if 1 | 31 #if 1 |
30 #define blk0(i) (block[i] = (rol(block[i],24)&0xFF00FF00) \ | 32 #define blk0(i) (block[i] = (rol(block[i],24)&0xFF00FF00) \ |
31 |(rol(block[i],8)&0x00FF00FF)) | 33 |(rol(block[i],8)&0x00FF00FF)) |
32 #else // big endian? | 34 #else // big endian? |
33 #define blk0(i) block[i] | 35 #define blk0(i) block[i] |
35 #define blk(i) (block[i&15] = rol(block[(i+13)&15]^block[(i+8)&15] \ | 37 #define blk(i) (block[i&15] = rol(block[(i+13)&15]^block[(i+8)&15] \ |
36 ^block[(i+2)&15]^block[i&15],1)) | 38 ^block[(i+2)&15]^block[i&15],1)) |
37 | 39 |
38 static const uint32_t rconsts[]={0x5A827999,0x6ED9EBA1,0x8F1BBCDC,0xCA62C1D6}; | 40 static const uint32_t rconsts[]={0x5A827999,0x6ED9EBA1,0x8F1BBCDC,0xCA62C1D6}; |
39 | 41 |
40 /* Hash a single 512-bit block. This is the core of the algorithm. */ | 42 // Hash a single 512-bit block. This is the core of the algorithm. |
41 | 43 |
42 void sha1_transform(struct sha1 *this) | 44 static void sha1_transform(struct sha1 *this) |
43 { | 45 { |
44 int i, j, k, count; | 46 int i, j, k, count; |
45 uint32_t *block = this->buffer.i; | 47 uint32_t *block = this->buffer.i; |
46 uint32_t *rot[5], *temp; | 48 uint32_t *rot[5], *temp; |
47 | 49 |
48 /* Copy context->state[] to working vars */ | 50 // Copy context->state[] to working vars |
49 for (i=0; i<5; i++) { | 51 for (i=0; i<5; i++) { |
50 this->oldstate[i] = this->state[i]; | 52 this->oldstate[i] = this->state[i]; |
51 rot[i] = this->state + i; | 53 rot[i] = this->state + i; |
52 } | 54 } |
53 /* 4 rounds of 20 operations each. */ | 55 // 4 rounds of 20 operations each. |
54 for (i=count=0; i<4; i++) { | 56 for (i=count=0; i<4; i++) { |
55 for (j=0; j<20; j++) { | 57 for (j=0; j<20; j++) { |
56 uint32_t work; | 58 uint32_t work; |
57 | 59 |
58 work = *rot[2] ^ *rot[3]; | 60 work = *rot[2] ^ *rot[3]; |
72 for (k=4; k; k--) rot[k] = rot[k-1]; | 74 for (k=4; k; k--) rot[k] = rot[k-1]; |
73 *rot = temp; | 75 *rot = temp; |
74 count++; | 76 count++; |
75 } | 77 } |
76 } | 78 } |
77 /* Add the previous values of state[] */ | 79 // Add the previous values of state[] |
78 for (i=0; i<5; i++) this->state[i] += this->oldstate[i]; | 80 for (i=0; i<5; i++) this->state[i] += this->oldstate[i]; |
79 } | 81 } |
80 | 82 |
81 | 83 |
82 /* SHA1Init - Initialize new context */ | 84 // Initialize a struct sha1. |
83 | 85 |
84 void sha1_init(struct sha1 *this) | 86 static void sha1_init(struct sha1 *this) |
85 { | 87 { |
86 /* SHA1 initialization constants */ | 88 /* SHA1 initialization constants */ |
87 this->state[0] = 0x67452301; | 89 this->state[0] = 0x67452301; |
88 this->state[1] = 0xEFCDAB89; | 90 this->state[1] = 0xEFCDAB89; |
89 this->state[2] = 0x98BADCFE; | 91 this->state[2] = 0x98BADCFE; |
90 this->state[3] = 0x10325476; | 92 this->state[3] = 0x10325476; |
91 this->state[4] = 0xC3D2E1F0; | 93 this->state[4] = 0xC3D2E1F0; |
92 this->count = 0; | 94 this->count = 0; |
93 } | 95 } |
94 | 96 |
95 /* Run your data through this function. */ | 97 // Fill the 64-byte working buffer and call sha1_transform() when full. |
96 | 98 |
97 void sha1_update(struct sha1 *this, char *data, unsigned int len) | 99 void sha1_update(struct sha1 *this, char *data, unsigned int len) |
98 { | 100 { |
99 unsigned int i, j; | 101 unsigned int i, j; |
100 | 102 |
114 } else i = 0; | 116 } else i = 0; |
115 // Grab remaining chunk | 117 // Grab remaining chunk |
116 memcpy(this->buffer.c + j, data + i, len - i); | 118 memcpy(this->buffer.c + j, data + i, len - i); |
117 } | 119 } |
118 | 120 |
119 /* Add padding and return the message digest. */ | 121 // Add padding and return the message digest. |
120 | 122 |
121 void sha1_final(struct sha1 *this, char digest[20]) | 123 void sha1_final(struct sha1 *this, char digest[20]) |
122 { | 124 { |
123 uint64_t count = this->count << 3; | 125 uint64_t count = this->count << 3; |
124 unsigned int i; | 126 unsigned int i; |
125 char buf; | 127 char buf; |
126 | 128 |
127 // End the message by appending a "1" bit to the data, ending with the | 129 // End the message by appending a "1" bit to the data, ending with the |
128 // message size (in bits, big endian), and adding enough zero bits in | 130 // message size (in bits, big endian), and adding enough zero bits in |
129 // between to pad to the end of the next 64-byte frame. Since our input | 131 // between to pad to the end of the next 64-byte frame. |
130 // up to now has been in whole bytes, we can deal with bytes here too. | 132 // |
133 // Since our input up to now has been in whole bytes, we can deal with | |
134 // bytes here too. | |
131 | 135 |
132 buf = 0x80; | 136 buf = 0x80; |
133 do { | 137 do { |
134 sha1_update(this, &buf, 1); | 138 sha1_update(this, &buf, 1); |
135 buf = 0; | 139 buf = 0; |
138 this->buffer.c[56+i] = count >> (8*(7-i)); | 142 this->buffer.c[56+i] = count >> (8*(7-i)); |
139 sha1_transform(this); | 143 sha1_transform(this); |
140 | 144 |
141 for (i = 0; i < 20; i++) | 145 for (i = 0; i < 20; i++) |
142 digest[i] = this->state[i>>2] >> ((3-(i & 3)) * 8); | 146 digest[i] = this->state[i>>2] >> ((3-(i & 3)) * 8); |
143 /* Wipe variables */ | 147 // Wipe variables. Cryptogropher paranoia. |
144 memset(this, 0, sizeof(struct sha1)); | 148 memset(this, 0, sizeof(struct sha1)); |
145 } | 149 } |
146 | 150 |
147 // Callback for loopfiles() | 151 // Callback for loopfiles() |
148 | 152 |