1 /*
2 * This software is
3 * Copyright (c) 2018 magnum
4 * and it is hereby released to the general public under the following terms:
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted.
8 */
9
10 #ifndef _OPENCL_MD5_CTX_H
11 #define _OPENCL_MD5_CTX_H
12
13 #include "opencl_misc.h"
14 #include "opencl_md5.h"
15
16 typedef struct {
17 uint total; /* number of bytes processed */
18 uint state[4]; /* intermediate digest state */
19 uchar buffer[64]; /* data block being processed */
20 } MD5_CTX;
21
22 #ifndef __MESA__
23 inline
24 #endif
_md5_process(MD5_CTX * ctx,const uchar data[64])25 void _md5_process(MD5_CTX *ctx, const uchar data[64]) {
26 uint W[16], A, B, C, D;
27
28 #if gpu_nvidia(DEVICE_INFO)
29 if (!((size_t)data & 0x03)) {
30 GET_UINT32_ALIGNED(W[ 0], data, 0);
31 GET_UINT32_ALIGNED(W[ 1], data, 4);
32 GET_UINT32_ALIGNED(W[ 2], data, 8);
33 GET_UINT32_ALIGNED(W[ 3], data, 12);
34 GET_UINT32_ALIGNED(W[ 4], data, 16);
35 GET_UINT32_ALIGNED(W[ 5], data, 20);
36 GET_UINT32_ALIGNED(W[ 6], data, 24);
37 GET_UINT32_ALIGNED(W[ 7], data, 28);
38 GET_UINT32_ALIGNED(W[ 8], data, 32);
39 GET_UINT32_ALIGNED(W[ 9], data, 36);
40 GET_UINT32_ALIGNED(W[10], data, 40);
41 GET_UINT32_ALIGNED(W[11], data, 44);
42 GET_UINT32_ALIGNED(W[12], data, 48);
43 GET_UINT32_ALIGNED(W[13], data, 52);
44 GET_UINT32_ALIGNED(W[14], data, 56);
45 GET_UINT32_ALIGNED(W[15], data, 60);
46 } else
47 #endif
48 {
49 GET_UINT32(W[ 0], data, 0);
50 GET_UINT32(W[ 1], data, 4);
51 GET_UINT32(W[ 2], data, 8);
52 GET_UINT32(W[ 3], data, 12);
53 GET_UINT32(W[ 4], data, 16);
54 GET_UINT32(W[ 5], data, 20);
55 GET_UINT32(W[ 6], data, 24);
56 GET_UINT32(W[ 7], data, 28);
57 GET_UINT32(W[ 8], data, 32);
58 GET_UINT32(W[ 9], data, 36);
59 GET_UINT32(W[10], data, 40);
60 GET_UINT32(W[11], data, 44);
61 GET_UINT32(W[12], data, 48);
62 GET_UINT32(W[13], data, 52);
63 GET_UINT32(W[14], data, 56);
64 GET_UINT32(W[15], data, 60);
65 }
66
67 A = ctx->state[0];
68 B = ctx->state[1];
69 C = ctx->state[2];
70 D = ctx->state[3];
71
72 MD5(A, B, C, D, W);
73
74 ctx->state[0] += A;
75 ctx->state[1] += B;
76 ctx->state[2] += C;
77 ctx->state[3] += D;
78 }
79
80 /*
81 * MD5 context setup
82 */
83 #ifndef __MESA__
84 inline
85 #endif
MD5_Init(MD5_CTX * ctx)86 void MD5_Init(MD5_CTX *ctx) {
87 ctx->total = 0;
88
89 ctx->state[0] = 0x67452301;
90 ctx->state[1] = 0xefcdab89;
91 ctx->state[2] = 0x98badcfe;
92 ctx->state[3] = 0x10325476;
93 }
94
95 /*
96 * MD5 process buffer
97 */
98 #ifndef __MESA__
99 inline
100 #endif
MD5_Update(MD5_CTX * ctx,const uchar * input,uint ilen)101 void MD5_Update(MD5_CTX *ctx, const uchar *input, uint ilen) {
102 uint fill;
103 uint left;
104
105 if (ilen <= 0)
106 return;
107
108 left = ctx->total & 0x3F;
109 fill = 64 - left;
110
111 ctx->total += ilen;
112
113 if (left && ilen >= fill)
114 {
115 memcpy_pp(ctx->buffer + left, input, fill);
116 _md5_process(ctx, ctx->buffer);
117 input += fill;
118 ilen -= fill;
119 left = 0;
120 }
121
122 while(ilen >= 64)
123 {
124 _md5_process(ctx, input);
125 input += 64;
126 ilen -= 64;
127 }
128
129 if (ilen > 0)
130 {
131 memcpy_pp(ctx->buffer + left, input, ilen);
132 }
133 }
134
135 /*
136 * MD5 final digest
137 */
138 #ifndef __MESA__
139 inline
140 #endif
MD5_Final(uchar output[20],MD5_CTX * ctx)141 void MD5_Final(uchar output[20], MD5_CTX *ctx) {
142 uint last, padn;
143 ulong bits;
144 uchar msglen[8];
145 uchar md5_padding[64] = { 0x80 /* , 0, 0 ... */ };
146
147 bits = ctx->total << 3;
148
149 PUT_UINT64(bits, msglen, 0);
150
151 last = ctx->total & 0x3F;
152 padn = (last < 56) ? (56 - last) : (120 - last);
153
154 MD5_Update(ctx, md5_padding, padn);
155 MD5_Update(ctx, msglen, 8);
156
157 #if gpu_nvidia(DEVICE_INFO)
158 if (!((size_t)output & 0x03)) {
159 PUT_UINT32_ALIGNED(ctx->state[0], output, 0);
160 PUT_UINT32_ALIGNED(ctx->state[1], output, 4);
161 PUT_UINT32_ALIGNED(ctx->state[2], output, 8);
162 PUT_UINT32_ALIGNED(ctx->state[3], output, 12);
163 } else
164 #endif
165 {
166 PUT_UINT32(ctx->state[0], output, 0);
167 PUT_UINT32(ctx->state[1], output, 4);
168 PUT_UINT32(ctx->state[2], output, 8);
169 PUT_UINT32(ctx->state[3], output, 12);
170 }
171 }
172
173 #endif /* _OPENCL_MD5_CTX_H */
174