Subversion Repositories Kolibri OS

Rev

Rev 7698 | Details | Compare with Previous | Last modification | View Log | RSS feed

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