blob: 39fa8c990f70e42bb2ee86773f2213fef900a7ff [file] [log] [blame]
nagendra modadugu4fae5422016-05-10 16:11:54 -07001// Copyright 2016 Google Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14#include "cryptoc/sha.h"
15
16#include <string.h>
17#include <stdint.h>
18
19#define rol(bits, value) (((value) << (bits)) | ((value) >> (32 - (bits))))
20
21static void SHA1_Transform(SHA_CTX* ctx) {
22 uint32_t W[80];
23 uint32_t A, B, C, D, E;
24 uint8_t* p = ctx->buf;
25 int t;
26
27 for(t = 0; t < 16; ++t) {
nagendra modadugu793cf592019-10-09 14:07:05 -070028 uint32_t tmp = (uint32_t)(*p++) << 24;
29 tmp |= (uint32_t)(*p++) << 16;
30 tmp |= (uint32_t)(*p++) << 8;
31 tmp |= (uint32_t)(*p++);
nagendra modadugu4fae5422016-05-10 16:11:54 -070032 W[t] = tmp;
33 }
34
35 for(; t < 80; t++) {
36 W[t] = rol(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
37 }
38
39 A = ctx->state[0];
40 B = ctx->state[1];
41 C = ctx->state[2];
42 D = ctx->state[3];
43 E = ctx->state[4];
44
45 for(t = 0; t < 80; t++) {
46 uint32_t tmp = rol(5,A) + E + W[t];
47
48 if (t < 20)
49 tmp += (D^(B&(C^D))) + 0x5A827999;
50 else if ( t < 40)
51 tmp += (B^C^D) + 0x6ED9EBA1;
52 else if ( t < 60)
53 tmp += ((B&C)|(D&(B|C))) + 0x8F1BBCDC;
54 else
55 tmp += (B^C^D) + 0xCA62C1D6;
56
57 E = D;
58 D = C;
59 C = rol(30,B);
60 B = A;
61 A = tmp;
62 }
63
64 ctx->state[0] += A;
65 ctx->state[1] += B;
66 ctx->state[2] += C;
67 ctx->state[3] += D;
68 ctx->state[4] += E;
69}
70
71static const HASH_VTAB SHA_VTAB = {
72 SHA_init,
73 SHA_update,
74 SHA_final,
75 SHA_hash,
nagendra modadugu793cf592019-10-09 14:07:05 -070076 SHA_DIGEST_SIZE,
77#ifdef SHA512_SUPPORT
78 SHA_BLOCK_SIZE,
79#endif
nagendra modadugu4fae5422016-05-10 16:11:54 -070080};
81
82void SHA_init(SHA_CTX* ctx) {
83 ctx->f = &SHA_VTAB;
84 ctx->state[0] = 0x67452301;
85 ctx->state[1] = 0xEFCDAB89;
86 ctx->state[2] = 0x98BADCFE;
87 ctx->state[3] = 0x10325476;
88 ctx->state[4] = 0xC3D2E1F0;
89 ctx->count = 0;
90}
91
92
nagendra modadugu810f8b82016-10-18 15:07:43 -070093void SHA_update(SHA_CTX* ctx, const void* data, size_t len) {
nagendra modadugu4fae5422016-05-10 16:11:54 -070094 unsigned int i = (unsigned int)(ctx->count & 63);
95 const uint8_t* p = (const uint8_t*)data;
96
97 ctx->count += len;
98
99 while (len--) {
100 ctx->buf[i++] = *p++;
101 if (i == 64) {
102 SHA1_Transform(ctx);
103 i = 0;
104 }
105 }
106}
107
108
109const uint8_t* SHA_final(SHA_CTX* ctx) {
110 uint8_t *p = ctx->buf;
nagendra modadugu793cf592019-10-09 14:07:05 -0700111 uint64_t cnt = LITE_LShiftU64(ctx->count, 3);
nagendra modadugu4fae5422016-05-10 16:11:54 -0700112 int i;
113
114 SHA_update(ctx, (uint8_t*)"\x80", 1);
115 while ((ctx->count & 63) != 56) {
116 SHA_update(ctx, (uint8_t*)"\0", 1);
117 }
118 for (i = 0; i < 8; ++i) {
nagendra modadugu793cf592019-10-09 14:07:05 -0700119 uint8_t tmp = (uint8_t) LITE_RShiftU64(cnt, 56);
120 cnt = LITE_LShiftU64(cnt, 8);
nagendra modadugu4fae5422016-05-10 16:11:54 -0700121 SHA_update(ctx, &tmp, 1);
122 }
123
124 for (i = 0; i < 5; i++) {
125 uint32_t tmp = ctx->state[i];
126 *p++ = (uint8_t)(tmp >> 24);
127 *p++ = (uint8_t)(tmp >> 16);
128 *p++ = (uint8_t)(tmp >> 8);
129 *p++ = (uint8_t)(tmp >> 0);
130 }
131
132 return ctx->buf;
133}
134
135/* Convenience function */
nagendra modadugu810f8b82016-10-18 15:07:43 -0700136const uint8_t* SHA_hash(const void* data, size_t len, uint8_t* digest) {
nagendra modadugu4fae5422016-05-10 16:11:54 -0700137 SHA_CTX ctx;
138 SHA_init(&ctx);
139 SHA_update(&ctx, data, len);
140 memcpy(digest, SHA_final(&ctx), SHA_DIGEST_SIZE);
141 return digest;
142}