// 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
|