1 /* Copyright (c) 2014 The Chromium OS Authors. All rights reserved. 2 * Use of this source code is governed by a BSD-style license that can be 3 * found in the LICENSE file. 4 * 5 * SHA-1 implementation largely based on libmincrypt in the the Android 6 * Open Source Project (platorm/system/core.git/libmincrypt/sha.c 7 */ 8 9 #include "2sysincludes.h" 10 #include "2common.h" 11 #include "2sha.h" 12 13 /* 14 * Some machines lack byteswap.h and endian.h. These have to use the 15 * slower code, even if they're little-endian. 16 */ 17 18 #if defined(HAVE_ENDIAN_H) && defined(HAVE_LITTLE_ENDIAN) 19 20 /* 21 * This version is about 28% faster than the generic version below, 22 * but assumes little-endianness. 23 */ 24 static uint32_t ror27(uint32_t val) 25 { 26 return (val >> 27) | (val << 5); 27 } 28 29 static uint32_t ror2(uint32_t val) 30 { 31 return (val >> 2) | (val << 30); 32 } 33 34 static uint32_t ror31(uint32_t val) 35 { 36 return (val >> 31) | (val << 1); 37 } 38 39 static void sha1_transform(struct vb2_sha1_context *ctx) 40 { 41 /* Note that this array uses 80*4=320 bytes of stack */ 42 uint32_t W[80]; 43 register uint32_t A, B, C, D, E; 44 int t; 45 46 A = ctx->state[0]; 47 B = ctx->state[1]; 48 C = ctx->state[2]; 49 D = ctx->state[3]; 50 E = ctx->state[4]; 51 52 #define SHA_F1(A,B,C,D,E,t) \ 53 E += ror27(A) + \ 54 (W[t] = bswap_32(ctx->buf.w[t])) + \ 55 (D^(B&(C^D))) + 0x5A827999; \ 56 B = ror2(B); 57 58 for (t = 0; t < 15; t += 5) { 59 SHA_F1(A,B,C,D,E,t + 0); 60 SHA_F1(E,A,B,C,D,t + 1); 61 SHA_F1(D,E,A,B,C,t + 2); 62 SHA_F1(C,D,E,A,B,t + 3); 63 SHA_F1(B,C,D,E,A,t + 4); 64 } 65 SHA_F1(A,B,C,D,E,t + 0); /* 16th one, t == 15 */ 66 67 #undef SHA_F1 68 69 #define SHA_F1(A,B,C,D,E,t) \ 70 E += ror27(A) + \ 71 (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \ 72 (D^(B&(C^D))) + 0x5A827999; \ 73 B = ror2(B); 74 75 SHA_F1(E,A,B,C,D,t + 1); 76 SHA_F1(D,E,A,B,C,t + 2); 77 SHA_F1(C,D,E,A,B,t + 3); 78 SHA_F1(B,C,D,E,A,t + 4); 79 80 #undef SHA_F1 81 82 #define SHA_F2(A,B,C,D,E,t) \ 83 E += ror27(A) + \ 84 (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \ 85 (B^C^D) + 0x6ED9EBA1; \ 86 B = ror2(B); 87 88 for (t = 20; t < 40; t += 5) { 89 SHA_F2(A,B,C,D,E,t + 0); 90 SHA_F2(E,A,B,C,D,t + 1); 91 SHA_F2(D,E,A,B,C,t + 2); 92 SHA_F2(C,D,E,A,B,t + 3); 93 SHA_F2(B,C,D,E,A,t + 4); 94 } 95 96 #undef SHA_F2 97 98 #define SHA_F3(A,B,C,D,E,t) \ 99 E += ror27(A) + \ 100 (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \ 101 ((B&C)|(D&(B|C))) + 0x8F1BBCDC; \ 102 B = ror2(B); 103 104 for (; t < 60; t += 5) { 105 SHA_F3(A,B,C,D,E,t + 0); 106 SHA_F3(E,A,B,C,D,t + 1); 107 SHA_F3(D,E,A,B,C,t + 2); 108 SHA_F3(C,D,E,A,B,t + 3); 109 SHA_F3(B,C,D,E,A,t + 4); 110 } 111 112 #undef SHA_F3 113 114 #define SHA_F4(A,B,C,D,E,t) \ 115 E += ror27(A) + \ 116 (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \ 117 (B^C^D) + 0xCA62C1D6; \ 118 B = ror2(B); 119 120 for (; t < 80; t += 5) { 121 SHA_F4(A,B,C,D,E,t + 0); 122 SHA_F4(E,A,B,C,D,t + 1); 123 SHA_F4(D,E,A,B,C,t + 2); 124 SHA_F4(C,D,E,A,B,t + 3); 125 SHA_F4(B,C,D,E,A,t + 4); 126 } 127 128 #undef SHA_F4 129 130 ctx->state[0] += A; 131 ctx->state[1] += B; 132 ctx->state[2] += C; 133 ctx->state[3] += D; 134 ctx->state[4] += E; 135 } 136 137 void vb2_sha1_update(struct vb2_sha1_context *ctx, 138 const uint8_t *data, 139 uint32_t size) 140 { 141 int i = ctx->count % sizeof(ctx->buf); 142 const uint8_t *p = (const uint8_t*)data; 143 144 ctx->count += size; 145 146 while (size > sizeof(ctx->buf) - i) { 147 memcpy(&ctx->buf.b[i], p, sizeof(ctx->buf) - i); 148 size -= sizeof(ctx->buf) - i; 149 p += sizeof(ctx->buf) - i; 150 sha1_transform(ctx); 151 i = 0; 152 } 153 154 while (size--) { 155 ctx->buf.b[i++] = *p++; 156 if (i == sizeof(ctx->buf)) { 157 sha1_transform(ctx); 158 i = 0; 159 } 160 } 161 } 162 163 uint8_t *vb2_sha1_finalize(struct vb2_sha1_context *ctx) 164 { 165 uint32_t cnt = ctx->count * 8; 166 int i; 167 168 vb2_sha1_update(ctx, (uint8_t*)"\x80", 1); 169 while ((ctx->count % sizeof(ctx->buf)) != (sizeof(ctx->buf) - 8)) { 170 vb2_sha1_update(ctx, (uint8_t*)"\0", 1); 171 } 172 173 for (i = 0; i < 8; ++i) { 174 uint8_t tmp = cnt >> ((7 - i) * 8); 175 vb2_sha1_update(ctx, &tmp, 1); 176 } 177 178 for (i = 0; i < 5; i++) { 179 ctx->buf.w[i] = bswap_32(ctx->state[i]); 180 } 181 182 return ctx->buf.b; 183 } 184 185 #else /* #if defined(HAVE_ENDIAN_H) && defined(HAVE_LITTLE_ENDIAN) */ 186 187 #define rol(bits, value) (((value) << (bits)) | ((value) >> (32 - (bits)))) 188 189 static void sha1_transform(struct vb2_sha1_context *ctx) 190 { 191 /* Note that this array uses 80*4=320 bytes of stack */ 192 uint32_t W[80]; 193 uint32_t A, B, C, D, E; 194 uint8_t *p = ctx->buf; 195 int t; 196 197 for(t = 0; t < 16; ++t) { 198 uint32_t tmp = *p++ << 24; 199 tmp |= *p++ << 16; 200 tmp |= *p++ << 8; 201 tmp |= *p++; 202 W[t] = tmp; 203 } 204 205 for(; t < 80; t++) { 206 W[t] = rol(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); 207 } 208 209 A = ctx->state[0]; 210 B = ctx->state[1]; 211 C = ctx->state[2]; 212 D = ctx->state[3]; 213 E = ctx->state[4]; 214 215 for(t = 0; t < 80; t++) { 216 uint32_t tmp = rol(5,A) + E + W[t]; 217 218 if (t < 20) 219 tmp += (D^(B&(C^D))) + 0x5A827999; 220 else if ( t < 40) 221 tmp += (B^C^D) + 0x6ED9EBA1; 222 else if ( t < 60) 223 tmp += ((B&C)|(D&(B|C))) + 0x8F1BBCDC; 224 else 225 tmp += (B^C^D) + 0xCA62C1D6; 226 227 E = D; 228 D = C; 229 C = rol(30,B); 230 B = A; 231 A = tmp; 232 } 233 234 ctx->state[0] += A; 235 ctx->state[1] += B; 236 ctx->state[2] += C; 237 ctx->state[3] += D; 238 ctx->state[4] += E; 239 } 240 241 void vb2_sha1_update(struct vb2_sha1_context *ctx, 242 const uint8_t *data, 243 uint32_t size) 244 { 245 int i = (int)(ctx->count % sizeof(ctx->buf)); 246 const uint8_t* p = (const uint8_t*) data; 247 248 ctx->count += size; 249 250 while (size--) { 251 ctx->buf[i++] = *p++; 252 if (i == sizeof(ctx->buf)) { 253 sha1_transform(ctx); 254 i = 0; 255 } 256 } 257 } 258 259 void vb2_sha1_finalize(struct vb2_sha1_context *ctx, uint8_t *digest) 260 { 261 uint32_t cnt = ctx->count << 3; 262 int i; 263 264 vb2_sha1_update(ctx, (uint8_t*)"\x80", 1); 265 while ((ctx->count % sizeof(ctx->buf)) != (sizeof(ctx->buf) - 8)) { 266 vb2_sha1_update(ctx, (uint8_t*)"\0", 1); 267 } 268 for (i = 0; i < 8; ++i) { 269 uint8_t tmp = (uint8_t)((uint64_t)cnt >> ((7 - i) * 8)); 270 vb2_sha1_update(ctx, &tmp, 1); 271 } 272 273 for (i = 0; i < 5; i++) { 274 uint32_t tmp = ctx->state[i]; 275 *digest++ = (uint8_t)(tmp >> 24); 276 *digest++ = (uint8_t)(tmp >> 16); 277 *digest++ = (uint8_t)(tmp >> 8); 278 *digest++ = (uint8_t)(tmp >> 0); 279 } 280 } 281 282 #endif /* endianness */ 283 284 void vb2_sha1_init(struct vb2_sha1_context *ctx) 285 { 286 ctx->state[0] = 0x67452301; 287 ctx->state[1] = 0xefcdab89; 288 ctx->state[2] = 0x98badcfe; 289 ctx->state[3] = 0x10325476; 290 ctx->state[4] = 0xc3d2e1f0; 291 ctx->count = 0; 292 } 293