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