blob: 0120bcb72ddce2ed1f7b9b61f0ef7125e62ff17c [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001/*
2 * Copyright (c) 2020 MediaTek Inc.
3 *
4 * Use of this source code is governed by a MIT-style
5 * license that can be found in the LICENSE file or at
6 * https://opensource.org/licenses/MIT
7 */
8
9#include <string.h>
10#include <sys/types.h>
11#include "sha256.h"
12
13#define htobe64 __builtin_bswap64
14
15typedef unsigned int __be32;
16typedef unsigned long long __be64;
17
18extern void sha256_block_data_order(u32 *digest, const void *data,
19 unsigned int num_blks);
20
21int sha256_start(struct sha256_context *s_ctx)
22{
23 struct sha256_context *sctx = s_ctx;
24 if(NULL ==s_ctx) return -1;
25 sctx->state[0] = 0x6a09e667UL;
26 sctx->state[1] = 0xbb67ae85UL;
27 sctx->state[2] = 0x3c6ef372UL;
28 sctx->state[3] = 0xa54ff53aUL;
29 sctx->state[4] = 0x510e527fUL;
30 sctx->state[5] = 0x9b05688cUL;
31 sctx->state[6] = 0x1f83d9abUL;
32 sctx->state[7] = 0x5be0cd19UL;
33 sctx->count = 0;
34
35 return 0;
36}
37
38static inline int sha256_padding(struct sha256_context *s_ctx)
39{
40 struct sha256_context *sctx = (s_ctx);
41 const unsigned int bit_offset = SHA256_BLOCK_SIZE - sizeof(__be64);
42 __be64 *bits = (__be64 *)(sctx->buf + bit_offset);
43 unsigned int non_block_align = sctx->count % SHA256_BLOCK_SIZE;
44
45 sctx->buf[non_block_align++] = 0x80;
46 if (non_block_align > bit_offset) {
47 memset(sctx->buf + non_block_align, 0x0, SHA256_BLOCK_SIZE - non_block_align);
48 sha256_block_data_order((u32*)sctx, sctx->buf, 1);
49 non_block_align = 0;
50 }
51
52 memset(sctx->buf + non_block_align, 0x0, bit_offset - non_block_align);
53 *bits = __builtin_bswap64(sctx->count << 3);
54 sha256_block_data_order((u32*)sctx, sctx->buf, 1);
55
56 return 0;
57}
58
59static inline void u32_split_u8(u32 val, u8 *p)
60{
61 *p++ = val >> 24;
62 *p++ = val >> 16;
63 *p++ = val >> 8;
64 *p++ = val;
65}
66
67int sha256_process(struct sha256_context *s_ctx, const u8 *input,
68 unsigned int len)
69{
70 struct sha256_context *sctx = s_ctx;
71 int block_num;
72 unsigned int non_block_align;
73 int fill;
74
75 if (s_ctx == NULL)
76 return -1;
77 non_block_align = sctx->count % SHA256_BLOCK_SIZE;
78 fill = SHA256_BLOCK_SIZE - non_block_align;
79 sctx->count += len;
80
81 if ((non_block_align + len) >= SHA256_BLOCK_SIZE) {
82 if (non_block_align) {
83 memcpy(sctx->buf + non_block_align, input, fill);
84 sha256_block_data_order((u32*)sctx, sctx->buf, 1);
85 input += fill;
86 len -= fill;
87 }
88
89 block_num = len / SHA256_BLOCK_SIZE;
90 len %= SHA256_BLOCK_SIZE;
91
92 if (block_num) {
93 sha256_block_data_order((u32*)sctx, input, block_num);
94 input += block_num * SHA256_BLOCK_SIZE;
95 }
96 non_block_align = 0;
97 }
98 if (len)
99 memcpy(sctx->buf + non_block_align, input, len);
100
101 return 0;
102}
103
104int sha256_end(struct sha256_context *s_ctx, u8 *out)
105{
106 unsigned int digest_size = 32;
107 struct sha256_context *sctx = s_ctx;
108 __be32 *digest = (__be32 *)out;
109 int i;
110
111 sha256_padding(sctx);
112
113 for (i = 0; digest_size > 0; i++, digest_size -= sizeof(__be32))
114 u32_split_u8(sctx->state[i],(u8*)digest++);
115
116 *sctx = (struct sha256_context) {};
117 return 0;
118
119}
120
121int sha256_hash(const void *input, int len, u8 *output)
122{
123 struct sha256_context s_ctx;
124 memset((void*)&s_ctx, 0, sizeof(s_ctx));
125 sha256_start(&s_ctx);
126 sha256_process(&s_ctx,input,len);
127 sha256_end(&s_ctx,output);
128 return 0;
129}