Subversion Repositories Kolibri OS

Rev

Rev 6465 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
7698 dunkaist 1
;    libcrash -- cryptographic hash functions
2
;
3
;    Copyright (C) 2013,2016,2019 Ivan Baravy (dunkaist)
4
;
5
;    This program is free software: you can redistribute it and/or modify
6
;    it under the terms of the GNU General Public License as published by
7
;    the Free Software Foundation, either version 3 of the License, or
8
;    (at your option) any later version.
9
;
10
;    This program is distributed in the hope that it will be useful,
11
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
;    GNU General Public License for more details.
14
;
15
;    You should have received a copy of the GNU General Public License
16
;    along with this program.  If not, see .
17
 
18
 
19
SHA3_224_HASH_SIZE       = 28
20
SHA3_256_HASH_SIZE       = 32
21
SHA3_384_HASH_SIZE       = 48
22
SHA3_512_HASH_SIZE       = 64
23
 
24
SHA3_224_BLOCK_SIZE      = 144
25
SHA3_256_BLOCK_SIZE      = 136
26
SHA3_384_BLOCK_SIZE      = 104
27
SHA3_512_BLOCK_SIZE      = 72
28
SHA3MAX_BLOCK_SIZE      = SHA3_224_BLOCK_SIZE
29
 
30
SHA3_INIT_SIZE          = 200
31
SHA3_ALIGN              = 16
32
SHA3_ALIGN_MASK         = SHA3_ALIGN-1
33
 
34
struct ctx_sha3
35
        hash            rb SHA3_INIT_SIZE
36
                        rb SHA3_ALIGN - (SHA3_INIT_SIZE mod SHA3_ALIGN)
37
        block           rb SHA3MAX_BLOCK_SIZE
38
                        rb SHA3_ALIGN - (SHA3MAX_BLOCK_SIZE mod SHA3_ALIGN)
39
        index           rd 1
40
        block_size      rd 1
41
        rounds_cnt      rd 1
42
                        rd 1    ; align
43
        ; tmp vars
44
        C               rq 5
45
        D               rq 5
46
ends
47
 
48
if defined sizeof.crash_ctx
49
  assert sizeof.crash_ctx >= sizeof.ctx_sha3
50
end if
51
 
52
macro sha3._.rol_xor nd, ncl, ncr
53
{
54
        movq    mm0, [C + 8*(ncl)]
55
        movq    mm1, mm0
56
        psllq   mm0, 1
57
        psrlq   mm1, 63
58
        por     mm0, mm1
59
        pxor    mm0, [C + 8*(ncr)]
60
        movq    [D + 8*(nd)], mm0
61
}
62
 
63
proc sha3._.theta
64
;locals
65
;        C       rq 5
66
;        D       rq 5
67
;endl
68
C equ ebx + ctx_sha3.C
69
D equ ebx + ctx_sha3.D
70
 
71
repeat 5
72
        movq    mm0, [edi + 8*(%-1 +  0)]
73
        pxor    mm0, [edi + 8*(%-1 +  5)]
74
        pxor    mm0, [edi + 8*(%-1 + 10)]
75
        pxor    mm0, [edi + 8*(%-1 + 15)]
76
        pxor    mm0, [edi + 8*(%-1 + 20)]
77
        movq    [C + 8*(%-1)], mm0
78
end repeat
79
 
80
        sha3._.rol_xor  0, 1, 4
81
        sha3._.rol_xor  1, 2, 0
82
        sha3._.rol_xor  2, 3, 1
83
        sha3._.rol_xor  3, 4, 2
84
        sha3._.rol_xor  4, 0, 3
85
 
86
repeat 5
87
        movq    mm1, [D + 8*(%-1)]
88
        movq    mm0, mm1
89
        pxor    mm0, [edi + 8*(%-1 +  0)]
90
        movq    [edi + 8*(%-1 +  0)], mm0
