1 /*
2 * This software is
3 * Copyright (c) 2016 JimF
4 * Copyright (c) 2017 magnum
5 * and it is hereby released to the general public under the following terms:
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted.
9 */
10
11 /*
12 * At some point based on "FIPS-180-1 compliant SHA-1 implementation"
13 * Copyright (C) 2006-2010, Brainspark B.V.
14 *
15 * This file is part of PolarSSL (http://www.polarssl.org)
16 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
17 *
18 * All rights reserved.
19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * You should have received a copy of the GNU General Public License along
31 * with this program; if not, write to the Free Software Foundation, Inc.,
32 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
33 */
34
35 #ifndef _OPENCL_SHA1_CTX_H
36 #define _OPENCL_SHA1_CTX_H
37
38 /* this file is ONLY made to be built by the GPU code in JtR */
39
40 #include "opencl_misc.h"
41 #include "opencl_sha1.h"
42
43 /*
44 * SHA-1 context setup
45 */
46
47 typedef struct {
48 uint total; /* number of bytes processed */
49 uint state[5]; /* intermediate digest state */
50 uchar buffer[64]; /* data block being processed */
51 } SHA_CTX;
52
53 #ifndef __MESA__
54 inline
55 #endif
SHA1_Init(SHA_CTX * ctx)56 void SHA1_Init(SHA_CTX *ctx) {
57 ctx->total = 0;
58
59 ctx->state[0] = INIT_A;
60 ctx->state[1] = INIT_B;
61 ctx->state[2] = INIT_C;
62 ctx->state[3] = INIT_D;
63 ctx->state[4] = INIT_E;
64 }
65
66 #ifndef __MESA__
67 inline
68 #endif
_sha1_process(SHA_CTX * ctx,const uchar data[64])69 void _sha1_process(SHA_CTX *ctx, const uchar data[64]) {
70 #if __OS_X__ && gpu_amd(DEVICE_INFO)
71 volatile
72 #endif
73 uint temp, W[16], A, B, C, D, E, r[16];
74
75 #if gpu_nvidia(DEVICE_INFO)
76 if (!((size_t)data & 0x03)) {
77 GET_UINT32BE_ALIGNED(W[ 0], data, 0);
78 GET_UINT32BE_ALIGNED(W[ 1], data, 4);
79 GET_UINT32BE_ALIGNED(W[ 2], data, 8);
80 GET_UINT32BE_ALIGNED(W[ 3], data, 12);
81 GET_UINT32BE_ALIGNED(W[ 4], data, 16);
82 GET_UINT32BE_ALIGNED(W[ 5], data, 20);
83 GET_UINT32BE_ALIGNED(W[ 6], data, 24);
84 GET_UINT32BE_ALIGNED(W[ 7], data, 28);
85 GET_UINT32BE_ALIGNED(W[ 8], data, 32);
86 GET_UINT32BE_ALIGNED(W[ 9], data, 36);
87 GET_UINT32BE_ALIGNED(W[10], data, 40);
88 GET_UINT32BE_ALIGNED(W[11], data, 44);
89 GET_UINT32BE_ALIGNED(W[12], data, 48);
90 GET_UINT32BE_ALIGNED(W[13], data, 52);
91 GET_UINT32BE_ALIGNED(W[14], data, 56);
92 GET_UINT32BE_ALIGNED(W[15], data, 60);
93 } else
94 #endif
95 {
96 GET_UINT32BE(W[ 0], data, 0);
97 GET_UINT32BE(W[ 1], data, 4);
98 GET_UINT32BE(W[ 2], data, 8);
99 GET_UINT32BE(W[ 3], data, 12);
100 GET_UINT32BE(W[ 4], data, 16);
101 GET_UINT32BE(W[ 5], data, 20);
102 GET_UINT32BE(W[ 6], data, 24);
103 GET_UINT32BE(W[ 7], data, 28);
104 GET_UINT32BE(W[ 8], data, 32);
105 GET_UINT32BE(W[ 9], data, 36);
106 GET_UINT32BE(W[10], data, 40);
107 GET_UINT32BE(W[11], data, 44);
108 GET_UINT32BE(W[12], data, 48);
109 GET_UINT32BE(W[13], data, 52);
110 GET_UINT32BE(W[14], data, 56);
111 GET_UINT32BE(W[15], data, 60);
112 }
113
114 A = ctx->state[0];
115 B = ctx->state[1];
116 C = ctx->state[2];
117 D = ctx->state[3];
118 E = ctx->state[4];
119
120 SHA1(A, B, C, D, E, W);
121
122 ctx->state[0] += A;
123 ctx->state[1] += B;
124 ctx->state[2] += C;
125 ctx->state[3] += D;
126 ctx->state[4] += E;
127 }
128
129 /*
130 * SHA-1 process buffer
131 */
132 #ifndef __MESA__
133 inline
134 #endif
SHA1_Update(SHA_CTX * ctx,const uchar * input,uint ilen)135 void SHA1_Update(SHA_CTX *ctx, const uchar *input, uint ilen) {
136 uint fill;
137 uint left;
138
139 if (ilen <= 0)
140 return;
141
142 left = ctx->total & 0x3F;
143 fill = 64 - left;
144
145 ctx->total += ilen;
146
147 if (left && ilen >= fill)
148 {
149 memcpy_pp(ctx->buffer + left, input, fill);
150 _sha1_process(ctx, ctx->buffer);
151 input += fill;
152 ilen -= fill;
153 left = 0;
154 }
155
156 while(ilen >= 64)
157 {
158 _sha1_process(ctx, input);
159 input += 64;
160 ilen -= 64;
161 }
162
163 if (ilen > 0)
164 {
165 memcpy_pp(ctx->buffer + left, input, ilen);
166 }
167 }
168
169 /*
170 * SHA-1 final digest
171 */
172 #ifndef __MESA__
173 inline
174 #endif
SHA1_Final(uchar output[20],SHA_CTX * ctx)175 void SHA1_Final(uchar output[20], SHA_CTX *ctx) {
176 uint last, padn;
177 ulong bits;
178 uchar msglen[8];
179 uchar sha1_padding[64] = { 0x80 /* , 0, 0 ... */ };
180
181 bits = ctx->total << 3;
182
183 PUT_UINT64BE(bits, msglen, 0);
184
185 last = ctx->total & 0x3F;
186 padn = (last < 56) ? (56 - last) : (120 - last);
187
188 SHA1_Update(ctx, sha1_padding, padn);
189 SHA1_Update(ctx, msglen, 8);
190
191 #if gpu_nvidia(DEVICE_INFO)
192 if (!((size_t)output & 0x03)) {
193 PUT_UINT32BE_ALIGNED(ctx->state[0], output, 0);
194 PUT_UINT32BE_ALIGNED(ctx->state[1], output, 4);
195 PUT_UINT32BE_ALIGNED(ctx->state[2], output, 8);
196 PUT_UINT32BE_ALIGNED(ctx->state[3], output, 12);
197 PUT_UINT32BE_ALIGNED(ctx->state[4], output, 16);
198 } else
199 #endif
200 {
201 PUT_UINT32BE(ctx->state[0], output, 0);
202 PUT_UINT32BE(ctx->state[1], output, 4);
203 PUT_UINT32BE(ctx->state[2], output, 8);
204 PUT_UINT32BE(ctx->state[3], output, 12);
205 PUT_UINT32BE(ctx->state[4], output, 16);
206 }
207 }
208
209 #endif /* _OPENCL_SHA1_CTX_H */
210