blob: b0cd8f34a621521ec768205a4e8c7455fbca9270 [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) {
28 uint32_t tmp = *p++ << 24;
29 tmp |= *p++ << 16;
30 tmp |= *p++ << 8;
31 tmp |= *p++;
32 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,
76 SHA_DIGEST_SIZE
77};
78
79void SHA_init(SHA_CTX* ctx) {
80 ctx->f = &SHA_VTAB;
81 ctx->state[0] = 0x67452301;
82 ctx->state[1] = 0xEFCDAB89;
83 ctx->state[2] = 0x98BADCFE;
84 ctx->state[3] = 0x10325476;
85 ctx->state[4] = 0xC3D2E1F0;
86 ctx->count = 0;
87}
88
89
nagendra modadugu810f8b82016-10-18 15:07:43 -070090void SHA_update(SHA_CTX* ctx, const void* data, size_t len) {
nagendra modadugu4fae5422016-05-10 16:11:54 -070091 unsigned int i = (unsigned int)(ctx->count & 63);
92 const uint8_t* p = (const uint8_t*)data;
93
94 ctx->count += len;
95
96 while (len--) {
97 ctx->buf[i++] = *p++;
98 if (i == 64) {
99 SHA1_Transform(ctx);
100 i = 0;
101 }
102 }
103}
104
105
106const uint8_t* SHA_final(SHA_CTX* ctx) {
107 uint8_t *p = ctx->buf;
108 uint64_t cnt = ctx->count * 8;
109 int i;
110
111 SHA_update(ctx, (uint8_t*)"\x80", 1);
112 while ((ctx->count & 63) != 56) {
113 SHA_update(ctx, (uint8_t*)"\0", 1);
114 }
115 for (i = 0; i < 8; ++i) {
116 uint8_t tmp = (uint8_t) (cnt >> 56);
117 cnt <<= 8;
118 SHA_update(ctx, &tmp, 1);
119 }
120
121 for (i = 0; i < 5; i++) {
122 uint32_t tmp = ctx->state[i];
123 *p++ = (uint8_t)(tmp >> 24);
124 *p++ = (uint8_t)(tmp >> 16);
125 *p++ = (uint8_t)(tmp >> 8);
126 *p++ = (uint8_t)(tmp >> 0);
127 }
128
129 return ctx->buf;
130}
131
132/* Convenience function */
nagendra modadugu810f8b82016-10-18 15:07:43 -0700133const uint8_t* SHA_hash(const void* data, size_t len, uint8_t* digest) {
nagendra modadugu4fae5422016-05-10 16:11:54 -0700134 SHA_CTX ctx;
135 SHA_init(&ctx);
136 SHA_update(&ctx, data, len);
137 memcpy(digest, SHA_final(&ctx), SHA_DIGEST_SIZE);
138 return digest;
139}