91
        movq    mm0, mm1
92
        pxor    mm0, [edi + 8*(%-1 +  5)]
93
        movq    [edi + 8*(%-1 +  5)], mm0
94
        movq    mm0, mm1
95
        pxor    mm0, [edi + 8*(%-1 + 10)]
96
        movq    [edi + 8*(%-1 + 10)], mm0
97
        movq    mm0, mm1
98
        pxor    mm0, [edi + 8*(%-1 + 15)]
99
        movq    [edi + 8*(%-1 + 15)], mm0
100
        movq    mm0, mm1
101
        pxor    mm0, [edi + 8*(%-1 + 20)]
102
        movq    [edi + 8*(%-1 + 20)], mm0
103
end repeat
104
 
105
restore C,D
106
        ret
107
endp
108
 
109
 
110
proc sha3._.pi
111
        movq    mm1, [edi + 8*1]
112
        movq    mm0, [edi + 8*6]
113
        movq    [edi + 8*1], mm0
114
        movq    mm0, [edi + 8*9]
115
        movq    [edi + 8*6], mm0
116
        movq    mm0, [edi + 8*22]
117
        movq    [edi + 8*9], mm0
118
        movq    mm0, [edi + 8*14]
119
        movq    [edi + 8*22], mm0
120
        movq    mm0, [edi + 8*20]
121
        movq    [edi + 8*14], mm0
122
        movq    mm0, [edi + 8*2]
123
        movq    [edi + 8*20], mm0
124
        movq    mm0, [edi + 8*12]
125
        movq    [edi + 8*2], mm0
126
        movq    mm0, [edi + 8*13]
127
        movq    [edi + 8*12], mm0
128
        movq    mm0, [edi + 8*19]
129
        movq    [edi + 8*13], mm0
130
        movq    mm0, [edi + 8*23]
131
        movq    [edi + 8*19], mm0
132
        movq    mm0, [edi + 8*15]
133
        movq    [edi + 8*23], mm0
134
        movq    mm0, [edi + 8*4]
135
        movq    [edi + 8*15], mm0
136
        movq    mm0, [edi + 8*24]
137
        movq    [edi + 8*4], mm0
138
        movq    mm0, [edi + 8*21]
139
        movq    [edi + 8*24], mm0
140
        movq    mm0, [edi + 8*8]
141
        movq    [edi + 8*21], mm0
142
        movq    mm0, [edi + 8*16]
143
        movq    [edi + 8*8], mm0
144
        movq    mm0, [edi + 8*5]
145
        movq    [edi + 8*16], mm0
146
        movq    mm0, [edi + 8*3]
147
        movq    [edi + 8*5], mm0
148
        movq    mm0, [edi + 8*18]
149
        movq    [edi + 8*3], mm0
150
        movq    mm0, [edi + 8*17]
151
        movq    [edi + 8*18], mm0
152
        movq    mm0, [edi + 8*11]
153
        movq    [edi + 8*17], mm0
154
        movq    mm0, [edi + 8*7]
155
        movq    [edi + 8*11], mm0
156
        movq    mm0, [edi + 8*10]
157
        movq    [edi + 8*7], mm0
158
        movq    [edi + 8*10], mm1
159
 
160
        ret
161
endp
162
 
163
 
164
proc sha3._.chi
165
 
166
        mov     eax, 0xffffffff
167
        movd    mm0, eax
168
        movq    mm2, mm0
169
        punpckldq       mm2, mm0
170
 
171
repeat 5
172
        movq    mm6, [edi + 8*(0 + 5*(%-1))]
173
        movq    mm7, [edi + 8*(1 + 5*(%-1))]
174
 
175
        movq    mm0, [edi + 8*(0 + 5*(%-1))]
176
        movq    mm1, mm7
177
        pandn   mm1, mm2
178
        pand    mm1, [edi + 8*(2 + 5*(%-1))]
179
        pxor    mm0, mm1
