1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
|
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include "textflag.h"
// func cryptBlocks(c code, key, dst, src *byte, length int)
TEXT ·cryptBlocks(SB),NOSPLIT,$0-40
MOVD key+8(FP), R1
MOVD dst+16(FP), R2
MOVD src+24(FP), R4
MOVD length+32(FP), R5
MOVD c+0(FP), R0
loop:
WORD $0xB92E0024 // cipher message (KM)
BVS loop // branch back if interrupted
XOR R0, R0
RET
// func cryptBlocksChain(c code, iv, key, dst, src *byte, length int)
TEXT ·cryptBlocksChain(SB),NOSPLIT,$48-48
LA params-48(SP), R1
MOVD iv+8(FP), R8
MOVD key+16(FP), R9
MVC $16, 0(R8), 0(R1) // move iv into params
MVC $32, 0(R9), 16(R1) // move key into params
MOVD dst+24(FP), R2
MOVD src+32(FP), R4
MOVD length+40(FP), R5
MOVD c+0(FP), R0
loop:
WORD $0xB92F0024 // cipher message with chaining (KMC)
BVS loop // branch back if interrupted
XOR R0, R0
MVC $16, 0(R1), 0(R8) // update iv
RET
// func xorBytes(dst, a, b []byte) int
TEXT ·xorBytes(SB),NOSPLIT,$0-80
MOVD dst_base+0(FP), R1
MOVD a_base+24(FP), R2
MOVD b_base+48(FP), R3
MOVD a_len+32(FP), R4
MOVD b_len+56(FP), R5
CMPBLE R4, R5, skip
MOVD R5, R4
skip:
MOVD R4, ret+72(FP)
MOVD $0, R5
CMPBLT R4, $8, tail
loop:
MOVD 0(R2)(R5*1), R7
MOVD 0(R3)(R5*1), R8
XOR R7, R8
MOVD R8, 0(R1)(R5*1)
LAY 8(R5), R5
SUB $8, R4
CMPBGE R4, $8, loop
tail:
CMPBEQ R4, $0, done
MOVB 0(R2)(R5*1), R7
MOVB 0(R3)(R5*1), R8
XOR R7, R8
MOVB R8, 0(R1)(R5*1)
LAY 1(R5), R5
SUB $1, R4
BR tail
done:
RET
// func cryptBlocksGCM(fn code, key, dst, src, buf []byte, cnt *[16]byte)
TEXT ·cryptBlocksGCM(SB),NOSPLIT,$0-112
MOVD src_len+64(FP), R0
MOVD buf_base+80(FP), R1
MOVD cnt+104(FP), R12
LMG (R12), R2, R3
// Check that the src size is less than or equal to the buffer size.
MOVD buf_len+88(FP), R4
CMP R0, R4
BGT crash
// Check that the src size is a multiple of 16-bytes.
MOVD R0, R4
AND $0xf, R4
BLT crash // non-zero
// Check that the src size is less than or equal to the dst size.
MOVD dst_len+40(FP), R4
CMP R0, R4
BGT crash
MOVD R2, R4
MOVD R2, R6
MOVD R2, R8
MOVD R3, R5
MOVD R3, R7
MOVD R3, R9
ADDW $1, R5
ADDW $2, R7
ADDW $3, R9
incr:
CMP R0, $64
BLT tail
STMG R2, R9, (R1)
ADDW $4, R3
ADDW $4, R5
ADDW $4, R7
ADDW $4, R9
MOVD $64(R1), R1
SUB $64, R0
BR incr
tail:
CMP R0, $0
BEQ crypt
STMG R2, R3, (R1)
ADDW $1, R3
MOVD $16(R1), R1
SUB $16, R0
BR tail
crypt:
STMG R2, R3, (R12) // update next counter value
MOVD fn+0(FP), R0 // function code (encryption)
MOVD key_base+8(FP), R1 // key
MOVD buf_base+80(FP), R2 // counter values
MOVD dst_base+32(FP), R4 // dst
MOVD src_base+56(FP), R6 // src
MOVD src_len+64(FP), R7 // len
loop:
WORD $0xB92D2046 // cipher message with counter (KMCTR)
BVS loop // branch back if interrupted
RET
crash:
MOVD $0, (R0)
RET
// func ghash(key *gcmHashKey, hash *[16]byte, data []byte)
TEXT ·ghash(SB),NOSPLIT,$32-40
MOVD $65, R0 // GHASH function code
MOVD key+0(FP), R2
LMG (R2), R6, R7
MOVD hash+8(FP), R8
LMG (R8), R4, R5
MOVD $params-32(SP), R1
STMG R4, R7, (R1)
LMG data+16(FP), R2, R3 // R2=base, R3=len
loop:
WORD $0xB93E0002 // compute intermediate message digest (KIMD)
BVS loop // branch back if interrupted
MVC $16, (R1), (R8)
MOVD $0, R0
RET
// func kmaGCM(fn code, key, dst, src, aad []byte, tag *[16]byte, cnt *gcmCount)
TEXT ·kmaGCM(SB),NOSPLIT,$112-120
MOVD fn+0(FP), R0
MOVD $params-112(SP), R1
// load ptr/len pairs
LMG dst+32(FP), R2, R3 // R2=base R3=len
LMG src+56(FP), R4, R5 // R4=base R5=len
LMG aad+80(FP), R6, R7 // R6=base R7=len
// setup parameters
MOVD cnt+112(FP), R8
XC $12, (R1), (R1) // reserved
MVC $4, 12(R8), 12(R1) // set chain value
MVC $16, (R8), 64(R1) // set initial counter value
XC $32, 16(R1), 16(R1) // set hash subkey and tag
SLD $3, R7, R12
MOVD R12, 48(R1) // set total AAD length
SLD $3, R5, R12
MOVD R12, 56(R1) // set total plaintext/ciphertext length
LMG key+8(FP), R8, R9 // R8=base R9=len
MVC $16, (R8), 80(R1) // set key
CMPBEQ R9, $16, kma
MVC $8, 16(R8), 96(R1)
CMPBEQ R9, $24, kma
MVC $8, 24(R8), 104(R1)
kma:
WORD $0xb9296024 // kma %r6,%r2,%r4
BVS kma
MOVD tag+104(FP), R2
MVC $16, 16(R1), 0(R2) // copy tag to output
MOVD cnt+112(FP), R8
MVC $4, 12(R1), 12(R8) // update counter value
RET
|