Merge pull request #1477 from dcooper16/faster_gcm

Speedup AES-GCM
This commit is contained in:
Dirk Wetter 2020-01-30 10:22:02 +01:00 committed by GitHub
commit 5e9767a17c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -11828,25 +11828,21 @@ gcm_mult() {
return 0
}
# arg1: a hexadecimal string that is at least 8 bytes in length
# See Section 6.2 of NIST SP 800-38D
inc32() {
local -i i len
local x="$1"
local msb
local -i lsb
# arg1: nonce (must be 96 bits)
# arg2: number of blocks needed for plaintext/ciphertext
# Generate the sequence of counter blocks, which are to be encrypted and then
# XORed with either the plaintext or the ciphertext. The first block that is
# encrypted is used in computing the authentication tag.
generate_gcm_ctr() {
local -i nr_blocks="$1"
local nonce="$2"
local i
local lsb ctr=""
len=${#x}
[[ $len -lt 8 ]] && return 7
i=$len-8
msb="${x:0:i}"
lsb="0x${x:i:8}"
if [[ "$lsb" -eq "0xffffffff" ]]; then
lsb=0
else
lsb+=1
fi
tm_out "${msb}$(printf "%08X" "$lsb")"
for (( i=1; i <= nr_blocks; i++ )); do
lsb="$(printf "%08X" "$i")"
printf "\x${nonce:0:2}\x${nonce:2:2}\x${nonce:4:2}\x${nonce:6:2}\x${nonce:8:2}\x${nonce:10:2}\x${nonce:12:2}\x${nonce:14:2}\x${nonce:16:2}\x${nonce:18:2}\x${nonce:20:2}\x${nonce:22:2}\x${lsb:0:2}\x${lsb:2:2}\x${lsb:4:2}\x${lsb:6:2}"
done
return 0
}
@ -11860,7 +11856,7 @@ inc32() {
# This function is based on gcm_setkey, gcm_start, gcm_update, and gcm_finish
# in https://github.com/mko-x/SharedAES-GCM
gcm() {
local cipher="$1" aes_key="$2" y="${3}00000001" input="$4" aad="$5" mode="$6"
local cipher="$1" aes_key="$2" nonce="$3" input="$4" aad="$5" mode="$6"
local compute_tag="$7"
local -a -i gcm_ctx_hl=(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
local -a -i gcm_ctx_hh=(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
@ -11912,10 +11908,6 @@ gcm() {
hh+="$(printf "%016X" ${gcm_ctx_hh[i]}) "
done
# gcm_start
# compute the encrypted counter for later use in computing the authentication tag
base_ectr="$(printf "\x${y:0:2}\x${y:2:2}\x${y:4:2}\x${y:6:2}\x${y:8:2}\x${y:10:2}\x${y:12:2}\x${y:14:2}\x${y:16:2}\x${y:18:2}\x${y:20:2}\x${y:22:2}\x${y:24:2}\x${y:26:2}\x${y:28:2}\x${y:30:2}" | $OPENSSL enc "$cipher" -K "$aes_key" -nopad 2>/dev/null | hexdump -v -e '16/1 "%02X"')"
# Feed any additional authenticated data into the computation for the authentication tag.
for (( i=0; i < aad_len; i+=use_len )); do
[[ $((aad_len-i)) -lt 16 ]] && use_len=$((aad_len-i)) || use_len=16
@ -11928,25 +11920,33 @@ gcm() {
done
fi
j=$((1 + input_len/16))
[[ $((input_len%16)) -ne 0 ]] && j+=1
ectr="$(generate_gcm_ctr "$j" "$nonce" | $OPENSSL enc "$cipher" -K "$aes_key" -nopad 2>/dev/null | hexdump -v -e '16/1 "%02X"')"
base_ectr="${ectr:0:32}"
ectr="${ectr:32}"
# gcm_update
# Encrypt or decrypt the input and feed the ciphertext into the computation for the authentication tag.
for (( length=input_len; length > 0; length=length-use_len )); do
[[ $length -lt 16 ]] && use_len=$length || use_len=16
y="$(inc32 "$y")"
ectr="$(printf "\x${y:0:2}\x${y:2:2}\x${y:4:2}\x${y:6:2}\x${y:8:2}\x${y:10:2}\x${y:12:2}\x${y:14:2}\x${y:16:2}\x${y:18:2}\x${y:20:2}\x${y:22:2}\x${y:24:2}\x${y:26:2}\x${y:28:2}\x${y:30:2}" | $OPENSSL enc "$cipher" -K "$aes_key" -nopad 2>/dev/null | hexdump -v -e '16/1 "%02X"')"
for (( i=0; i < use_len; i++ )); do
tmp="$(printf "%02X" $((0x${ectr:$((2*i)):2} ^ 0x${input:$((2*i)):2})))"
output+="$tmp"
if "$compute_tag"; then
if [[ $mode == encrypt ]]; then
gcm_ctx_buf[i]="$(printf "%02X" $((0x${gcm_ctx_buf[i]} ^ 0x$tmp)))"
else
gcm_ctx_buf[i]="$(printf "%02X" $((0x${gcm_ctx_buf[i]} ^ 0x${input:$((2*i)):2})))"
fi
fi
done
if [[ $use_len -eq 16 ]]; then
tmp="$(printf "%08X%08X%08X%08X" "$((0x${ectr:0:8} ^ 0x${input:0:8}))" "$((0x${ectr:8:8} ^ 0x${input:8:8}))" "$((0x${ectr:16:8} ^ 0x${input:16:8}))" "$((0x${ectr:24:8} ^ 0x${input:24:8}))")"
else
tmp=""
for (( i=0; i < use_len; i++ )); do
tmp+="$(printf "%02X" $((0x${ectr:$((2*i)):2} ^ 0x${input:$((2*i)):2})))"
done
fi
output+="$tmp"
if "$compute_tag"; then
[[ $mode == decrypt ]] && tmp="${input:0:32}"
for (( i=0; i < use_len; i++ )); do
gcm_ctx_buf[i]="$(printf "%02X" $((0x${gcm_ctx_buf[i]} ^ 0x${tmp:$((2*i)):2})))"
done
fi
ectr="${ectr:32}"
if "$compute_tag"; then
tmp="$(gcm_mult $hl $hh ${gcm_ctx_buf[0]} ${gcm_ctx_buf[1]} ${gcm_ctx_buf[2]} ${gcm_ctx_buf[3]} ${gcm_ctx_buf[4]} ${gcm_ctx_buf[5]} ${gcm_ctx_buf[6]} ${gcm_ctx_buf[7]} ${gcm_ctx_buf[8]} ${gcm_ctx_buf[9]} ${gcm_ctx_buf[10]} ${gcm_ctx_buf[11]} ${gcm_ctx_buf[12]} ${gcm_ctx_buf[13]} ${gcm_ctx_buf[14]} ${gcm_ctx_buf[15]})"