180
        movq    [edi + 8*(0 + 5*(%-1))], mm0
181
 
182
        movq    mm0, [edi + 8*(1 + 5*(%-1))]
183
        movq    mm1, [edi + 8*(2 + 5*(%-1))]
184
        pandn   mm1, mm2
185
        pand    mm1, [edi + 8*(3 + 5*(%-1))]
186
        pxor    mm0, mm1
187
        movq    [edi + 8*(1 + 5*(%-1))], mm0
188
 
189
        movq    mm0, [edi + 8*(2 + 5*(%-1))]
190
        movq    mm1, [edi + 8*(3 + 5*(%-1))]
191
        pandn   mm1, mm2
192
        pand    mm1, [edi + 8*(4 + 5*(%-1))]
193
        pxor    mm0, mm1
194
        movq    [edi + 8*(2 + 5*(%-1))], mm0
195
 
196
        movq    mm0, [edi + 8*(3 + 5*(%-1))]
197
        movq    mm1, [edi + 8*(4 + 5*(%-1))]
198
        pandn   mm1, mm2
199
        pand    mm1, mm6
200
        pxor    mm0, mm1
201
        movq    [edi + 8*(3 + 5*(%-1))], mm0
202
 
203
        movq    mm0, [edi + 8*(4 + 5*(%-1))]
204
        movq    mm1, mm6
205
        pandn   mm1, mm2
206
        pand    mm1, mm7
207
        pxor    mm0, mm1
208
        movq    [edi + 8*(4 + 5*(%-1))], mm0
209
end repeat
210
        ret
211
endp
212
 
213
 
214
macro sha3._.rol_mov n, c
215
{
216
        movq    mm0, [edi + 8*(n)]
217
        movq    mm1, mm0
218
        psllq   mm0, (c)
219
        psrlq   mm1, (64-(c))
220
        por     mm0, mm1
221
        movq    [edi + 8*(n)], mm0
222
}
223
 
224
proc sha3._.permutation
225
 
226
repeat 24
227
        stdcall sha3._.theta
228
 
229
        sha3._.rol_mov   1,  1
230
        sha3._.rol_mov   2, 62
231
        sha3._.rol_mov   3, 28
232
        sha3._.rol_mov   4, 27
233
        sha3._.rol_mov   5, 36
234
        sha3._.rol_mov   6, 44
235
        sha3._.rol_mov   7,  6
236
        sha3._.rol_mov   8, 55
237
        sha3._.rol_mov   9, 20
238
        sha3._.rol_mov  10,  3
239
        sha3._.rol_mov  11, 10
240
        sha3._.rol_mov  12, 43
241
        sha3._.rol_mov  13, 25
242
        sha3._.rol_mov  14, 39
243
        sha3._.rol_mov  15, 41
244
        sha3._.rol_mov  16, 45
245
        sha3._.rol_mov  17, 15
246
        sha3._.rol_mov  18, 21
247
        sha3._.rol_mov  19,  8
248
        sha3._.rol_mov  20, 18
249
        sha3._.rol_mov  21,  2
250
        sha3._.rol_mov  22, 61
251
        sha3._.rol_mov  23, 56
252
        sha3._.rol_mov  24, 14
253
 
254
        stdcall sha3._.pi
255
        stdcall sha3._.chi
256
 
257
        movq    mm0, [edi + 8*(0)]
258
        pxor    mm0, [sha3._.round + 8*(%-1)]
259
        movq    [edi + 8*(0)], mm0
260
end repeat
261
 
262
        ret
263
endp
264
 
265
 
266
proc sha3._.init _ctx
267
        mov     [ebx + ctx_sha3.block_size], eax
268
        shr     eax, 3
269
        dec     eax
270
        mov     [ebx + ctx_sha3.rounds_cnt], eax
271
        xor     eax, eax
272
        lea     edi, [ebx + ctx_sha3.hash]
