Home | History | Annotate | Download | only in 2lib
      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