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 return 0
} }
# arg1: a hexadecimal string that is at least 8 bytes in length # arg1: nonce (must be 96 bits)
# See Section 6.2 of NIST SP 800-38D # arg2: number of blocks needed for plaintext/ciphertext
inc32() { # Generate the sequence of counter blocks, which are to be encrypted and then
local -i i len # XORed with either the plaintext or the ciphertext. The first block that is
local x="$1" # encrypted is used in computing the authentication tag.
local msb generate_gcm_ctr() {
local -i lsb local -i nr_blocks="$1"
local nonce="$2"
local i
local lsb ctr=""
len=${#x} for (( i=1; i <= nr_blocks; i++ )); do
[[ $len -lt 8 ]] && return 7 lsb="$(printf "%08X" "$i")"
i=$len-8 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}"
msb="${x:0:i}" done
lsb="0x${x:i:8}"
if [[ "$lsb" -eq "0xffffffff" ]]; then
lsb=0
else
lsb+=1
fi
tm_out "${msb}$(printf "%08X" "$lsb")"
return 0 return 0
} }
@ -11860,7 +11856,7 @@ inc32() {
# This function is based on gcm_setkey, gcm_start, gcm_update, and gcm_finish # This function is based on gcm_setkey, gcm_start, gcm_update, and gcm_finish
# in https://github.com/mko-x/SharedAES-GCM # in https://github.com/mko-x/SharedAES-GCM
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 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_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) 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]}) " hh+="$(printf "%016X" ${gcm_ctx_hh[i]}) "
done 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. # Feed any additional authenticated data into the computation for the authentication tag.
for (( i=0; i < aad_len; i+=use_len )); do for (( i=0; i < aad_len; i+=use_len )); do
[[ $((aad_len-i)) -lt 16 ]] && use_len=$((aad_len-i)) || use_len=16 [[ $((aad_len-i)) -lt 16 ]] && use_len=$((aad_len-i)) || use_len=16
@ -11928,25 +11920,33 @@ gcm() {
done done
fi 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 # gcm_update
# Encrypt or decrypt the input and feed the ciphertext into the computation for the authentication tag. # 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 for (( length=input_len; length > 0; length=length-use_len )); do
[[ $length -lt 16 ]] && use_len=$length || use_len=16 [[ $length -lt 16 ]] && use_len=$length || use_len=16
y="$(inc32 "$y")" if [[ $use_len -eq 16 ]]; then
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"')" 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
for (( i=0; i < use_len; i++ )); do tmp=""
tmp="$(printf "%02X" $((0x${ectr:$((2*i)):2} ^ 0x${input:$((2*i)):2})))" for (( i=0; i < use_len; i++ )); do
output+="$tmp" tmp+="$(printf "%02X" $((0x${ectr:$((2*i)):2} ^ 0x${input:$((2*i)):2})))"
if "$compute_tag"; then done
if [[ $mode == encrypt ]]; then fi
gcm_ctx_buf[i]="$(printf "%02X" $((0x${gcm_ctx_buf[i]} ^ 0x$tmp)))" output+="$tmp"
else if "$compute_tag"; then
gcm_ctx_buf[i]="$(printf "%02X" $((0x${gcm_ctx_buf[i]} ^ 0x${input:$((2*i)):2})))" [[ $mode == decrypt ]] && tmp="${input:0:32}"
fi for (( i=0; i < use_len; i++ )); do
fi gcm_ctx_buf[i]="$(printf "%02X" $((0x${gcm_ctx_buf[i]} ^ 0x${tmp:$((2*i)):2})))"
done done
fi
ectr="${ectr:32}"
if "$compute_tag"; then 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]})" 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]})"