273
        mov     ecx, SHA3_INIT_SIZE/4
274
        rep     stosd
275
        mov     [ebx + ctx_sha3.index], eax
276
        ret
277
endp
278
 
279
 
280
proc sha3_224.init _ctx
281
        mov     ebx, [_ctx]
282
        mov     eax, SHA3_224_BLOCK_SIZE
283
        stdcall sha3._.init
284
        ret
285
endp
286
 
287
 
288
proc sha3_256.init _ctx
289
        mov     ebx, [_ctx]
290
        mov     eax, SHA3_256_BLOCK_SIZE
291
        stdcall sha3._.init
292
        ret
293
endp
294
 
295
 
296
proc sha3_384.init _ctx
297
        mov     ebx, [_ctx]
298
        mov     eax, SHA3_384_BLOCK_SIZE
299
        stdcall sha3._.init
300
        ret
301
endp
302
 
303
 
304
proc sha3_512.init _ctx
305
        mov     ebx, [_ctx]
306
        mov     eax, SHA3_512_BLOCK_SIZE
307
        stdcall sha3._.init
308
        ret
309
endp
310
 
311
 
312
proc sha3._.block _hash
313
        mov     ecx, [ebx + ctx_sha3.rounds_cnt]
314
        mov     edi, [_hash]
315
 
316
    @@:
317
        movq    mm0, [esi + 8*ecx]
318
        pxor    mm0, [edi + 8*ecx]
319
        movq    [edi + 8*ecx], mm0
320
        dec     ecx
321
        jns     @b
322
 
323
        stdcall sha3._.permutation
324
 
325
        ret
326
endp
327
 
328
 
329
sha3_224.update = sha3.update
330
sha3_256.update = sha3.update
331
sha3_384.update = sha3.update
332
sha3_512.update = sha3.update
333
proc sha3.update _ctx, _msg, _size
334
  .next_block:
335
        mov     ebx, [_ctx]
336
        mov     esi, [_msg]
337
        mov     eax, [ebx + ctx_sha3.index]
338
        test    eax, eax
339
        jnz     .copy_to_buf
340
        test    esi, SHA3_ALIGN_MASK
341
        jnz     .copy_to_buf
342
  .no_copy:
343
        ; data is aligned, hash it in place without copying
344
        mov     ebx, [_ctx]
345
        mov     eax, [ebx + ctx_sha3.block_size]
346
        cmp     [_size], eax
347
        jb      .copy_quit
348
        lea     eax, [ebx + ctx_sha3.hash]
349
        push    ebx esi
350
        stdcall sha3._.block, eax
351
        pop     esi ebx
352
        mov     eax, [ebx + ctx_sha3.block_size]
353
        sub     [_size], eax
354
        add     esi, [ebx + ctx_sha3.block_size]
355
        jmp     .no_copy
356
 
357
  .copy_to_buf:
358
        lea     edi, [ebx + ctx_sha3.block]
359
        add     edi, eax
360
        mov     ecx, [ebx + ctx_sha3.block_size]
361
        sub     ecx, eax
362
        cmp     [_size], ecx
363
        jb      .copy_quit
364
        sub     [_size], ecx
365
        add     [_msg], ecx
366
        add     [ebx + ctx_sha3.index], ecx
367
        mov     eax, [ebx + ctx_sha3.block_size]
368
        cmp     [ebx + ctx_sha3.index], eax
369
        jb      @f
370
        sub     [ebx + ctx_sha3.index], eax
371
    @@:
372
        rep     movsb
373
        lea     eax, [ebx + ctx_sha3.hash]
374
        lea     esi, [ebx + ctx_sha3.block]
375
        stdcall sha3._.block, eax
376
        jmp     .next_block
377
 
378
  .copy_quit:
379
        mov     ebx, [_ctx]
380
        lea     edi, [ebx + ctx_sha3.block]
381
        mov     eax, [ebx + ctx_sha3.index]
382
        add     edi, eax
383
        mov     ecx, [_size]
384
        add     [ebx + ctx_sha3.index], ecx
385
        rep     movsb
386
  .quit:
387
        ret
388
endp
389
 
390
 
391
sha3_224.final = sha3.final
392
sha3_256.final = sha3.final
393
sha3_384.final = sha3.final
394
sha3_512.final = sha3.final
395
proc sha3.final _ctx
396
        pushad
397
        mov     ebx, [_ctx]
398
        mov     eax, [ebx + ctx_sha3.index]
399
        xor     edx, edx
400
        mov     ecx, [ebx + ctx_sha3.block_size]
401
        div     ecx
402
        sub     ecx, edx
403
        ja      @f
404
        add     ecx, [ebx + ctx_sha3.block_size]
405
    @@:
406
        add     [ebx + ctx_sha3.index], ecx
407
        mov     eax, [ebx + ctx_sha3.block_size]
408
        cmp     [ebx + ctx_sha3.index], eax
409
        jb      @f
410
        sub     [ebx + ctx_sha3.index], eax
411
    @@:
412
 
413
        mov     byte[edi], 0x06
414
        inc     edi
415
        dec     ecx
416
        xor     eax, eax
417
        rep     stosb
418
        or      byte[edi - 1], 0x80
419
 
420
        mov     ebx, [_ctx]
421
        lea     esi, [ebx + ctx_sha3.block]
422
        lea     eax, [ebx + ctx_sha3.hash]
423
        stdcall sha3._.block, eax
424
 
425
        mov     ebx, [_ctx]
426
        lea     eax, [ebx + ctx_sha3.hash]
427
        stdcall sha3._.postprocess, ebx, eax
428
 
429
        popad
430
        ret
431
endp
432
 
433
 
434
proc sha3._.postprocess _ctx, _hash
435
        emms
436
        ret
437
endp
438
 
439
 
440
proc sha3_224.oneshot _ctx, _data, _len
441
	stdcall	sha3_224.init, [_ctx]
442
	stdcall	sha3.update, [_ctx], [_data], [_len]
443
	stdcall	sha3.final, [_ctx]
444
	ret
445
endp
446
 
447
 
448
proc sha3_256.oneshot _ctx, _data, _len
449
	stdcall	sha3_256.init, [_ctx]
450
	stdcall	sha3.update, [_ctx], [_data], [_len]
451
	stdcall	sha3.final, [_ctx]
452
	ret
453
endp
454
 
455
 
456
proc sha3_384.oneshot _ctx, _data, _len
457
	stdcall	sha3_384.init, [_ctx]
458
	stdcall	sha3.update, [_ctx], [_data], [_len]
459
	stdcall	sha3.final, [_ctx]
460
	ret
461
endp
462
 
463
 
464
proc sha3_512.oneshot _ctx, _data, _len
465
	stdcall	sha3_512.init, [_ctx]
466
	stdcall	sha3.update, [_ctx], [_data], [_len]
467
	stdcall	sha3.final, [_ctx]
468
	ret
469
endp
470
 
471
 
472
iglobal
473
align SHA3_ALIGN
474
sha3._.round    dq 0x0000000000000001, 0x0000000000008082, 0x800000000000808A,\
475
                   0x8000000080008000, 0x000000000000808B, 0x0000000080000001,\
476
                   0x8000000080008081, 0x8000000000008009, 0x000000000000008A,\
477
                   0x0000000000000088, 0x0000000080008009, 0x000000008000000A,\
478
                   0x000000008000808B, 0x800000000000008B, 0x8000000000008089,\
479
                   0x8000000000008003, 0x8000000000008002, 0x8000000000000080,\
480
                   0x000000000000800A, 0x800000008000000A, 0x8000000080008081,\
481
                   0x8000000000008080, 0x0000000080000001, 0x8000000080008008
482
endg