mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-24 17:37:30 +09:00
Replace NSS with Pale Moon's
This commit is contained in:
parent
ff1e5e48bf
commit
8c2e376f94
2870 changed files with 1762232 additions and 1374220 deletions
|
|
@ -85,11 +85,11 @@ endif
|
|||
# FREEBL_PRELINK_COMMAND
|
||||
#
|
||||
# This is an optional environment variable which can override the default
|
||||
# prelink command. It could be used on systems that did something similiar to
|
||||
# prelink but used a different command and syntax. The only requirement is the
|
||||
# program must take the library as the last argument, the program must output
|
||||
# the original library to standard out, and the program does not need to take
|
||||
# any quoted or imbedded spaces in its arguments (except the path to the
|
||||
# prelink command. It could be used on systems that did something similiar to
|
||||
# prelink but used a different command and syntax. The only requirement is the
|
||||
# program must take the library as the last argument, the program must output
|
||||
# the original library to standard out, and the program does not need to take
|
||||
# any quoted or imbedded spaces in its arguments (except the path to the
|
||||
# library itself, which can have imbedded spaces or special characters).
|
||||
#
|
||||
ifdef FREEBL_USE_PRELINK
|
||||
|
|
@ -101,6 +101,9 @@ endif
|
|||
ifdef NSS_NO_INIT_SUPPORT
|
||||
DEFINES += -DNSS_NO_INIT_SUPPORT
|
||||
endif
|
||||
ifdef NSS_STRICT_INTEGRITY
|
||||
DEFINES += -DNSS_STRICT_INTEGRITY_
|
||||
endif
|
||||
|
||||
ifdef FREEBL_PRELINK_COMMAND
|
||||
DEFINES +=-DFREEBL_PRELINK_COMMAND=\"$(FREEBL_PRELINK_COMMAND)\"
|
||||
|
|
@ -118,36 +121,66 @@ ifneq (,$(USE_64)$(USE_X32))
|
|||
else
|
||||
DEFINES += -DNSS_X86
|
||||
endif
|
||||
endif
|
||||
ifeq ($(CPU_ARCH),aarch64)
|
||||
DEFINES += -DUSE_HW_AES
|
||||
EXTRA_SRCS += aes-armv8.c gcm-aarch64.c
|
||||
endif
|
||||
ifeq ($(CPU_ARCH),arm)
|
||||
ifdef CC_IS_CLANG
|
||||
DEFINES += -DUSE_HW_AES
|
||||
EXTRA_SRCS += aes-armv8.c
|
||||
EXTRA_SRCS += sha256-x86.c
|
||||
DEFINES += -DUSE_HW_SHA2
|
||||
else ifeq (1,$(CC_IS_GCC))
|
||||
# Old compiler doesn't support ARM AES.
|
||||
# Old compiler doesn't support Intel SHA extension
|
||||
ifneq (,$(filter 4.9,$(word 1,$(GCC_VERSION)).$(word 2,$(GCC_VERSION))))
|
||||
DEFINES += -DUSE_HW_AES
|
||||
EXTRA_SRCS += aes-armv8.c
|
||||
EXTRA_SRCS += sha256-x86.c
|
||||
DEFINES += -DUSE_HW_SHA2
|
||||
endif
|
||||
ifeq (,$(filter 0 1 2 3 4,$(word 1,$(GCC_VERSION))))
|
||||
DEFINES += -DUSE_HW_AES
|
||||
EXTRA_SRCS += aes-armv8.c
|
||||
EXTRA_SRCS += sha256-x86.c
|
||||
DEFINES += -DUSE_HW_SHA2
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifeq ($(CPU_ARCH),aarch64)
|
||||
ifdef CC_IS_CLANG
|
||||
DEFINES += -DUSE_HW_AES -DUSE_HW_SHA1 -DUSE_HW_SHA2
|
||||
EXTRA_SRCS += aes-armv8.c gcm-aarch64.c sha1-armv8.c sha256-armv8.c
|
||||
else ifeq (1,$(CC_IS_GCC))
|
||||
# GCC versions older than 4.9 don't support ARM AES. The check
|
||||
# is done in two parts, first allows "major.minor" == "4.9",
|
||||
# and then rejects any major versions prior to 5. Note that
|
||||
# there has been no GCC 4.10, as it was renamed to GCC 5.
|
||||
ifneq (,$(filter 4.9,$(word 1,$(GCC_VERSION)).$(word 2,$(GCC_VERSION))))
|
||||
DEFINES += -DUSE_HW_AES -DUSE_HW_SHA1 -DUSE_HW_SHA2
|
||||
EXTRA_SRCS += aes-armv8.c gcm-aarch64.c sha1-armv8.c sha256-armv8.c
|
||||
endif
|
||||
ifeq (,$(filter 0 1 2 3 4,$(word 1,$(GCC_VERSION))))
|
||||
DEFINES += -DUSE_HW_AES -DUSE_HW_SHA1 -DUSE_HW_SHA2
|
||||
EXTRA_SRCS += aes-armv8.c gcm-aarch64.c sha1-armv8.c sha256-armv8.c
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifeq ($(CPU_ARCH),arm)
|
||||
ifndef NSS_DISABLE_ARM32_NEON
|
||||
EXTRA_SRCS += gcm-arm32-neon.c
|
||||
endif
|
||||
ifdef CC_IS_CLANG
|
||||
DEFINES += -DUSE_HW_AES -DUSE_HW_SHA1 -DUSE_HW_SHA2
|
||||
EXTRA_SRCS += aes-armv8.c sha1-armv8.c sha256-armv8.c
|
||||
else ifeq (1,$(CC_IS_GCC))
|
||||
# GCC versions older than 4.9 don't support ARM AES. The check
|
||||
# is done in two parts, first allows "major.minor" == "4.9",
|
||||
# and then rejects any major versions prior to 5. Note that
|
||||
# there has been no GCC 4.10, as it was renamed to GCC 5.
|
||||
ifneq (,$(filter 4.9,$(word 1,$(GCC_VERSION)).$(word 2,$(GCC_VERSION))))
|
||||
DEFINES += -DUSE_HW_AES -DUSE_HW_SHA1 -DUSE_HW_SHA2
|
||||
EXTRA_SRCS += aes-armv8.c sha1-armv8.c sha256-armv8.c
|
||||
endif
|
||||
ifeq (,$(filter 0 1 2 3 4,$(word 1,$(GCC_VERSION))))
|
||||
DEFINES += -DUSE_HW_AES -DUSE_HW_SHA1 -DUSE_HW_SHA2
|
||||
EXTRA_SRCS += aes-armv8.c sha1-armv8.c sha256-armv8.c
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(OS_TARGET),OSF1)
|
||||
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_NO_MP_WORD
|
||||
MPI_SRCS += mpvalpha.c
|
||||
endif
|
||||
|
||||
ifeq (OS2,$(OS_TARGET))
|
||||
ASFILES = mpi_x86_os2.s
|
||||
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
|
||||
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
|
||||
DEFINES += -DMP_ASSEMBLY_DIV_2DX1D
|
||||
DEFINES += -DMP_USE_UINT_DIGIT -DMP_NO_MP_WORD
|
||||
DEFINES += -DMP_IS_LITTLE_ENDIAN
|
||||
|
|
@ -168,7 +201,7 @@ ifdef NS_USE_GCC
|
|||
else
|
||||
# MSVC
|
||||
MPI_SRCS += mpi_x86_asm.c
|
||||
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
|
||||
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
|
||||
DEFINES += -DMP_ASSEMBLY_DIV_2DX1D -DMP_USE_UINT_DIGIT -DMP_NO_MP_WORD
|
||||
ifdef BUILD_OPT
|
||||
OPTIMIZER += -Ox # maximum optimization for freebl
|
||||
|
|
@ -183,6 +216,11 @@ else
|
|||
INTEL_GCM_CLANG_CL = 1
|
||||
endif
|
||||
endif
|
||||
# The Intel SHA extenstion requires Visual C++ 2015.
|
||||
ifeq ($(_MSC_VER_GE_14),1)
|
||||
DEFINES += -DUSE_HW_SHA2
|
||||
EXTRA_SRCS += sha256-x86.c
|
||||
endif
|
||||
endif
|
||||
else
|
||||
# -DMP_NO_MP_WORD
|
||||
|
|
@ -195,6 +233,7 @@ else
|
|||
ifdef BUILD_OPT
|
||||
OPTIMIZER += -Ox # maximum optimization for freebl
|
||||
endif
|
||||
ifeq ($(CPU_ARCH),x86_64)
|
||||
ASFILES = arcfour-amd64-masm.asm mpi_amd64_masm.asm mp_comba_amd64_masm.asm
|
||||
DEFINES += -DNSS_BEVAND_ARCFOUR -DMPI_AMD64 -DMP_ASSEMBLY_MULTIPLY
|
||||
DEFINES += -DNSS_USE_COMBA
|
||||
|
|
@ -208,26 +247,24 @@ else
|
|||
INTEL_GCM_CLANG_CL = 1
|
||||
endif
|
||||
endif
|
||||
# The Intel SHA extenstion requires Visual C++ 2015.
|
||||
ifeq ($(_MSC_VER_GE_14),1)
|
||||
DEFINES += -DUSE_HW_SHA2
|
||||
EXTRA_SRCS += sha256-x86.c
|
||||
endif
|
||||
MPI_SRCS += mpi_amd64.c
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(OS_TARGET),IRIX)
|
||||
ifeq ($(USE_N32),1)
|
||||
ASFILES = mpi_mips.s
|
||||
ifeq ($(NS_USE_GCC),1)
|
||||
ASFLAGS = -Wp,-P -Wp,-traditional -O -mips3
|
||||
else
|
||||
ASFLAGS = -O -OPT:Olimit=4000 -dollar -fullwarn -xansi -n32 -mips3
|
||||
endif
|
||||
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
|
||||
DEFINES += -DMP_USE_UINT_DIGIT
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(OS_TARGET),Darwin)
|
||||
ifeq ($(CPU_ARCH),x86)
|
||||
ifeq ($(CPU_ARCH),x86_64)
|
||||
ASFILES = mpi_amd64_common.s
|
||||
DEFINES += -DMPI_AMD64 -DMP_IS_LITTLE_ENDIAN
|
||||
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DNSS_USE_COMBA
|
||||
MPI_SRCS += mpi_amd64.c mp_comba.c
|
||||
else ifeq ($(CPU_ARCH),x86)
|
||||
ASFILES = mpi_sse2.s
|
||||
DEFINES += -DMP_USE_UINT_DIGIT
|
||||
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
|
||||
|
|
@ -237,7 +274,8 @@ endif # Darwin
|
|||
|
||||
ifeq ($(OS_TARGET),Linux)
|
||||
ifeq ($(CPU_ARCH),x86_64)
|
||||
ASFILES = arcfour-amd64-gas.s mpi_amd64_gas.s
|
||||
# Lower case s on mpi_amd64_common due to make implicit rules.
|
||||
ASFILES = arcfour-amd64-gas.s mpi_amd64_common.s
|
||||
ASFLAGS += -fPIC -Wa,--noexecstack
|
||||
DEFINES += -DNSS_BEVAND_ARCFOUR -DMPI_AMD64 -DMP_ASSEMBLY_MULTIPLY
|
||||
DEFINES += -DNSS_USE_COMBA
|
||||
|
|
@ -252,12 +290,12 @@ ifeq ($(CPU_ARCH),x86_64)
|
|||
endif
|
||||
ifeq ($(CPU_ARCH),x86)
|
||||
ASFILES = mpi_x86.s
|
||||
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
|
||||
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
|
||||
DEFINES += -DMP_ASSEMBLY_DIV_2DX1D -DMP_USE_UINT_DIGIT
|
||||
DEFINES += -DMP_IS_LITTLE_ENDIAN
|
||||
endif
|
||||
ifeq ($(CPU_ARCH),arm)
|
||||
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
|
||||
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
|
||||
DEFINES += -DMP_USE_UINT_DIGIT
|
||||
DEFINES += -DSHA_NO_LONG_LONG # avoid 64-bit arithmetic in SHA512
|
||||
MPI_SRCS += mpi_arm.c
|
||||
|
|
@ -266,6 +304,15 @@ ifeq ($(CPU_ARCH),ppc)
|
|||
EXTRA_SRCS += gcm-ppc.c
|
||||
ifdef USE_64
|
||||
DEFINES += -DNSS_NO_INIT_SUPPORT
|
||||
PPC_ABI := $(shell $(CC) -dM -E - < /dev/null | awk '$$2 == "_CALL_ELF" {print $$3}')
|
||||
ifeq ($(PPC_ABI),2)
|
||||
ASFILES += sha512-p8.s
|
||||
ifeq ($(OS_TEST),ppc64le)
|
||||
DEFINES += -DPPC_GCM
|
||||
EXTRA_SRCS += chacha20poly1305-ppc.c ppc-gcm-wrap.c
|
||||
ASFILES += chacha20-ppc64le.s ppc-gcm.s
|
||||
endif # ppc64le
|
||||
endif
|
||||
endif # USE_64
|
||||
endif # ppc
|
||||
endif # Linux
|
||||
|
|
@ -282,7 +329,7 @@ ifneq ($(OS_TEST), ia64)
|
|||
# PA-RISC
|
||||
ASFILES += ret_cr16.s
|
||||
ifndef USE_64
|
||||
FREEBL_BUILD_SINGLE_SHLIB =
|
||||
FREEBL_BUILD_SINGLE_SHLIB =
|
||||
HAVE_ABI32_INT32 = 1
|
||||
HAVE_ABI32_FPU = 1
|
||||
endif
|
||||
|
|
@ -293,15 +340,15 @@ ifdef USE_ABI32_INT32
|
|||
DEFINES += -DSHA_NO_LONG_LONG # avoid 64-bit arithmetic in SHA512
|
||||
else
|
||||
ifdef USE_64
|
||||
# this builds for DA2.0W (HP PA 2.0 Wide), the LP64 ABI, using 64-bit digits
|
||||
MPI_SRCS += mpi_hp.c
|
||||
ASFILES += hpma512.s hppa20.s
|
||||
# this builds for DA2.0W (HP PA 2.0 Wide), the LP64 ABI, using 64-bit digits
|
||||
MPI_SRCS += mpi_hp.c
|
||||
ASFILES += hpma512.s hppa20.s
|
||||
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
|
||||
else
|
||||
# this builds for DA2.0 (HP PA 2.0 Narrow) ABI32_FPU model
|
||||
# this builds for DA2.0 (HP PA 2.0 Narrow) ABI32_FPU model
|
||||
# (the 32-bit ABI with 64-bit registers) using 64-bit digits
|
||||
MPI_SRCS += mpi_hp.c
|
||||
ASFILES += hpma512.s hppa20.s
|
||||
MPI_SRCS += mpi_hp.c
|
||||
ASFILES += hpma512.s hppa20.s
|
||||
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
|
||||
ifndef NS_USE_GCC
|
||||
ARCHFLAG = -Aa +e +DA2.0 +DS2.0
|
||||
|
|
@ -336,7 +383,7 @@ else
|
|||
endif # NS_USE_GCC
|
||||
|
||||
# Sun's WorkShop defines v8, v8plus and v9 architectures.
|
||||
# gcc on Solaris defines v8 and v9 "cpus".
|
||||
# gcc on Solaris defines v8 and v9 "cpus".
|
||||
# gcc's v9 is equivalent to Workshop's v8plus.
|
||||
# gcc's -m64 is equivalent to Workshop's v9
|
||||
# We always use Sun's assembler, which uses Sun's naming convention.
|
||||
|
|
@ -386,7 +433,7 @@ ifeq ($(CPU_ARCH),sparc)
|
|||
FPU_TARGET_OPTIMIZER = -xchip=ultra2
|
||||
endif
|
||||
ifdef USE_ABI32_INT64
|
||||
# this builds for Sparc v8+a ABI32_FPU architecture, 64-bit registers,
|
||||
# this builds for Sparc v8+a ABI32_FPU architecture, 64-bit registers,
|
||||
# 32-bit ABI, it uses 64-bit words, integer arithmetic,
|
||||
# no FPU (non-VIS cpus).
|
||||
# These flags were suggested by the compiler group for building
|
||||
|
|
@ -399,7 +446,7 @@ ifeq ($(CPU_ARCH),sparc)
|
|||
SOLARIS_AS_FLAGS = -xarch=v8plus -K PIC
|
||||
endif
|
||||
ifdef USE_ABI32_FPU
|
||||
# this builds for Sparc v8+a ABI32_FPU architecture, 64-bit registers,
|
||||
# this builds for Sparc v8+a ABI32_FPU architecture, 64-bit registers,
|
||||
# 32-bit ABI, it uses FPU code, and 32-bit word size.
|
||||
# these flags were determined by running cc -### -fast and copying
|
||||
# the generated flag settings
|
||||
|
|
@ -441,12 +488,12 @@ ifeq ($(CPU_ARCH),sparc)
|
|||
|
||||
### set flags for both GCC and Sun cc
|
||||
ifdef USE_ABI32_INT64
|
||||
# this builds for Sparc v8+a ABI32_FPU architecture, 64-bit registers,
|
||||
# this builds for Sparc v8+a ABI32_FPU architecture, 64-bit registers,
|
||||
# 32-bit ABI, it uses 64-bit words, integer arithmetic, no FPU
|
||||
# best times are with no MP_ flags specified
|
||||
endif
|
||||
ifdef USE_ABI32_FPU
|
||||
# this builds for Sparc v8+a ABI32_FPU architecture, 64-bit registers,
|
||||
# this builds for Sparc v8+a ABI32_FPU architecture, 64-bit registers,
|
||||
# 32-bit ABI, it uses FPU code, and 32-bit word size
|
||||
MPI_SRCS += mpi_sparc.c
|
||||
ASFILES = mpv_sparcv8.s montmulfv8.s
|
||||
|
|
@ -476,7 +523,7 @@ else
|
|||
ifeq ($(USE_64),1)
|
||||
# Solaris for AMD64
|
||||
ifdef NS_USE_GCC
|
||||
ASFILES = arcfour-amd64-gas.s mpi_amd64_gas.s
|
||||
ASFILES = arcfour-amd64-gas.s mpi_amd64_common.s
|
||||
ASFLAGS += -march=opteron -m64 -fPIC
|
||||
MPI_SRCS += mp_comba.c
|
||||
# comment the next four lines to turn off Intel HW acceleration
|
||||
|
|
@ -502,7 +549,7 @@ else
|
|||
else
|
||||
# Solaris x86
|
||||
DEFINES += -DMP_USE_UINT_DIGIT
|
||||
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
|
||||
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
|
||||
DEFINES += -DMP_ASSEMBLY_DIV_2DX1D
|
||||
ASFILES = mpi_i86pc.s
|
||||
ifndef NS_USE_GCC
|
||||
|
|
@ -525,51 +572,50 @@ ifneq ($(shell $(CC) -? 2>&1 >/dev/null </dev/null | sed -e 's/:.*//;1q'),lcc)
|
|||
HAVE_INT128_SUPPORT = 1
|
||||
DEFINES += -DHAVE_INT128_SUPPORT
|
||||
endif
|
||||
ifneq (,$(filter 0 1 2 3 4,$(word 1,$(GCC_VERSION))))
|
||||
NSS_DISABLE_AVX2 = 1
|
||||
endif
|
||||
ifeq (,$(filter 0 1 2 3 4,$(word 1,$(GCC_VERSION))))
|
||||
HAVE_INT128_SUPPORT = 1
|
||||
DEFINES += -DHAVE_INT128_SUPPORT
|
||||
endif
|
||||
ifeq (,$(filter 0 1 2 3 4,$(word 1,$(GCC_VERSION))))
|
||||
NSS_DISABLE_SSE3 = 1
|
||||
NSS_DISABLE_SSE4_1 = 1
|
||||
NSS_DISABLE_SSE4_2 = 1
|
||||
endif
|
||||
endif
|
||||
endif # lcc
|
||||
endif # USE_64
|
||||
|
||||
ifndef HAVE_INT128_SUPPORT
|
||||
DEFINES += -DKRML_NOUINT128
|
||||
DEFINES += -DKRML_VERIFIED_UINT128
|
||||
endif
|
||||
|
||||
ifndef NSS_DISABLE_CHACHAPOLY
|
||||
ifeq ($(CPU_ARCH),x86_64)
|
||||
ifdef HAVE_INT128_SUPPORT
|
||||
EXTRA_SRCS += Hacl_Poly1305_64.c
|
||||
else
|
||||
EXTRA_SRCS += Hacl_Poly1305_32.c
|
||||
endif
|
||||
else
|
||||
ifeq ($(CPU_ARCH),aarch64)
|
||||
EXTRA_SRCS += Hacl_Poly1305_64.c
|
||||
else
|
||||
EXTRA_SRCS += Hacl_Poly1305_32.c
|
||||
ifndef NSS_DISABLE_AVX2
|
||||
EXTRA_SRCS += Hacl_Poly1305_256.c Hacl_Chacha20_Vec256.c Hacl_Chacha20Poly1305_256.c
|
||||
DEFINES += -DHACL_CAN_COMPILE_VEC256
|
||||
endif # NSS_DISABLE_AVX2
|
||||
ifndef NSS_DISABLE_SSE3
|
||||
EXTRA_SRCS += Hacl_Poly1305_128.c Hacl_Chacha20_Vec128.c Hacl_Chacha20Poly1305_128.c
|
||||
DEFINES += -DHACL_CAN_COMPILE_VEC128
|
||||
endif
|
||||
endif # x86_64
|
||||
|
||||
VERIFIED_SRCS += Hacl_Chacha20.c
|
||||
VERIFIED_SRCS += Hacl_Chacha20_Vec128.c
|
||||
VERIFIED_SRCS += Hacl_Poly1305_32.c Hacl_Chacha20.c Hacl_Chacha20Poly1305_32.c
|
||||
endif # NSS_DISABLE_CHACHAPOLY
|
||||
|
||||
ifeq (,$(filter-out i386 x386 x86 x86_64 aarch64,$(CPU_ARCH)))
|
||||
# All intel architectures get the 64 bit version
|
||||
# With custom uint128 if necessary (faster than generic 32 bit version).
|
||||
ifeq (,$(filter-out x86_64 aarch64,$(CPU_ARCH)))
|
||||
# All 64-bit architectures get the 64 bit version.
|
||||
ECL_SRCS += curve25519_64.c
|
||||
VERIFIED_SRCS += Hacl_Curve25519.c
|
||||
VERIFIED_SRCS += Hacl_Curve25519_51.c
|
||||
else
|
||||
# All non intel architectures get the generic 32 bit implementation (slow!)
|
||||
# All other architectures get the generic 32 bit implementation
|
||||
ECL_SRCS += curve25519_32.c
|
||||
endif
|
||||
|
||||
ifndef HAVE_INT128_SUPPORT
|
||||
VERIFIED_SRCS += FStar.c
|
||||
endif
|
||||
|
||||
#######################################################################
|
||||
# (5) Execute "global" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
|
@ -586,24 +632,23 @@ include $(CORE_DEPTH)/coreconf/rules.mk
|
|||
# (7) Execute "local" rules. (OPTIONAL). #
|
||||
#######################################################################
|
||||
|
||||
export:: private_export
|
||||
|
||||
rijndael_tables:
|
||||
$(CC) -o $(OBJDIR)/make_rijndael_tab rijndael_tables.c \
|
||||
$(DEFINES) $(INCLUDES) $(OBJDIR)/libfreebl.a
|
||||
$(OBJDIR)/make_rijndael_tab
|
||||
|
||||
vpath %.h mpi ecl verified
|
||||
vpath %.c mpi ecl verified
|
||||
vpath %.h mpi ecl verified deprecated
|
||||
vpath %.c mpi ecl verified deprecated
|
||||
vpath %.S mpi ecl
|
||||
vpath %.s mpi ecl
|
||||
vpath %.asm mpi ecl
|
||||
INCLUDES += -Impi -Iecl -Iverified
|
||||
INCLUDES += -Impi -Iecl -Iverified -Iverified/internal -Iverified/karamel/include -Iverified/karamel/krmllib/dist/minimal -Ideprecated
|
||||
|
||||
|
||||
DEFINES += -DMP_API_COMPATIBLE
|
||||
|
||||
MPI_USERS = dh.c pqg.c dsa.c rsa.c ec.c
|
||||
MPI_USERS = secmpi.c dh.c pqg.c dsa.c rsa.c ec.c
|
||||
|
||||
MPI_OBJS = $(addprefix $(OBJDIR)/$(PROG_PREFIX), $(MPI_SRCS:.c=$(OBJ_SUFFIX)))
|
||||
MPI_OBJS += $(addprefix $(OBJDIR)/$(PROG_PREFIX), $(MPI_USERS:.c=$(OBJ_SUFFIX)))
|
||||
|
|
@ -625,12 +670,10 @@ $(OBJDIR)/ldvector$(OBJ_SUFFIX) $(OBJDIR)/loader$(OBJ_SUFFIX) : loader.h
|
|||
|
||||
ifeq ($(SYSV_SPARC),1)
|
||||
|
||||
$(OBJDIR)/mpv_sparcv8.o $(OBJDIR)/mpv_sparcv8x.o $(OBJDIR)/montmulfv8.o : $(OBJDIR)/%.o : %.s
|
||||
@$(MAKE_OBJDIR)
|
||||
$(OBJDIR)/mpv_sparcv8.o $(OBJDIR)/mpv_sparcv8x.o $(OBJDIR)/montmulfv8.o : $(OBJDIR)/%.o : %.s | $$(@D)/d
|
||||
$(SOLARIS_AS) -o $@ $(SOLARIS_AS_FLAGS) $<
|
||||
|
||||
$(OBJDIR)/mpv_sparcv9.o $(OBJDIR)/montmulfv9.o : $(OBJDIR)/%.o : %.s
|
||||
@$(MAKE_OBJDIR)
|
||||
$(OBJDIR)/mpv_sparcv9.o $(OBJDIR)/montmulfv9.o : $(OBJDIR)/%.o : %.s | $$(@D)/d
|
||||
$(SOLARIS_AS) -o $@ $(SOLARIS_AS_FLAGS) $<
|
||||
|
||||
$(OBJDIR)/mpmontg.o: mpmontg.c montmulf.h
|
||||
|
|
@ -641,103 +684,35 @@ ifndef FREEBL_CHILD_BUILD
|
|||
|
||||
# Parent build. This is where we decide which shared libraries to build
|
||||
|
||||
ifdef FREEBL_BUILD_SINGLE_SHLIB
|
||||
# too suppress the SINGLE_SHLIB override warning
|
||||
FREEBL_OBJDIRS :=
|
||||
|
||||
################### Single shared lib stuff #########################
|
||||
SINGLE_SHLIB_DIR = $(OBJDIR)/$(OS_TARGET)_SINGLE_SHLIB
|
||||
ALL_TRASH += $(SINGLE_SHLIB_DIR)
|
||||
|
||||
$(SINGLE_SHLIB_DIR):
|
||||
-mkdir -p $(SINGLE_SHLIB_DIR)
|
||||
|
||||
release_md libs:: $(SINGLE_SHLIB_DIR)
|
||||
$(MAKE) FREEBL_CHILD_BUILD=1 \
|
||||
OBJDIR=$(SINGLE_SHLIB_DIR) $@
|
||||
######################## common stuff #########################
|
||||
define target_freebl_SHLIB
|
||||
ifdef $(2)
|
||||
$(1)_DIR = $$(OBJDIR)/$$(OS_TARGET)_$(1)
|
||||
ALL_TRASH += $$($(1)_DIR)
|
||||
|
||||
ifeq (,$$(filter $$($(1)_DIR)/d,$$(FREEBL_OBJDIRS)))
|
||||
FREEBL_OBJDIRS += $$($(1)_DIR)/d
|
||||
endif
|
||||
|
||||
ifdef NEED_STUB_BUILD
|
||||
SINGLE_SHLIB_DIR = $(OBJDIR)/$(OS_TARGET)_SINGLE_SHLIB
|
||||
ALL_TRASH += $(SINGLE_SHLIB_DIR)
|
||||
$(SINGLE_SHLIB_DIR):
|
||||
-mkdir $(SINGLE_SHLIB_DIR)
|
||||
|
||||
release_md libs:: $(SINGLE_SHLIB_DIR)
|
||||
$(MAKE) FREEBL_CHILD_BUILD=1 USE_STUB_BUILD=1 \
|
||||
OBJDIR=$(SINGLE_SHLIB_DIR) $@
|
||||
release_md:: freebl_$(2)
|
||||
libs: freebl_$(2)
|
||||
freebl_$(2): | $$($(1)_DIR)/d
|
||||
$$(MAKE) FREEBL_CHILD_BUILD=1 $(3)=1 OBJDIR=$$($(1)_DIR) libs
|
||||
endif
|
||||
endef # target_freebl_SHLIB
|
||||
|
||||
# multiple shared libraries
|
||||
target_freebl_ABI = $(call target_freebl_SHLIB,$(1),HAVE_$(1),USE_$(1))
|
||||
|
||||
######################## ABI32_FPU stuff #########################
|
||||
ifdef HAVE_ABI32_FPU
|
||||
ABI32_FPU_DIR = $(OBJDIR)/$(OS_TARGET)_ABI32_FPU
|
||||
ALL_TRASH += $(ABI32_FPU_DIR)
|
||||
$(eval $(call target_freebl_SHLIB,SINGLE_SHLIB,FREEBL_BUILD_SINGLE_SHLIB,NEEDED_DUMMY))
|
||||
$(eval $(call target_freebl_SHLIB,SINGLE_SHLIB,NEED_STUB_BUILD,USE_STUB_BUILD))
|
||||
|
||||
$(ABI32_FPU_DIR):
|
||||
-mkdir $(ABI32_FPU_DIR)
|
||||
|
||||
release_md libs:: $(ABI32_FPU_DIR)
|
||||
$(MAKE) FREEBL_CHILD_BUILD=1 USE_ABI32_FPU=1 \
|
||||
OBJDIR=$(ABI32_FPU_DIR) $@
|
||||
endif
|
||||
|
||||
######################## ABI32_INT32 stuff #########################
|
||||
ifdef HAVE_ABI32_INT32
|
||||
ABI32_INT32_DIR = $(OBJDIR)/$(OS_TARGET)_ABI32_INT32
|
||||
ALL_TRASH += $(ABI32_INT32_DIR)
|
||||
|
||||
$(ABI32_INT32_DIR):
|
||||
-mkdir $(ABI32_INT32_DIR)
|
||||
|
||||
release_md libs:: $(ABI32_INT32_DIR)
|
||||
$(MAKE) FREEBL_CHILD_BUILD=1 USE_ABI32_INT32=1 \
|
||||
OBJDIR=$(ABI32_INT32_DIR) $@
|
||||
endif
|
||||
|
||||
######################## ABI32_INT64 stuff #########################
|
||||
ifdef HAVE_ABI32_INT64
|
||||
ABI32_INT64_DIR = $(OBJDIR)/$(OS_TARGET)_ABI32_INT64
|
||||
ALL_TRASH += $(ABI32_INT64_DIR)
|
||||
|
||||
$(ABI32_INT64_DIR):
|
||||
-mkdir $(ABI32_INT64_DIR)
|
||||
|
||||
release_md libs:: $(ABI32_INT64_DIR)
|
||||
$(MAKE) FREEBL_CHILD_BUILD=1 USE_ABI32_INT64=1\
|
||||
OBJDIR=$(ABI32_INT64_DIR) $@
|
||||
endif
|
||||
|
||||
######################## END of 32-bit stuff #########################
|
||||
|
||||
# above is 32-bit builds, below is 64-bit builds
|
||||
|
||||
######################## ABI64_FPU stuff #########################
|
||||
ifdef HAVE_ABI64_FPU
|
||||
ABI64_FPU_DIR = $(OBJDIR)/$(OS_TARGET)_ABI64_FPU
|
||||
ALL_TRASH += $(ABI64_FPU_DIR)
|
||||
|
||||
$(ABI64_FPU_DIR):
|
||||
-mkdir $(ABI64_FPU_DIR)
|
||||
|
||||
release_md libs:: $(ABI64_FPU_DIR)
|
||||
$(MAKE) FREEBL_CHILD_BUILD=1 USE_ABI64_FPU=1 \
|
||||
OBJDIR=$(ABI64_FPU_DIR) $@
|
||||
endif
|
||||
|
||||
######################## ABI64_INT stuff #########################
|
||||
ifdef HAVE_ABI64_INT
|
||||
ABI64_INT_DIR = $(OBJDIR)/$(OS_TARGET)_ABI64_INT
|
||||
ALL_TRASH += $(ABI64_INT_DIR)
|
||||
|
||||
$(ABI64_INT_DIR):
|
||||
-mkdir $(ABI64_INT_DIR)
|
||||
|
||||
release_md libs:: $(ABI64_INT_DIR)
|
||||
$(MAKE) FREEBL_CHILD_BUILD=1 USE_ABI64_INT=1 \
|
||||
OBJDIR=$(ABI64_INT_DIR) $@
|
||||
endif
|
||||
$(eval $(call target_freebl_ABI,ABI32_FPU))
|
||||
$(eval $(call target_freebl_ABI,ABI32_INT32))
|
||||
$(eval $(call target_freebl_ABI,ABI32_INT64))
|
||||
$(eval $(call target_freebl_ABI,ABI64_FPU))
|
||||
$(eval $(call target_freebl_ABI,ABI64_INT))
|
||||
|
||||
endif # FREEBL_CHILD_BUILD
|
||||
|
||||
|
|
@ -746,8 +721,7 @@ endif # FREEBL_CHILD_BUILD
|
|||
# ANSI C's strict aliasing rules.
|
||||
ifeq ($(OS_TARGET),Linux)
|
||||
ifneq ($(CPU_ARCH),x86)
|
||||
$(OBJDIR)/$(PROG_PREFIX)desblapi$(OBJ_SUFFIX): desblapi.c
|
||||
@$(MAKE_OBJDIR)
|
||||
$(OBJDIR)/$(PROG_PREFIX)desblapi$(OBJ_SUFFIX): desblapi.c | $$(@D)/d
|
||||
ifdef NEED_ABSOLUTE_PATH
|
||||
$(CC) -o $@ -c $(CFLAGS) -fno-strict-aliasing $(call core_abspath,$<)
|
||||
else
|
||||
|
|
@ -779,14 +753,52 @@ ifdef INTEL_GCM_CLANG_CL
|
|||
$(OBJDIR)/$(PROG_PREFIX)intel-gcm-wrap$(OBJ_SUFFIX): CFLAGS += -mssse3
|
||||
endif
|
||||
|
||||
$(OBJDIR)/$(PROG_PREFIX)sha256-x86$(OBJ_SUFFIX): CFLAGS += -msha -mssse3 -msse4.1
|
||||
|
||||
ifeq ($(CPU_ARCH),arm)
|
||||
$(OBJDIR)/$(PROG_PREFIX)aes-armv8$(OBJ_SUFFIX): CFLAGS += -march=armv8-a -mfpu=crypto-neon-fp-armv8
|
||||
# When the compiler uses the softfloat ABI, we want to use the compatible softfp ABI when
|
||||
# enabling NEON for these objects.
|
||||
# Confusingly, __SOFTFP__ is the name of the define for the softfloat ABI, not for the softfp ABI.
|
||||
USES_SOFTFLOAT_ABI := $(shell $(CC) -o - -E -dM - $(CFLAGS) < /dev/null | grep __SOFTFP__ > /dev/null && echo 1)
|
||||
$(OBJDIR)/$(PROG_PREFIX)aes-armv8$(OBJ_SUFFIX): CFLAGS += -march=armv8-a -mfpu=crypto-neon-fp-armv8$(if $(USES_SOFTFLOAT_ABI), -mfloat-abi=softfp)
|
||||
$(OBJDIR)/$(PROG_PREFIX)sha1-armv8$(OBJ_SUFFIX): CFLAGS += -march=armv8-a -mfpu=crypto-neon-fp-armv8$(if $(USES_SOFTFLOAT_ABI), -mfloat-abi=softfp)
|
||||
$(OBJDIR)/$(PROG_PREFIX)sha256-armv8$(OBJ_SUFFIX): CFLAGS += -march=armv8-a -mfpu=crypto-neon-fp-armv8$(if $(USES_SOFTFLOAT_ABI), -mfloat-abi=softfp)
|
||||
ifndef NSS_DISABLE_ARM32_NEON
|
||||
$(OBJDIR)/$(PROG_PREFIX)gcm-arm32-neon$(OBJ_SUFFIX): CFLAGS += -mfpu=neon$(if $(USES_SOFTFLOAT_ABI), -mfloat-abi=softfp)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CPU_ARCH),aarch64)
|
||||
$(OBJDIR)/$(PROG_PREFIX)aes-armv8$(OBJ_SUFFIX): CFLAGS += -march=armv8-a+crypto
|
||||
$(OBJDIR)/$(PROG_PREFIX)gcm-aarch64$(OBJ_SUFFIX): CFLAGS += -march=armv8-a+crypto
|
||||
$(OBJDIR)/$(PROG_PREFIX)sha1-armv8$(OBJ_SUFFIX): CFLAGS += -march=armv8-a+crypto
|
||||
$(OBJDIR)/$(PROG_PREFIX)sha256-armv8$(OBJ_SUFFIX): CFLAGS += -march=armv8-a+crypto
|
||||
endif
|
||||
|
||||
ifeq ($(CPU_ARCH),ppc)
|
||||
$(OBJDIR)/$(PROG_PREFIX)gcm-ppc$(OBJ_SUFFIX): CFLAGS += -mcrypto -maltivec
|
||||
$(OBJDIR)/$(PROG_PREFIX)sha512$(OBJ_SUFFIX): CFLAGS += -funroll-loops -fpeel-loops
|
||||
ifneq ($(NSS_DISABLE_ALTIVEC),1)
|
||||
$(OBJDIR)/$(PROG_PREFIX)gcm-ppc$(OBJ_SUFFIX): CFLAGS += -maltivec
|
||||
$(OBJDIR)/$(PROG_PREFIX)gcm$(OBJ_SUFFIX): CFLAGS += -maltivec
|
||||
$(OBJDIR)/$(PROG_PREFIX)rijndael$(OBJ_SUFFIX): CFLAGS += -maltivec
|
||||
$(OBJDIR)/$(PROG_PREFIX)sha512$(OBJ_SUFFIX): CFLAGS += -maltivec
|
||||
$(OBJDIR)/$(PROG_PREFIX)chacha20poly1305-ppc$(OBJ_SUFFIX): CFLAGS += -maltivec
|
||||
endif
|
||||
ifneq ($(NSS_DISABLE_CRYPTO_VSX),1)
|
||||
$(OBJDIR)/$(PROG_PREFIX)gcm-ppc$(OBJ_SUFFIX): CFLAGS += -mcrypto -mvsx
|
||||
$(OBJDIR)/$(PROG_PREFIX)gcm$(OBJ_SUFFIX): CFLAGS += -mcrypto -mvsx
|
||||
$(OBJDIR)/$(PROG_PREFIX)rijndael$(OBJ_SUFFIX): CFLAGS += -mcrypto -mvsx
|
||||
$(OBJDIR)/$(PROG_PREFIX)sha512$(OBJ_SUFFIX): CFLAGS += -mcrypto -mvsx
|
||||
$(OBJDIR)/$(PROG_PREFIX)chacha20poly1305-ppc$(OBJ_SUFFIX): CFLAGS += -mcrypto -mvsx
|
||||
endif
|
||||
endif
|
||||
|
||||
$(OBJDIR)/$(PROG_PREFIX)Hacl_Chacha20_Vec128$(OBJ_SUFFIX): CFLAGS += -mssse3 -msse4.1 -msse4.2 -mavx
|
||||
$(OBJDIR)/$(PROG_PREFIX)Hacl_Chacha20Poly1305_128$(OBJ_SUFFIX): CFLAGS += -mssse3 -msse4.1 -msse4.2 -mavx
|
||||
$(OBJDIR)/$(PROG_PREFIX)Hacl_Poly1305_128$(OBJ_SUFFIX): CFLAGS += -mssse3 -msse4.1 -msse4.2 -mavx
|
||||
|
||||
ifndef NSS_DISABLE_AVX2
|
||||
$(OBJDIR)/$(PROG_PREFIX)Hacl_Chacha20Poly1305_256$(OBJ_SUFFIX): CFLAGS += -mssse3 -msse4.1 -msse4.2 -mavx2
|
||||
$(OBJDIR)/$(PROG_PREFIX)Hacl_Chacha20_Vec256$(OBJ_SUFFIX): CFLAGS += -mssse3 -msse4.1 -msse4.2 -mavx -mavx2
|
||||
$(OBJDIR)/$(PROG_PREFIX)Hacl_Poly1305_256$(OBJ_SUFFIX): CFLAGS += -mssse3 -msse4.1 -msse4.2 -mavx -mavx2
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
#if ((defined(__clang__) || \
|
||||
(defined(__GNUC__) && defined(__GNUC_MINOR__) && \
|
||||
(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 8)))) && \
|
||||
(defined(__ARM_NEON) || defined(__ARM_NEON__)))
|
||||
defined(IS_LITTLE_ENDIAN))
|
||||
|
||||
#ifndef __ARM_FEATURE_CRYPTO
|
||||
#error "Compiler option is invalid"
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ native_key_expansion192(AESContext *cx, const unsigned char *key)
|
|||
pre_align __m128i tmp3 post_align;
|
||||
pre_align __m128i carry post_align;
|
||||
keySchedule[0] = _mm_loadu_si128((__m128i *)key);
|
||||
keySchedule[1] = _mm_loadu_si128((__m128i *)(key + 16));
|
||||
keySchedule[1] = _mm_loadl_epi64((__m128i *)(key + 16));
|
||||
EXPAND_KEY192(keySchedule[0], keySchedule[1], keySchedule[2],
|
||||
keySchedule[3], carry, 0x1, 0x2);
|
||||
EXPAND_KEY192_PART2(keySchedule[4], carry, keySchedule[3]);
|
||||
|
|
@ -146,7 +146,7 @@ rijndael_native_encryptBlock(AESContext *cx,
|
|||
unsigned char *output,
|
||||
const unsigned char *input)
|
||||
{
|
||||
int i;
|
||||
unsigned int i;
|
||||
pre_align __m128i m post_align = _mm_loadu_si128((__m128i *)input);
|
||||
m = _mm_xor_si128(m, cx->k.keySchedule[0]);
|
||||
for (i = 1; i < cx->Nr; ++i) {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@
|
|||
#include "stubs.h"
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "prcpucfg.h"
|
||||
#if defined(IS_LITTLE_ENDIAN) || defined(SHA_NO_LONG_LONG)
|
||||
#define BIG_ENDIAN_WITH_64_BIT_REGISTERS 0
|
||||
|
|
@ -196,11 +198,33 @@ set_t(unsigned char *pt, unsigned long t)
|
|||
|
||||
#endif
|
||||
|
||||
static void
|
||||
encode_PRUint32_BE(unsigned char *data, PRUint32 val)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < sizeof(PRUint32); i++) {
|
||||
data[i] = PORT_GET_BYTE_BE(val, i, sizeof(PRUint32));
|
||||
}
|
||||
}
|
||||
|
||||
static PRUint32
|
||||
decode_PRUint32_BE(unsigned char *data)
|
||||
{
|
||||
PRUint32 val = 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < sizeof(PRUint32); i++) {
|
||||
val = (val << PR_BITS_PER_BYTE) | data[i];
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
** Perform AES key wrap.
|
||||
** Perform AES key wrap W function.
|
||||
** "cx" the context
|
||||
** "iv" the iv is concatenated to the plain text for for executing the function
|
||||
** "output" the output buffer to store the encrypted data.
|
||||
** "outputLen" how much data is stored in "output". Set by the routine
|
||||
** "pOutputLen" how much data is stored in "output". Set by the routine
|
||||
** after some data is stored in output.
|
||||
** "maxOutputLen" the maximum amount of data that can ever be
|
||||
** stored in "output"
|
||||
|
|
@ -208,9 +232,9 @@ set_t(unsigned char *pt, unsigned long t)
|
|||
** "inputLen" the amount of input data
|
||||
*/
|
||||
extern SECStatus
|
||||
AESKeyWrap_Encrypt(AESKeyWrapContext *cx, unsigned char *output,
|
||||
unsigned int *pOutputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen)
|
||||
AESKeyWrap_W(AESKeyWrapContext *cx, unsigned char *iv, unsigned char *output,
|
||||
unsigned int *pOutputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen)
|
||||
{
|
||||
PRUint64 *R = NULL;
|
||||
unsigned int nBlocks;
|
||||
|
|
@ -251,7 +275,7 @@ AESKeyWrap_Encrypt(AESKeyWrapContext *cx, unsigned char *output,
|
|||
/*
|
||||
** 1) Initialize variables.
|
||||
*/
|
||||
memcpy(&A, cx->iv, AES_KEY_WRAP_IV_BYTES);
|
||||
memcpy(&A, iv, AES_KEY_WRAP_IV_BYTES);
|
||||
memcpy(&R[1], input, inputLen);
|
||||
#if BIG_ENDIAN_WITH_64_BIT_REGISTERS
|
||||
t = 0;
|
||||
|
|
@ -294,10 +318,12 @@ AESKeyWrap_Encrypt(AESKeyWrapContext *cx, unsigned char *output,
|
|||
#undef A
|
||||
|
||||
/*
|
||||
** Perform AES key unwrap.
|
||||
** Perform AES key wrap W^-1 function.
|
||||
** "cx" the context
|
||||
** "iv" the input IV to verify against. If NULL, then skip verification.
|
||||
** "ivOut" the output buffer to store the IV (optional).
|
||||
** "output" the output buffer to store the decrypted data.
|
||||
** "outputLen" how much data is stored in "output". Set by the routine
|
||||
** "pOutputLen" how much data is stored in "output". Set by the routine
|
||||
** after some data is stored in output.
|
||||
** "maxOutputLen" the maximum amount of data that can ever be
|
||||
** stored in "output"
|
||||
|
|
@ -305,9 +331,10 @@ AESKeyWrap_Encrypt(AESKeyWrapContext *cx, unsigned char *output,
|
|||
** "inputLen" the amount of input data
|
||||
*/
|
||||
extern SECStatus
|
||||
AESKeyWrap_Decrypt(AESKeyWrapContext *cx, unsigned char *output,
|
||||
unsigned int *pOutputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen)
|
||||
AESKeyWrap_Winv(AESKeyWrapContext *cx, unsigned char *iv,
|
||||
unsigned char *ivOut, unsigned char *output,
|
||||
unsigned int *pOutputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen)
|
||||
{
|
||||
PRUint64 *R = NULL;
|
||||
unsigned int nBlocks;
|
||||
|
|
@ -378,11 +405,14 @@ AESKeyWrap_Decrypt(AESKeyWrapContext *cx, unsigned char *output,
|
|||
** 3) Output the results.
|
||||
*/
|
||||
if (s == SECSuccess) {
|
||||
int bad = memcmp(&B[0], cx->iv, AES_KEY_WRAP_IV_BYTES);
|
||||
int bad = (iv) && memcmp(&B[0], iv, AES_KEY_WRAP_IV_BYTES);
|
||||
if (!bad) {
|
||||
memcpy(output, &R[1], outLen);
|
||||
if (pOutputLen)
|
||||
*pOutputLen = outLen;
|
||||
if (ivOut) {
|
||||
memcpy(ivOut, &B[0], AES_KEY_WRAP_IV_BYTES);
|
||||
}
|
||||
} else {
|
||||
s = SECFailure;
|
||||
PORT_SetError(SEC_ERROR_BAD_DATA);
|
||||
|
|
@ -396,3 +426,217 @@ AESKeyWrap_Decrypt(AESKeyWrapContext *cx, unsigned char *output,
|
|||
return s;
|
||||
}
|
||||
#undef A
|
||||
|
||||
/*
|
||||
** Perform AES key wrap.
|
||||
** "cx" the context
|
||||
** "output" the output buffer to store the encrypted data.
|
||||
** "pOutputLen" how much data is stored in "output". Set by the routine
|
||||
** after some data is stored in output.
|
||||
** "maxOutputLen" the maximum amount of data that can ever be
|
||||
** stored in "output"
|
||||
** "input" the input data
|
||||
** "inputLen" the amount of input data
|
||||
*/
|
||||
extern SECStatus
|
||||
AESKeyWrap_Encrypt(AESKeyWrapContext *cx, unsigned char *output,
|
||||
unsigned int *pOutputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen)
|
||||
{
|
||||
return AESKeyWrap_W(cx, cx->iv, output, pOutputLen, maxOutputLen,
|
||||
input, inputLen);
|
||||
}
|
||||
|
||||
/*
|
||||
** Perform AES key unwrap.
|
||||
** "cx" the context
|
||||
** "output" the output buffer to store the decrypted data.
|
||||
** "pOutputLen" how much data is stored in "output". Set by the routine
|
||||
** after some data is stored in output.
|
||||
** "maxOutputLen" the maximum amount of data that can ever be
|
||||
** stored in "output"
|
||||
** "input" the input data
|
||||
** "inputLen" the amount of input data
|
||||
*/
|
||||
extern SECStatus
|
||||
AESKeyWrap_Decrypt(AESKeyWrapContext *cx, unsigned char *output,
|
||||
unsigned int *pOutputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen)
|
||||
{
|
||||
return AESKeyWrap_Winv(cx, cx->iv, NULL, output, pOutputLen, maxOutputLen,
|
||||
input, inputLen);
|
||||
}
|
||||
|
||||
#define BLOCK_PAD_POWER2(x, bs) (((bs) - ((x) & ((bs)-1))) & ((bs)-1))
|
||||
#define AES_KEY_WRAP_ICV2 0xa6, 0x59, 0x59, 0xa6
|
||||
#define AES_KEY_WRAP_ICV2_INT32 0xa65959a6
|
||||
#define AES_KEY_WRAP_ICV2_LEN 4
|
||||
|
||||
/*
|
||||
** Perform AES key wrap with padding.
|
||||
** "cx" the context
|
||||
** "output" the output buffer to store the encrypted data.
|
||||
** "pOutputLen" how much data is stored in "output". Set by the routine
|
||||
** after some data is stored in output.
|
||||
** "maxOutputLen" the maximum amount of data that can ever be
|
||||
** stored in "output"
|
||||
** "input" the input data
|
||||
** "inputLen" the amount of input data
|
||||
*/
|
||||
extern SECStatus
|
||||
AESKeyWrap_EncryptKWP(AESKeyWrapContext *cx, unsigned char *output,
|
||||
unsigned int *pOutputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen)
|
||||
{
|
||||
unsigned int padLen = BLOCK_PAD_POWER2(inputLen, AES_KEY_WRAP_BLOCK_SIZE);
|
||||
unsigned int paddedInputLen = inputLen + padLen;
|
||||
unsigned int outLen = paddedInputLen + AES_KEY_WRAP_BLOCK_SIZE;
|
||||
unsigned char iv[AES_BLOCK_SIZE] = { AES_KEY_WRAP_ICV2 };
|
||||
unsigned char *newBuf;
|
||||
SECStatus rv;
|
||||
|
||||
*pOutputLen = outLen;
|
||||
if (maxOutputLen < outLen) {
|
||||
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
PORT_Assert((AES_KEY_WRAP_ICV2_LEN + sizeof(PRUint32)) == AES_KEY_WRAP_BLOCK_SIZE);
|
||||
encode_PRUint32_BE(iv + AES_KEY_WRAP_ICV2_LEN, inputLen);
|
||||
|
||||
/* If we can fit in an AES Block, just do and AES Encrypt,
|
||||
* iv is big enough to handle this on the stack, so no need to allocate
|
||||
*/
|
||||
if (outLen == AES_BLOCK_SIZE) {
|
||||
PORT_Assert(inputLen <= AES_KEY_WRAP_BLOCK_SIZE);
|
||||
PORT_Memset(iv + AES_KEY_WRAP_BLOCK_SIZE, 0, AES_KEY_WRAP_BLOCK_SIZE);
|
||||
PORT_Memcpy(iv + AES_KEY_WRAP_BLOCK_SIZE, input, inputLen);
|
||||
rv = AES_Encrypt(&cx->aescx, output, pOutputLen, maxOutputLen, iv,
|
||||
outLen);
|
||||
PORT_Memset(iv, 0, sizeof(iv));
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* add padding to our input block */
|
||||
newBuf = PORT_ZAlloc(paddedInputLen);
|
||||
if (newBuf == NULL) {
|
||||
return SECFailure;
|
||||
}
|
||||
PORT_Memcpy(newBuf, input, inputLen);
|
||||
|
||||
rv = AESKeyWrap_W(cx, iv, output, pOutputLen, maxOutputLen,
|
||||
newBuf, paddedInputLen);
|
||||
PORT_ZFree(newBuf, paddedInputLen);
|
||||
/* a little overkill, we only need to clear out the length, but this
|
||||
* is easier to verify we got it all */
|
||||
PORT_Memset(iv, 0, sizeof(iv));
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
** Perform AES key unwrap with padding.
|
||||
** "cx" the context
|
||||
** "output" the output buffer to store the decrypted data.
|
||||
** "pOutputLen" how much data is stored in "output". Set by the routine
|
||||
** after some data is stored in output.
|
||||
** "maxOutputLen" the maximum amount of data that can ever be
|
||||
** stored in "output"
|
||||
** "input" the input data
|
||||
** "inputLen" the amount of input data
|
||||
*/
|
||||
extern SECStatus
|
||||
AESKeyWrap_DecryptKWP(AESKeyWrapContext *cx, unsigned char *output,
|
||||
unsigned int *pOutputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen)
|
||||
{
|
||||
unsigned int padLen;
|
||||
unsigned int padLen2;
|
||||
unsigned int outLen;
|
||||
unsigned int paddedLen;
|
||||
unsigned int good;
|
||||
unsigned char *newBuf = NULL;
|
||||
unsigned char *allocBuf = NULL;
|
||||
int i;
|
||||
unsigned char iv[AES_BLOCK_SIZE];
|
||||
PRUint32 magic;
|
||||
SECStatus rv = SECFailure;
|
||||
|
||||
paddedLen = inputLen - AES_KEY_WRAP_BLOCK_SIZE;
|
||||
/* unwrap the padded result */
|
||||
if (inputLen == AES_BLOCK_SIZE) {
|
||||
rv = AES_Decrypt(&cx->aescx, iv, &outLen, inputLen, input, inputLen);
|
||||
newBuf = &iv[AES_KEY_WRAP_BLOCK_SIZE];
|
||||
outLen -= AES_KEY_WRAP_BLOCK_SIZE;
|
||||
} else {
|
||||
/* if the caller supplied enough space to hold the unpadded buffer,
|
||||
* we can unwrap directly into that unpadded buffer. Otherwise
|
||||
* we allocate a buffer that can hold the padding, and we'll copy
|
||||
* the result in a later step */
|
||||
newBuf = output;
|
||||
if (maxOutputLen < paddedLen) {
|
||||
allocBuf = newBuf = PORT_Alloc(paddedLen);
|
||||
if (!allocBuf) {
|
||||
return SECFailure;
|
||||
}
|
||||
}
|
||||
/* We pass NULL for the first IV argument because we don't know
|
||||
* what the IV has since in includes the length, so we don't have
|
||||
* Winv verify it. We pass iv in the second argument to get the
|
||||
* iv, which we verify below before we return anything */
|
||||
rv = AESKeyWrap_Winv(cx, NULL, iv, newBuf, &outLen,
|
||||
paddedLen, input, inputLen);
|
||||
}
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
rv = SECFailure;
|
||||
if (outLen != paddedLen) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* we verify the result in a constant time manner */
|
||||
/* verify ICV magic */
|
||||
magic = decode_PRUint32_BE(iv);
|
||||
good = PORT_CT_EQ(magic, AES_KEY_WRAP_ICV2_INT32);
|
||||
/* fetch and verify plain text length */
|
||||
outLen = decode_PRUint32_BE(iv + AES_KEY_WRAP_ICV2_LEN);
|
||||
good &= PORT_CT_LE(outLen, paddedLen);
|
||||
/* now verify the padding */
|
||||
padLen = paddedLen - outLen;
|
||||
padLen2 = BLOCK_PAD_POWER2(outLen, AES_KEY_WRAP_BLOCK_SIZE);
|
||||
good &= PORT_CT_EQ(padLen, padLen2);
|
||||
for (i = 0; i < AES_KEY_WRAP_BLOCK_SIZE; i++) {
|
||||
unsigned int doTest = PORT_CT_GT(padLen, i);
|
||||
unsigned int result = PORT_CT_ZERO(newBuf[paddedLen - i - 1]);
|
||||
good &= PORT_CT_SEL(doTest, result, PORT_CT_TRUE);
|
||||
}
|
||||
|
||||
/* now if anything was wrong, fail. At this point we will leak timing
|
||||
* information, but we also 'leak' the error code as well. */
|
||||
if (!good) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DATA);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* now copy out the result */
|
||||
*pOutputLen = outLen;
|
||||
if (maxOutputLen < outLen) {
|
||||
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
|
||||
goto loser;
|
||||
}
|
||||
if (output != newBuf) {
|
||||
PORT_Memcpy(output, newBuf, outLen);
|
||||
}
|
||||
rv = SECSuccess;
|
||||
loser:
|
||||
/* if we failed, make sure we don't return any data to the user */
|
||||
if ((rv != SECSuccess) && (output == newBuf)) {
|
||||
PORT_Memset(newBuf, 0, paddedLen);
|
||||
}
|
||||
/* clear out CSP sensitive data from the heap and stack */
|
||||
if (allocBuf) {
|
||||
PORT_ZFree(allocBuf, paddedLen);
|
||||
}
|
||||
PORT_Memset(iv, 0, sizeof(iv));
|
||||
return rv;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,27 +37,18 @@ HMAC_Destroy(HMACContext *cx, PRBool freeit)
|
|||
PORT_Free(cx);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
HMAC_Init(HMACContext *cx, const SECHashObject *hash_obj,
|
||||
const unsigned char *secret, unsigned int secret_len, PRBool isFIPS)
|
||||
static SECStatus
|
||||
hmac_initKey(HMACContext *cx, const unsigned char *secret,
|
||||
unsigned int secret_len, PRBool isFIPS)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned char hashed_secret[HASH_LENGTH_MAX];
|
||||
|
||||
/* required by FIPS 198 Section 3 */
|
||||
if (isFIPS && secret_len < hash_obj->length / 2) {
|
||||
if (isFIPS && secret_len < cx->hashobj->length / 2) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
if (cx == NULL) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
cx->wasAllocated = PR_FALSE;
|
||||
cx->hashobj = hash_obj;
|
||||
cx->hash = cx->hashobj->create();
|
||||
if (cx->hash == NULL)
|
||||
goto loser;
|
||||
|
||||
if (secret_len > cx->hashobj->blocklength) {
|
||||
cx->hashobj->begin(cx->hash);
|
||||
|
|
@ -85,6 +76,31 @@ HMAC_Init(HMACContext *cx, const SECHashObject *hash_obj,
|
|||
|
||||
loser:
|
||||
PORT_Memset(hashed_secret, 0, sizeof hashed_secret);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
HMAC_Init(HMACContext *cx, const SECHashObject *hash_obj,
|
||||
const unsigned char *secret, unsigned int secret_len, PRBool isFIPS)
|
||||
{
|
||||
SECStatus rv;
|
||||
|
||||
if (cx == NULL) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
cx->wasAllocated = PR_FALSE;
|
||||
cx->hashobj = hash_obj;
|
||||
cx->hash = cx->hashobj->create();
|
||||
if (cx->hash == NULL)
|
||||
goto loser;
|
||||
|
||||
rv = hmac_initKey(cx, secret, secret_len, isFIPS);
|
||||
if (rv != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
return rv;
|
||||
loser:
|
||||
if (cx->hash != NULL)
|
||||
cx->hashobj->destroy(cx->hash, PR_TRUE);
|
||||
return SECFailure;
|
||||
|
|
@ -107,6 +123,34 @@ HMAC_Create(const SECHashObject *hash_obj, const unsigned char *secret,
|
|||
return cx;
|
||||
}
|
||||
|
||||
/* this allows us to reuse an existing HMACContext with a new key and
|
||||
* Hash function */
|
||||
SECStatus
|
||||
HMAC_ReInit(HMACContext *cx, const SECHashObject *hash_obj,
|
||||
const unsigned char *secret, unsigned int secret_len, PRBool isFIPS)
|
||||
{
|
||||
PRBool wasAllocated;
|
||||
SECStatus rv;
|
||||
|
||||
/* if we are using the same hash, keep the hash contexts and only
|
||||
* init the key */
|
||||
if ((cx->hashobj == hash_obj) && (cx->hash != NULL)) {
|
||||
return hmac_initKey(cx, secret, secret_len, isFIPS);
|
||||
}
|
||||
/* otherwise we destroy the contents of the context and
|
||||
* initalize it from scratch. We need to preseve the current state
|
||||
* of wasAllocated to the final destroy works correctly */
|
||||
wasAllocated = cx->wasAllocated;
|
||||
cx->wasAllocated = PR_FALSE;
|
||||
HMAC_Destroy(cx, PR_FALSE);
|
||||
rv = HMAC_Init(cx, hash_obj, secret, secret_len, isFIPS);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
}
|
||||
cx->wasAllocated = wasAllocated;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
void
|
||||
HMAC_Begin(HMACContext *cx)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -30,6 +30,12 @@ SECStatus
|
|||
HMAC_Init(HMACContext *cx, const SECHashObject *hash_obj,
|
||||
const unsigned char *secret, unsigned int secret_len, PRBool isFIPS);
|
||||
|
||||
/* like HMAC_Init, except caller passes in an existing context
|
||||
* previously used by either HMAC_Create or HMAC_Init. */
|
||||
SECStatus
|
||||
HMAC_ReInit(HMACContext *cx, const SECHashObject *hash_obj,
|
||||
const unsigned char *secret, unsigned int secret_len, PRBool isFIPS);
|
||||
|
||||
/* reset HMAC for a fresh round */
|
||||
extern void
|
||||
HMAC_Begin(HMACContext *cx);
|
||||
|
|
|
|||
|
|
@ -16,8 +16,10 @@ typedef __vector unsigned short vec_u16;
|
|||
typedef __vector signed short vec_s16;
|
||||
typedef __vector unsigned int vec_u32;
|
||||
typedef __vector signed int vec_s32;
|
||||
#ifdef __VSX__
|
||||
typedef __vector unsigned long long vec_u64;
|
||||
typedef __vector signed long long vec_s64;
|
||||
#endif
|
||||
typedef __vector float vec_f;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
#define CONVERT_TO_WORDS
|
||||
#endif
|
||||
|
||||
#if defined(AIX) || defined(OSF1) || defined(NSS_BEVAND_ARCFOUR)
|
||||
#if defined(AIX) || defined(NSS_BEVAND_ARCFOUR)
|
||||
/* Treat array variables as words, not bytes, on CPUs that take
|
||||
* much longer to write bytes than to write words, or when using
|
||||
* assembler code that required it.
|
||||
|
|
|
|||
|
|
@ -380,6 +380,9 @@ extern SECStatus KEA_Derive(SECItem *prime,
|
|||
*/
|
||||
extern PRBool KEA_Verify(SECItem *Y, SECItem *prime, SECItem *subPrime);
|
||||
|
||||
/* verify a value is prime */
|
||||
PRBool KEA_PrimeCheck(SECItem *prime);
|
||||
|
||||
/****************************************
|
||||
* J-PAKE key transport
|
||||
*/
|
||||
|
|
@ -856,6 +859,28 @@ extern SECStatus
|
|||
AES_Decrypt(AESContext *cx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen);
|
||||
/*
|
||||
** Perform AES AEAD operation (either encrypt or decrypt), controlled by
|
||||
** the context.
|
||||
** "cx" the context
|
||||
** "output" the output buffer to store the encrypted data.
|
||||
** "outputLen" how much data is stored in "output". Set by the routine
|
||||
** after some data is stored in output.
|
||||
** "maxOutputLen" the maximum amount of data that can ever be
|
||||
** stored in "output"
|
||||
** "input" the input data
|
||||
** "inputLen" the amount of input data
|
||||
** "params" pointer to an AEAD specific param PKCS #11 param structure
|
||||
** "paramsLen" length of the param structure pointed to by params
|
||||
** "aad" addition authenticated data
|
||||
** "aadLen" the amount of additional authenticated data.
|
||||
*/
|
||||
extern SECStatus
|
||||
AES_AEAD(AESContext *cx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen,
|
||||
void *params, unsigned int paramsLen,
|
||||
const unsigned char *aad, unsigned int aadLen);
|
||||
|
||||
/******************************************/
|
||||
/*
|
||||
|
|
@ -922,6 +947,38 @@ AESKeyWrap_Decrypt(AESKeyWrapContext *cx, unsigned char *output,
|
|||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen);
|
||||
|
||||
/*
|
||||
** Perform AES padded key wrap.
|
||||
** "cx" the context
|
||||
** "output" the output buffer to store the encrypted data.
|
||||
** "outputLen" how much data is stored in "output". Set by the routine
|
||||
** after some data is stored in output.
|
||||
** "maxOutputLen" the maximum amount of data that can ever be
|
||||
** stored in "output"
|
||||
** "input" the input data
|
||||
** "inputLen" the amount of input data
|
||||
*/
|
||||
extern SECStatus
|
||||
AESKeyWrap_EncryptKWP(AESKeyWrapContext *cx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen);
|
||||
|
||||
/*
|
||||
** Perform AES padded key unwrap.
|
||||
** "cx" the context
|
||||
** "output" the output buffer to store the decrypted data.
|
||||
** "outputLen" how much data is stored in "output". Set by the routine
|
||||
** after some data is stored in output.
|
||||
** "maxOutputLen" the maximum amount of data that can ever be
|
||||
** stored in "output"
|
||||
** "input" the input data
|
||||
** "inputLen" the amount of input data
|
||||
*/
|
||||
extern SECStatus
|
||||
AESKeyWrap_DecryptKWP(AESKeyWrapContext *cx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen);
|
||||
|
||||
/******************************************/
|
||||
/*
|
||||
** Camellia symmetric block cypher
|
||||
|
|
@ -984,6 +1041,26 @@ Camellia_Decrypt(CamelliaContext *cx, unsigned char *output,
|
|||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen);
|
||||
|
||||
/******************************************/
|
||||
/*
|
||||
** ChaCha20 block cipher
|
||||
*/
|
||||
|
||||
extern SECStatus ChaCha20_InitContext(ChaCha20Context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keyLen,
|
||||
const unsigned char *nonce,
|
||||
unsigned int nonceLen,
|
||||
PRUint32 ctr);
|
||||
|
||||
extern ChaCha20Context *ChaCha20_CreateContext(const unsigned char *key,
|
||||
unsigned int keyLen,
|
||||
const unsigned char *nonce,
|
||||
unsigned int nonceLen,
|
||||
PRUint32 ctr);
|
||||
|
||||
extern void ChaCha20_DestroyContext(ChaCha20Context *ctx, PRBool freeit);
|
||||
|
||||
/******************************************/
|
||||
/*
|
||||
** ChaCha20+Poly1305 AEAD
|
||||
|
|
@ -1014,6 +1091,20 @@ extern SECStatus ChaCha20Poly1305_Open(
|
|||
const unsigned char *nonce, unsigned int nonceLen,
|
||||
const unsigned char *ad, unsigned int adLen);
|
||||
|
||||
extern SECStatus ChaCha20Poly1305_Encrypt(
|
||||
const ChaCha20Poly1305Context *ctx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen,
|
||||
const unsigned char *nonce, unsigned int nonceLen,
|
||||
const unsigned char *ad, unsigned int adLen, unsigned char *tagOut);
|
||||
|
||||
extern SECStatus ChaCha20Poly1305_Decrypt(
|
||||
const ChaCha20Poly1305Context *ctx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen,
|
||||
const unsigned char *nonce, unsigned int nonceLen,
|
||||
const unsigned char *ad, unsigned int adLen, unsigned char *tagIn);
|
||||
|
||||
extern SECStatus ChaCha20_Xor(
|
||||
unsigned char *output, const unsigned char *block, unsigned int len,
|
||||
const unsigned char *k, const unsigned char *nonce, PRUint32 ctr);
|
||||
|
|
@ -1430,7 +1521,7 @@ extern SECStatus BLAKE2B_MAC_HashBuf(unsigned char *output,
|
|||
/*
|
||||
** Create a new Blake2b context
|
||||
*/
|
||||
extern BLAKE2BContext *BLAKE2B_NewContext();
|
||||
extern BLAKE2BContext *BLAKE2B_NewContext(void);
|
||||
|
||||
/*
|
||||
** Destroy a Blake2b secure hash context.
|
||||
|
|
|
|||
|
|
@ -18,12 +18,18 @@ typedef SECStatus (*freeblCipherFunc)(void *cx, unsigned char *output,
|
|||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen,
|
||||
unsigned int blocksize);
|
||||
typedef SECStatus (*freeblAeadFunc)(void *cx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen,
|
||||
void *params, unsigned int paramsLen,
|
||||
const unsigned char *aad, unsigned int aadLen,
|
||||
unsigned int blocksize);
|
||||
typedef void (*freeblDestroyFunc)(void *cx, PRBool freeit);
|
||||
|
||||
SEC_BEGIN_PROTOS
|
||||
|
||||
#ifndef NSS_FIPS_DISABLED
|
||||
SECStatus BL_FIPSEntryOK(PRBool freeblOnly);
|
||||
SECStatus BL_FIPSEntryOK(PRBool freeblOnly, PRBool rerun);
|
||||
PRBool BL_POSTRan(PRBool freeblOnly);
|
||||
#endif
|
||||
|
||||
|
|
@ -54,10 +60,10 @@ SEC_END_PROTOS
|
|||
#endif
|
||||
|
||||
/* Alignment helpers. */
|
||||
#if defined(_WINDOWS) && defined(NSS_X86_OR_X64)
|
||||
#if defined(_MSC_VER)
|
||||
#define pre_align __declspec(align(16))
|
||||
#define post_align
|
||||
#elif defined(NSS_X86_OR_X64)
|
||||
#elif defined(__GNUC__)
|
||||
#define pre_align
|
||||
#define post_align __attribute__((aligned(16)))
|
||||
#else
|
||||
|
|
@ -79,8 +85,12 @@ SECStatus generate_prime(mp_int *prime, int primeLen);
|
|||
/* Freebl state. */
|
||||
PRBool aesni_support();
|
||||
PRBool clmul_support();
|
||||
PRBool sha_support();
|
||||
PRBool avx_support();
|
||||
PRBool avx2_support();
|
||||
PRBool ssse3_support();
|
||||
PRBool sse4_1_support();
|
||||
PRBool sse4_2_support();
|
||||
PRBool arm_neon_support();
|
||||
PRBool arm_aes_support();
|
||||
PRBool arm_pmull_support();
|
||||
|
|
@ -88,4 +98,14 @@ PRBool arm_sha1_support();
|
|||
PRBool arm_sha2_support();
|
||||
PRBool ppc_crypto_support();
|
||||
|
||||
#ifdef NSS_FIPS_DISABLED
|
||||
#define BLAPI_CLEAR_STACK(stack_size)
|
||||
#else
|
||||
#define BLAPI_CLEAR_STACK(stack_size) \
|
||||
{ \
|
||||
volatile char _stkclr[stack_size]; \
|
||||
PORT_Memset((void *)&_stkclr[0], 0, stack_size); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _BLAPII_H_ */
|
||||
|
|
|
|||
|
|
@ -114,9 +114,9 @@ typedef int __BLAPI_DEPRECATED __attribute__((deprecated));
|
|||
#define BLAKE2B_BLOCK_LENGTH 128 /* Bytes */
|
||||
#define HASH_BLOCK_LENGTH_MAX SHA512_BLOCK_LENGTH
|
||||
|
||||
#define AES_KEY_WRAP_IV_BYTES 8
|
||||
#define AES_KEY_WRAP_BLOCK_SIZE 8 /* bytes */
|
||||
#define AES_BLOCK_SIZE 16 /* bytes */
|
||||
#define AES_BLOCK_SIZE 16 /* bytes */
|
||||
#define AES_KEY_WRAP_BLOCK_SIZE (AES_BLOCK_SIZE / 2)
|
||||
#define AES_KEY_WRAP_IV_BYTES AES_KEY_WRAP_BLOCK_SIZE
|
||||
|
||||
#define AES_128_KEY_LENGTH 16 /* bytes */
|
||||
#define AES_192_KEY_LENGTH 24 /* bytes */
|
||||
|
|
@ -199,6 +199,39 @@ typedef int __BLAPI_DEPRECATED __attribute__((deprecated));
|
|||
*/
|
||||
#define PQG_INDEX_TO_PBITS(j) (((unsigned)(j) > 8) ? -1 : (512 + 64 * (j)))
|
||||
|
||||
/* When we are generating a gcm iv from a random number, we need to calculate
|
||||
* an acceptable iteration count to avoid birthday attacks. (randomly
|
||||
* generating the same IV twice).
|
||||
*
|
||||
* We use the approximation n = sqrt(2*m*p) to find an acceptable n given m
|
||||
* and p.
|
||||
* where n is the number of iterations.
|
||||
* m is the number of possible random values.
|
||||
* p is the probability of collision (0-1).
|
||||
*
|
||||
* We want to calculate the constant number GCM_IV_RANDOM_BIRTHDAY_BITS, which
|
||||
* is the number of bits we subtract off of the length of the iv (in bits) to
|
||||
* get a safe count value (log2).
|
||||
*
|
||||
* Since we do the calculation in bits, so we need to take the whole
|
||||
* equation log2:
|
||||
* log2 n = (1+(log2 m)+(log2 p))/2
|
||||
* Since p < 1, log2 p is negative. Also note that the length of the iv in
|
||||
* bits is log2 m, so if we set GCMIV_RANDOM_BIRTHDAY_BITS =- log2 p - 1.
|
||||
* then we can calculate a safe counter value with:
|
||||
* n = 2^((ivLenBits - GCMIV_RANDOM_BIRTHDAY_BITS)/2)
|
||||
*
|
||||
* If we arbitrarily set p = 10^-18 (1 chance in trillion trillion operation)
|
||||
* we get GCMIV_RANDOM_BIRTHDAY_BITS = -(-18)/.301 -1 = 59 (.301 = log10 2)
|
||||
* GCMIV_RANDOM_BIRTHDAY_BITS should be at least 59, call it a round 64. NOTE:
|
||||
* the variable IV size for TLS is 64 bits, which explains why it's not safe
|
||||
* to use a random value for the nonce in TLS. */
|
||||
#define GCMIV_RANDOM_BIRTHDAY_BITS 64
|
||||
|
||||
/* flag to tell BLAPI_Verify* to rerun the post and integrity tests */
|
||||
#define BLAPI_FIPS_RERUN_FLAG '\377' /* 0xff, 255 invalide code for UFT8/ASCII */
|
||||
#define BLAPI_FIPS_RERUN_FLAG_STRING "\377" /* The above as a C string */
|
||||
|
||||
/***************************************************************************
|
||||
** Opaque objects
|
||||
*/
|
||||
|
|
@ -216,6 +249,7 @@ struct SHA256ContextStr;
|
|||
struct SHA512ContextStr;
|
||||
struct AESKeyWrapContextStr;
|
||||
struct SEEDContextStr;
|
||||
struct ChaCha20ContextStr;
|
||||
struct ChaCha20Poly1305ContextStr;
|
||||
struct Blake2bContextStr;
|
||||
|
||||
|
|
@ -236,6 +270,7 @@ typedef struct SHA512ContextStr SHA512Context;
|
|||
typedef struct SHA512ContextStr SHA384Context;
|
||||
typedef struct AESKeyWrapContextStr AESKeyWrapContext;
|
||||
typedef struct SEEDContextStr SEEDContext;
|
||||
typedef struct ChaCha20ContextStr ChaCha20Context;
|
||||
typedef struct ChaCha20Poly1305ContextStr ChaCha20Poly1305Context;
|
||||
typedef struct Blake2bContextStr BLAKE2BContext;
|
||||
|
||||
|
|
|
|||
|
|
@ -17,13 +17,25 @@
|
|||
#include <intrin.h> /* for _xgetbv() */
|
||||
#endif
|
||||
|
||||
#if defined(_WIN64) && defined(__aarch64__)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#if defined(DARWIN)
|
||||
#include <TargetConditionals.h>
|
||||
#endif
|
||||
|
||||
static PRCallOnceType coFreeblInit;
|
||||
|
||||
/* State variables. */
|
||||
static PRBool aesni_support_ = PR_FALSE;
|
||||
static PRBool clmul_support_ = PR_FALSE;
|
||||
static PRBool sha_support_ = PR_FALSE;
|
||||
static PRBool avx_support_ = PR_FALSE;
|
||||
static PRBool avx2_support_ = PR_FALSE;
|
||||
static PRBool ssse3_support_ = PR_FALSE;
|
||||
static PRBool sse4_1_support_ = PR_FALSE;
|
||||
static PRBool sse4_2_support_ = PR_FALSE;
|
||||
static PRBool arm_neon_support_ = PR_FALSE;
|
||||
static PRBool arm_aes_support_ = PR_FALSE;
|
||||
static PRBool arm_sha1_support_ = PR_FALSE;
|
||||
|
|
@ -35,6 +47,7 @@ static PRBool ppc_crypto_support_ = PR_FALSE;
|
|||
/*
|
||||
* Adapted from the example code in "How to detect New Instruction support in
|
||||
* the 4th generation Intel Core processor family" by Max Locktyukhin.
|
||||
* https://www.intel.com/content/dam/develop/external/us/en/documents/how-to-detect-new-instruction-support-in-the-4th-generation-intel-core-processor-family.pdf
|
||||
*
|
||||
* XGETBV:
|
||||
* Reads an extended control register (XCR) specified by ECX into EDX:EAX.
|
||||
|
|
@ -69,31 +82,64 @@ check_xcr0_ymm()
|
|||
#define ECX_XSAVE (1 << 26)
|
||||
#define ECX_OSXSAVE (1 << 27)
|
||||
#define ECX_AVX (1 << 28)
|
||||
#define EBX_AVX2 (1 << 5)
|
||||
#define EBX_BMI1 (1 << 3)
|
||||
#define EBX_BMI2 (1 << 8)
|
||||
#define EBX_SHA (1 << 29)
|
||||
#define ECX_FMA (1 << 12)
|
||||
#define ECX_MOVBE (1 << 22)
|
||||
#define ECX_SSSE3 (1 << 9)
|
||||
#define ECX_SSE4_1 (1 << 19)
|
||||
#define ECX_SSE4_2 (1 << 20)
|
||||
#define AVX_BITS (ECX_XSAVE | ECX_OSXSAVE | ECX_AVX)
|
||||
#define AVX2_EBX_BITS (EBX_AVX2 | EBX_BMI1 | EBX_BMI2)
|
||||
#define AVX2_ECX_BITS (ECX_FMA | ECX_MOVBE)
|
||||
|
||||
void
|
||||
CheckX86CPUSupport()
|
||||
{
|
||||
unsigned long eax, ebx, ecx, edx;
|
||||
unsigned long eax7, ebx7, ecx7, edx7;
|
||||
char *disable_hw_aes = PR_GetEnvSecure("NSS_DISABLE_HW_AES");
|
||||
char *disable_pclmul = PR_GetEnvSecure("NSS_DISABLE_PCLMUL");
|
||||
char *disable_hw_sha = PR_GetEnvSecure("NSS_DISABLE_HW_SHA");
|
||||
char *disable_avx = PR_GetEnvSecure("NSS_DISABLE_AVX");
|
||||
char *disable_avx2 = PR_GetEnvSecure("NSS_DISABLE_AVX2");
|
||||
char *disable_ssse3 = PR_GetEnvSecure("NSS_DISABLE_SSSE3");
|
||||
char *disable_sse4_1 = PR_GetEnvSecure("NSS_DISABLE_SSE4_1");
|
||||
char *disable_sse4_2 = PR_GetEnvSecure("NSS_DISABLE_SSE4_2");
|
||||
freebl_cpuid(1, &eax, &ebx, &ecx, &edx);
|
||||
freebl_cpuid(7, &eax7, &ebx7, &ecx7, &edx7);
|
||||
aesni_support_ = (PRBool)((ecx & ECX_AESNI) != 0 && disable_hw_aes == NULL);
|
||||
clmul_support_ = (PRBool)((ecx & ECX_CLMUL) != 0 && disable_pclmul == NULL);
|
||||
/* For AVX we check AVX, OSXSAVE, and XSAVE
|
||||
* as well as XMM and YMM state. */
|
||||
sha_support_ = (PRBool)((ebx7 & EBX_SHA) != 0 && disable_hw_sha == NULL);
|
||||
/* For AVX we ensure that:
|
||||
* - The AVX, OSXSAVE, and XSAVE bits of ECX from CPUID(EAX=1) are set, and
|
||||
* - the SSE and AVX state bits of XCR0 are set (check_xcr0_ymm).
|
||||
*/
|
||||
avx_support_ = (PRBool)((ecx & AVX_BITS) == AVX_BITS) && check_xcr0_ymm() &&
|
||||
disable_avx == NULL;
|
||||
/* For AVX2 we ensure that:
|
||||
* - AVX is supported,
|
||||
* - the AVX2, BMI1, and BMI2 bits of EBX from CPUID(EAX=7) are set, and
|
||||
* - the FMA, and MOVBE bits of ECX from CPUID(EAX=1) are set.
|
||||
* We do not check for LZCNT support.
|
||||
*/
|
||||
avx2_support_ = (PRBool)(avx_support_ == PR_TRUE &&
|
||||
(ebx7 & AVX2_EBX_BITS) == AVX2_EBX_BITS &&
|
||||
(ecx & AVX2_ECX_BITS) == AVX2_ECX_BITS &&
|
||||
disable_avx2 == NULL);
|
||||
ssse3_support_ = (PRBool)((ecx & ECX_SSSE3) != 0 &&
|
||||
disable_ssse3 == NULL);
|
||||
sse4_1_support_ = (PRBool)((ecx & ECX_SSE4_1) != 0 &&
|
||||
disable_sse4_1 == NULL);
|
||||
sse4_2_support_ = (PRBool)((ecx & ECX_SSE4_2) != 0 &&
|
||||
disable_sse4_2 == NULL);
|
||||
}
|
||||
#endif /* NSS_X86_OR_X64 */
|
||||
|
||||
/* clang-format off */
|
||||
#if defined(__aarch64__) || defined(__arm__)
|
||||
#if (defined(__aarch64__) || defined(__arm__)) && !defined(TARGET_OS_IPHONE)
|
||||
#ifndef __has_include
|
||||
#define __has_include(x) 0
|
||||
#endif
|
||||
|
|
@ -104,10 +150,26 @@ CheckX86CPUSupport()
|
|||
#include <sys/auxv.h>
|
||||
#endif
|
||||
extern unsigned long getauxval(unsigned long type) __attribute__((weak));
|
||||
#else
|
||||
#elif defined(__arm__) || (!defined(__OpenBSD__) && !defined(_WIN64))
|
||||
static unsigned long (*getauxval)(unsigned long) = NULL;
|
||||
#endif /* defined(__GNUC__) && __GNUC__ >= 2 && defined(__ELF__)*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__aarch64__) && __has_include(<sys/auxv.h>)
|
||||
/* Avoid conflict with static declaration above */
|
||||
#define getauxval freebl_getauxval
|
||||
static unsigned long getauxval(unsigned long type)
|
||||
{
|
||||
/* Only AT_HWCAP* return unsigned long */
|
||||
if (type != AT_HWCAP && type != AT_HWCAP2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long ret = 0;
|
||||
elf_aux_info(type, &ret, sizeof(ret));
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef AT_HWCAP2
|
||||
#define AT_HWCAP2 26
|
||||
#endif
|
||||
|
|
@ -119,6 +181,8 @@ static unsigned long (*getauxval)(unsigned long) = NULL;
|
|||
/* clang-format on */
|
||||
|
||||
#if defined(__aarch64__)
|
||||
|
||||
#if defined(__linux__)
|
||||
// Defines from hwcap.h in Linux kernel - ARM64
|
||||
#ifndef HWCAP_AES
|
||||
#define HWCAP_AES (1 << 3)
|
||||
|
|
@ -132,22 +196,81 @@ static unsigned long (*getauxval)(unsigned long) = NULL;
|
|||
#ifndef HWCAP_SHA2
|
||||
#define HWCAP_SHA2 (1 << 6)
|
||||
#endif
|
||||
#endif /* defined(__linux__) */
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#include <stdint.h>
|
||||
#include <machine/armreg.h>
|
||||
// Support for older version of armreg.h
|
||||
#ifndef ID_AA64ISAR0_AES_VAL
|
||||
#define ID_AA64ISAR0_AES_VAL ID_AA64ISAR0_AES
|
||||
#endif
|
||||
#ifndef ID_AA64ISAR0_SHA1_VAL
|
||||
#define ID_AA64ISAR0_SHA1_VAL ID_AA64ISAR0_SHA1
|
||||
#endif
|
||||
#ifndef ID_AA64ISAR0_SHA2_VAL
|
||||
#define ID_AA64ISAR0_SHA2_VAL ID_AA64ISAR0_SHA2
|
||||
#endif
|
||||
#endif /* defined(__FreeBSD__) */
|
||||
|
||||
#if defined(__OpenBSD__)
|
||||
#include <sys/sysctl.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/armreg.h>
|
||||
#endif /* defined(__OpenBSD__) */
|
||||
|
||||
void
|
||||
CheckARMSupport()
|
||||
{
|
||||
char *disable_arm_neon = PR_GetEnvSecure("NSS_DISABLE_ARM_NEON");
|
||||
char *disable_hw_aes = PR_GetEnvSecure("NSS_DISABLE_HW_AES");
|
||||
char *disable_pmull = PR_GetEnvSecure("NSS_DISABLE_PMULL");
|
||||
#if defined(_WIN64)
|
||||
BOOL arm_crypto_support = IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE);
|
||||
arm_aes_support_ = arm_crypto_support;
|
||||
arm_pmull_support_ = arm_crypto_support;
|
||||
arm_sha1_support_ = arm_crypto_support;
|
||||
arm_sha2_support_ = arm_crypto_support;
|
||||
#elif defined(__linux__)
|
||||
if (getauxval) {
|
||||
long hwcaps = getauxval(AT_HWCAP);
|
||||
arm_aes_support_ = hwcaps & HWCAP_AES && disable_hw_aes == NULL;
|
||||
arm_pmull_support_ = hwcaps & HWCAP_PMULL && disable_pmull == NULL;
|
||||
arm_sha1_support_ = hwcaps & HWCAP_SHA1;
|
||||
arm_sha2_support_ = hwcaps & HWCAP_SHA2;
|
||||
arm_aes_support_ = (hwcaps & HWCAP_AES) == HWCAP_AES;
|
||||
arm_pmull_support_ = (hwcaps & HWCAP_PMULL) == HWCAP_PMULL;
|
||||
arm_sha1_support_ = (hwcaps & HWCAP_SHA1) == HWCAP_SHA1;
|
||||
arm_sha2_support_ = (hwcaps & HWCAP_SHA2) == HWCAP_SHA2;
|
||||
}
|
||||
#elif defined(__FreeBSD__)
|
||||
/* qemu-user does not support register access from userspace */
|
||||
if (PR_GetEnvSecure("QEMU_EMULATING") == NULL) {
|
||||
uint64_t isar0 = READ_SPECIALREG(id_aa64isar0_el1);
|
||||
arm_aes_support_ = ID_AA64ISAR0_AES_VAL(isar0) >= ID_AA64ISAR0_AES_BASE;
|
||||
arm_pmull_support_ = ID_AA64ISAR0_AES_VAL(isar0) >= ID_AA64ISAR0_AES_PMULL;
|
||||
arm_sha1_support_ = ID_AA64ISAR0_SHA1_VAL(isar0) >= ID_AA64ISAR0_SHA1_BASE;
|
||||
arm_sha2_support_ = ID_AA64ISAR0_SHA2_VAL(isar0) >= ID_AA64ISAR0_SHA2_BASE;
|
||||
}
|
||||
#elif defined(__OpenBSD__)
|
||||
const int isar0_mib[] = { CTL_MACHDEP, CPU_ID_AA64ISAR0 };
|
||||
uint64_t isar0;
|
||||
size_t len = sizeof(isar0);
|
||||
if (sysctl(isar0_mib, 2, &isar0, &len, NULL, 0) < 0)
|
||||
return;
|
||||
arm_aes_support_ = ID_AA64ISAR0_AES(isar0) >= ID_AA64ISAR0_AES_BASE;
|
||||
arm_pmull_support_ = ID_AA64ISAR0_AES(isar0) >= ID_AA64ISAR0_AES_PMULL;
|
||||
arm_sha1_support_ = ID_AA64ISAR0_SHA1(isar0) >= ID_AA64ISAR0_SHA1_BASE;
|
||||
arm_sha2_support_ = ID_AA64ISAR0_SHA2(isar0) >= ID_AA64ISAR0_SHA2_BASE;
|
||||
#elif defined(__ARM_FEATURE_CRYPTO)
|
||||
/*
|
||||
* Although no feature detection, default compiler option allows ARM
|
||||
* Crypto Extension.
|
||||
*/
|
||||
arm_aes_support_ = PR_TRUE;
|
||||
arm_pmull_support_ = PR_TRUE;
|
||||
arm_sha1_support_ = PR_TRUE;
|
||||
arm_sha2_support_ = PR_TRUE;
|
||||
#endif
|
||||
/* aarch64 must support NEON. */
|
||||
arm_neon_support_ = disable_arm_neon == NULL;
|
||||
arm_neon_support_ = PR_GetEnvSecure("NSS_DISABLE_ARM_NEON") == NULL;
|
||||
arm_aes_support_ &= PR_GetEnvSecure("NSS_DISABLE_HW_AES") == NULL;
|
||||
arm_pmull_support_ &= PR_GetEnvSecure("NSS_DISABLE_PMULL") == NULL;
|
||||
arm_sha1_support_ &= PR_GetEnvSecure("NSS_DISABLE_HW_SHA1") == NULL;
|
||||
arm_sha2_support_ &= PR_GetEnvSecure("NSS_DISABLE_HW_SHA2") == NULL;
|
||||
}
|
||||
#endif /* defined(__aarch64__) */
|
||||
|
||||
|
|
@ -271,6 +394,8 @@ CheckARMSupport()
|
|||
arm_sha2_support_ = hwcaps & HWCAP2_SHA2;
|
||||
}
|
||||
arm_neon_support_ = GetNeonSupport();
|
||||
arm_sha1_support_ &= PR_GetEnvSecure("NSS_DISABLE_HW_SHA1") == NULL;
|
||||
arm_sha2_support_ &= PR_GetEnvSecure("NSS_DISABLE_HW_SHA2") == NULL;
|
||||
}
|
||||
#endif /* defined(__arm__) */
|
||||
|
||||
|
|
@ -315,16 +440,36 @@ clmul_support()
|
|||
return clmul_support_;
|
||||
}
|
||||
PRBool
|
||||
sha_support()
|
||||
{
|
||||
return sha_support_;
|
||||
}
|
||||
PRBool
|
||||
avx_support()
|
||||
{
|
||||
return avx_support_;
|
||||
}
|
||||
PRBool
|
||||
avx2_support()
|
||||
{
|
||||
return avx2_support_;
|
||||
}
|
||||
PRBool
|
||||
ssse3_support()
|
||||
{
|
||||
return ssse3_support_;
|
||||
}
|
||||
PRBool
|
||||
sse4_1_support()
|
||||
{
|
||||
return sse4_1_support_;
|
||||
}
|
||||
PRBool
|
||||
sse4_2_support()
|
||||
{
|
||||
return sse4_2_support_;
|
||||
}
|
||||
PRBool
|
||||
arm_neon_support()
|
||||
{
|
||||
return arm_neon_support_;
|
||||
|
|
@ -357,7 +502,18 @@ ppc_crypto_support()
|
|||
|
||||
#if defined(__powerpc__)
|
||||
|
||||
#ifndef __has_include
|
||||
#define __has_include(x) 0
|
||||
#endif
|
||||
|
||||
/* clang-format off */
|
||||
#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD__ >= 12)
|
||||
#if __has_include(<sys/auxv.h>)
|
||||
#include <sys/auxv.h>
|
||||
#endif
|
||||
#elif (defined(__FreeBSD__) && __FreeBSD__ < 12)
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
// Defines from cputable.h in Linux kernel - PPC, letting us build on older kernels
|
||||
#ifndef PPC_FEATURE2_VEC_CRYPTO
|
||||
|
|
@ -369,10 +525,25 @@ CheckPPCSupport()
|
|||
{
|
||||
char *disable_hw_crypto = PR_GetEnvSecure("NSS_DISABLE_PPC_GHASH");
|
||||
|
||||
long hwcaps = getauxval(AT_HWCAP2);
|
||||
unsigned long hwcaps = 0;
|
||||
#if defined(__linux__)
|
||||
#if __has_include(<sys/auxv.h>)
|
||||
hwcaps = getauxval(AT_HWCAP2);
|
||||
#endif
|
||||
#elif defined(__FreeBSD__)
|
||||
#if __FreeBSD__ >= 12
|
||||
#if __has_include(<sys/auxv.h>)
|
||||
elf_aux_info(AT_HWCAP2, &hwcaps, sizeof(hwcaps));
|
||||
#endif
|
||||
#else
|
||||
size_t len = sizeof(hwcaps);
|
||||
sysctlbyname("hw.cpu_features2", &hwcaps, &len, NULL, 0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
ppc_crypto_support_ = hwcaps & PPC_FEATURE2_VEC_CRYPTO && disable_hw_crypto == NULL;
|
||||
}
|
||||
/* clang-format on */
|
||||
|
||||
#endif /* __powerpc__ */
|
||||
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ static const PRUint32 camellia_sp1110[256] = {
|
|||
0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00,
|
||||
0xbbbbbb00, 0xc9c9c900, 0x43434300, 0xc1c1c100,
|
||||
0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400,
|
||||
0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00,
|
||||
0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00
|
||||
};
|
||||
|
||||
static const PRUint32 camellia_sp0222[256] = {
|
||||
|
|
@ -287,7 +287,7 @@ static const PRUint32 camellia_sp0222[256] = {
|
|||
0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6,
|
||||
0x00777777, 0x00939393, 0x00868686, 0x00838383,
|
||||
0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9,
|
||||
0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d,
|
||||
0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d
|
||||
};
|
||||
|
||||
static const PRUint32 camellia_sp3033[256] = {
|
||||
|
|
@ -354,7 +354,7 @@ static const PRUint32 camellia_sp3033[256] = {
|
|||
0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd,
|
||||
0xdd00dddd, 0xe400e4e4, 0xa100a1a1, 0xe000e0e0,
|
||||
0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a,
|
||||
0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f,
|
||||
0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f
|
||||
};
|
||||
|
||||
static const PRUint32 camellia_sp4404[256] = {
|
||||
|
|
@ -421,7 +421,7 @@ static const PRUint32 camellia_sp4404[256] = {
|
|||
0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a,
|
||||
0x49490049, 0x68680068, 0x38380038, 0xa4a400a4,
|
||||
0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1,
|
||||
0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e,
|
||||
0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
668
security/nss/lib/freebl/chacha20-ppc64le.S
Normal file
668
security/nss/lib/freebl/chacha20-ppc64le.S
Normal file
|
|
@ -0,0 +1,668 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
# vs0 - vs15 : buffer for xor
|
||||
# vs32 - vs47 (v0 - v15) : 4 "converted" states
|
||||
# vs48 - vs51 (v16 - v19) : original state
|
||||
# vs52 - vs55 (v20 - v23) : "converted" constants
|
||||
# vs56 (v24) : "converted" counter
|
||||
# vs57 (v25) : increment for "converted" counter
|
||||
# vs60 - vs63 (v28 - v31) : constants for rotate left or vpermxor
|
||||
|
||||
#define r0 0
|
||||
#define sp 1
|
||||
#define r2 2
|
||||
#define rSIZE 3
|
||||
#define rDST 4
|
||||
#define rSRC 5
|
||||
#define rKEY 6
|
||||
#define rNONCE 7
|
||||
#define rCNTR 8
|
||||
#define r9 9
|
||||
#define r10 10
|
||||
#define r11 11
|
||||
#define r12 12
|
||||
#define r13 13
|
||||
#define r14 14
|
||||
#define r15 15
|
||||
#define r16 16
|
||||
#define r17 17
|
||||
#define r18 18
|
||||
#define r19 19
|
||||
#define r20 20
|
||||
#define r21 21
|
||||
#define r22 22
|
||||
#define r23 23
|
||||
#define r24 24
|
||||
#define r25 25
|
||||
#define r26 26
|
||||
#define r27 27
|
||||
#define r28 28
|
||||
#define r29 29
|
||||
#define r30 30
|
||||
#define r31 31
|
||||
|
||||
#define v0 0
|
||||
#define v1 1
|
||||
#define v2 2
|
||||
#define v3 3
|
||||
#define v4 4
|
||||
#define v5 5
|
||||
#define v6 6
|
||||
#define v7 7
|
||||
#define v8 8
|
||||
#define v9 9
|
||||
#define v10 10
|
||||
#define v11 11
|
||||
#define v12 12
|
||||
#define v13 13
|
||||
#define v14 14
|
||||
#define v15 15
|
||||
#define v16 16
|
||||
#define v17 17
|
||||
#define v18 18
|
||||
#define v19 19
|
||||
#define v20 20
|
||||
#define v21 21
|
||||
#define v22 22
|
||||
#define v23 23
|
||||
#define v24 24
|
||||
#define v25 25
|
||||
#define v26 26
|
||||
#define v27 27
|
||||
#define v28 28
|
||||
#define v29 29
|
||||
#define v30 30
|
||||
#define v31 31
|
||||
|
||||
#define vs0 0
|
||||
#define vs1 1
|
||||
#define vs2 2
|
||||
#define vs3 3
|
||||
#define vs4 4
|
||||
#define vs5 5
|
||||
#define vs6 6
|
||||
#define vs7 7
|
||||
#define vs8 8
|
||||
#define vs9 9
|
||||
#define vs10 10
|
||||
#define vs11 11
|
||||
#define vs12 12
|
||||
#define vs13 13
|
||||
#define vs14 14
|
||||
#define vs15 15
|
||||
#define vs16 16
|
||||
#define vs17 17
|
||||
#define vs18 18
|
||||
#define vs19 19
|
||||
#define vs20 20
|
||||
#define vs21 21
|
||||
#define vs22 22
|
||||
#define vs23 23
|
||||
#define vs24 24
|
||||
#define vs25 25
|
||||
#define vs26 26
|
||||
#define vs27 27
|
||||
#define vs28 28
|
||||
#define vs29 29
|
||||
#define vs30 30
|
||||
#define vs31 31
|
||||
#define vs32 32
|
||||
#define vs33 33
|
||||
#define vs34 34
|
||||
#define vs35 35
|
||||
#define vs36 36
|
||||
#define vs37 37
|
||||
#define vs38 38
|
||||
#define vs39 39
|
||||
#define vs40 40
|
||||
#define vs41 41
|
||||
#define vs42 42
|
||||
#define vs43 43
|
||||
#define vs44 44
|
||||
#define vs45 45
|
||||
#define vs46 46
|
||||
#define vs47 47
|
||||
#define vs48 48
|
||||
#define vs49 49
|
||||
#define vs50 50
|
||||
#define vs51 51
|
||||
#define vs52 52
|
||||
#define vs53 53
|
||||
#define vs54 54
|
||||
#define vs55 55
|
||||
#define vs56 56
|
||||
#define vs57 57
|
||||
#define vs58 58
|
||||
#define vs59 59
|
||||
#define vs60 60
|
||||
#define vs61 61
|
||||
#define vs62 62
|
||||
#define vs63 63
|
||||
|
||||
.abiversion 2
|
||||
.section ".data"
|
||||
.align 5
|
||||
lblock: .skip 256
|
||||
cnts0: .long 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574
|
||||
cnts1: .long 0x61707865, 0x61707865, 0x61707865, 0x61707865
|
||||
cnts2: .long 0x3320646e, 0x3320646e, 0x3320646e, 0x3320646e
|
||||
cnts3: .long 0x79622d32, 0x79622d32, 0x79622d32, 0x79622d32
|
||||
cnts4: .long 0x6b206574, 0x6b206574, 0x6b206574, 0x6b206574
|
||||
st4: .long 0, 0, 0, 0
|
||||
cntr: .long 0, 0, 0, 0
|
||||
incr: .long 4, 4, 4, 4
|
||||
rotl1: .long 0x22330011, 0x66774455, 0xAABB8899, 0xEEFFCCDD
|
||||
rotl2: .long 12, 12, 12, 12
|
||||
rotl3: .long 0x11223300, 0x55667744, 0x99AABB88, 0xDDEEFFCC
|
||||
rotl4: .long 7, 7, 7, 7
|
||||
|
||||
.section ".text"
|
||||
.align 5
|
||||
.globl chacha20vsx
|
||||
.type chacha20vsx, @function
|
||||
chacha20vsx:
|
||||
# prologue
|
||||
addis 2, r12, .TOC.-chacha20vsx@ha
|
||||
addi 2, 2, .TOC.-chacha20vsx@l
|
||||
.localentry chacha20vsx, .-chacha20vsx
|
||||
std r14, -8(sp)
|
||||
std r15, -16(sp)
|
||||
std r16, -24(sp)
|
||||
std r17, -32(sp)
|
||||
std r18, -40(sp)
|
||||
std r19, -48(sp)
|
||||
std r20, -56(sp)
|
||||
std r21, -64(sp)
|
||||
std r22, -72(sp)
|
||||
std r23, -80(sp)
|
||||
std r24, -88(sp)
|
||||
std r25, -96(sp)
|
||||
std r26, -104(sp)
|
||||
std r27, -112(sp)
|
||||
std r28, -120(sp)
|
||||
std r29, -128(sp)
|
||||
std r30, -136(sp)
|
||||
std r31, -144(sp)
|
||||
|
||||
addi r14, sp, -160
|
||||
|
||||
li r16, -16
|
||||
li r17, -32
|
||||
li r18, -48
|
||||
li r19, -64
|
||||
li r20, -80
|
||||
li r21, -96
|
||||
li r22, -112
|
||||
li r23, -128
|
||||
li r24, -144
|
||||
li r25, -160
|
||||
li r26, -176
|
||||
li r27, -192
|
||||
li r28, -208
|
||||
|
||||
# save f14, f15
|
||||
stxvw4x vs14, 0, r14
|
||||
stxvw4x vs15, r16, r14
|
||||
|
||||
# save v20 - v31
|
||||
stxvw4x vs52, r17, r14
|
||||
stxvw4x vs53, r18, r14
|
||||
stxvw4x vs54, r19, r14
|
||||
stxvw4x vs55, r20, r14
|
||||
stxvw4x vs56, r21, r14
|
||||
stxvw4x vs57, r22, r14
|
||||
stxvw4x vs58, r23, r14
|
||||
stxvw4x vs59, r24, r14
|
||||
stxvw4x vs60, r25, r14
|
||||
stxvw4x vs61, r26, r14
|
||||
stxvw4x vs62, r27, r14
|
||||
stxvw4x vs63, r28, r14
|
||||
|
||||
# offset in src/dst
|
||||
li r17, 16
|
||||
li r18, 32
|
||||
li r19, 48
|
||||
li r20, 64
|
||||
li r21, 80
|
||||
li r22, 96
|
||||
li r23, 112
|
||||
li r24, 128
|
||||
li r25, 144
|
||||
li r26, 160
|
||||
li r27, 176
|
||||
li r28, 192
|
||||
li r29, 208
|
||||
li r30, 224
|
||||
li r31, 240
|
||||
|
||||
# load const's address
|
||||
addis r14, 2, cnts0@toc@ha
|
||||
addi r14, r14, cnts0@toc@l
|
||||
|
||||
# save nonce to st4
|
||||
lwz r15, 0(rNONCE)
|
||||
stw r15, 84(r14)
|
||||
lwz r15, 4(rNONCE)
|
||||
stw r15, 88(r14)
|
||||
lwz r15, 8(rNONCE)
|
||||
stw r15, 92(r14)
|
||||
|
||||
# load state to vectors
|
||||
lxvw4x vs48, 0, r14
|
||||
lxvw4x vs49, 0, rKEY
|
||||
lxvw4x vs50, r17, rKEY
|
||||
lxvw4x vs51, r21, r14
|
||||
|
||||
# load consts for x4 rounds
|
||||
lxvw4x vs52, r17, r14
|
||||
lxvw4x vs53, r18, r14
|
||||
lxvw4x vs54, r19, r14
|
||||
lxvw4x vs55, r20, r14
|
||||
|
||||
# counter
|
||||
stw rCNTR, 96(r14)
|
||||
addi rCNTR, rCNTR, 1
|
||||
stw rCNTR, 100(r14)
|
||||
addi rCNTR, rCNTR, 1
|
||||
stw rCNTR, 104(r14)
|
||||
addi rCNTR, rCNTR, 1
|
||||
stw rCNTR, 108(r14)
|
||||
lxvw4x vs56, r22, r14
|
||||
|
||||
# load increment
|
||||
lxvw4x vs57, r23, r14
|
||||
|
||||
# load rotl to vectors
|
||||
lxvw4x vs60, r24, r14
|
||||
lxvw4x vs61, r25, r14
|
||||
lxvw4x vs62, r26, r14
|
||||
lxvw4x vs63, r27, r14
|
||||
|
||||
# counter for loop = size/256
|
||||
li r15, 256
|
||||
divdu. r16, rSIZE, r15
|
||||
beq lastblock
|
||||
mtctr r16
|
||||
|
||||
mainloop:
|
||||
# init 16 vectors (4 states x4)
|
||||
vor v0, v20, v20
|
||||
vor v1, v21, v21
|
||||
vor v2, v22, v22
|
||||
vor v3, v23, v23
|
||||
vspltw v4, v17, v0
|
||||
vspltw v5, v17, v1
|
||||
vspltw v6, v17, v2
|
||||
vspltw v7, v17, v3
|
||||
vspltw v8, v18, v0
|
||||
vspltw v9, v18, v1
|
||||
vspltw v10, v18, v2
|
||||
vspltw v11, v18, v3
|
||||
vor v12, v24, v24
|
||||
vspltw v13, v19, v1
|
||||
vspltw v14, v19, v2
|
||||
vspltw v15, v19, v3
|
||||
|
||||
.macro _plus a b_y b_x
|
||||
vadduwm \a, \a, \b_y*4+(\b_x)%4
|
||||
vadduwm \a+1, \a+1, \b_y*4+(\b_x+1)%4
|
||||
vadduwm \a+2, \a+2, \b_y*4+(\b_x+2)%4
|
||||
vadduwm \a+3, \a+3, \b_y*4+(\b_x+3)%4
|
||||
.endm
|
||||
|
||||
.macro _xor a b_y b_x
|
||||
vxor \a, \a, \b_y*4+(\b_x)%4
|
||||
vxor \a+1, \a+1, \b_y*4+(\b_x+1)%4
|
||||
vxor \a+2, \a+2, \b_y*4+(\b_x+2)%4
|
||||
vxor \a+3, \a+3, \b_y*4+(\b_x+3)%4
|
||||
.endm
|
||||
|
||||
.macro _rotl a b
|
||||
vrlw \a, \a, \b
|
||||
vrlw \a+1, \a+1, \b
|
||||
vrlw \a+2, \a+2, \b
|
||||
vrlw \a+3, \a+3, \b
|
||||
.endm
|
||||
|
||||
.macro _pxor a b_y b_x c
|
||||
vpermxor \a, \a, \b_y*4+(\b_x)%4, \c
|
||||
vpermxor \a+1, \a+1, \b_y*4+(\b_x+1)%4, \c
|
||||
vpermxor \a+2, \a+2, \b_y*4+(\b_x+2)%4, \c
|
||||
vpermxor \a+3, \a+3, \b_y*4+(\b_x+3)%4, \c
|
||||
.endm
|
||||
|
||||
# 00 01 02 03
|
||||
# 04 05 06 07
|
||||
# 08 09 10 11
|
||||
# 12 13 14 15
|
||||
.macro doubleround
|
||||
# column round
|
||||
_plus v0, v1, v0 # a+=b
|
||||
_pxor v12, v0, v0, v28 # d^=a; d<<<=16
|
||||
_plus v8, v3, v0 # c+=d
|
||||
_xor v4, v2, v0 # b^=c
|
||||
_rotl v4, v29 # b<<<=12
|
||||
_plus v0, v1, v0 # a+=b
|
||||
_pxor v12, v0, v0, v30 # d^=a; d<<<=8
|
||||
_plus v8, v3, v0 # c+=d
|
||||
_xor v4, v2, v0 # b^=c
|
||||
_rotl v4, v31 # b<<<=7
|
||||
|
||||
# diagonal round
|
||||
_plus v0, v1, v1 # a+=b
|
||||
_pxor v12, v0, v1, v28 # d^=a; d<<<=16
|
||||
_plus v8, v3, v1 # c+=d
|
||||
_xor v4, v2, v1 # b^=c
|
||||
_rotl v4, v29 # b<<<=12
|
||||
_plus v0, v1, v1 # a+=b
|
||||
_pxor v12, v0, v1, v30 # d^=a; d<<<=8
|
||||
_plus v8, v3, v1 # c+=d
|
||||
_xor v4, v2, v1 # b^=c
|
||||
_rotl v4, v31 # b<<<=7
|
||||
.endm
|
||||
|
||||
doubleround # 1
|
||||
doubleround # 2
|
||||
doubleround # 3
|
||||
doubleround # 4
|
||||
doubleround # 5
|
||||
doubleround # 6
|
||||
doubleround # 7
|
||||
doubleround # 8
|
||||
doubleround # 9
|
||||
doubleround # 10
|
||||
|
||||
# counter += original counter
|
||||
vadduwm v12, v12, v24
|
||||
|
||||
.macro convert a
|
||||
vmrgew 26, 0+\a, 1+\a
|
||||
vmrgew 27, 2+\a, 3+\a
|
||||
vmrgow 0+\a, 0+\a, 1+\a
|
||||
vmrgow 2+\a, 2+\a, 3+\a
|
||||
xxmrghd 33+\a, 32+\a, 34+\a
|
||||
xxmrgld 35+\a, 32+\a, 34+\a
|
||||
xxmrghd 32+\a, 58, 59
|
||||
xxmrgld 34+\a, 58, 59
|
||||
.endm
|
||||
|
||||
convert 0
|
||||
convert 4
|
||||
convert 8
|
||||
convert 12
|
||||
|
||||
.macro addition a
|
||||
vadduwm 0+\a, 0+\a, 16
|
||||
vadduwm 4+\a, 4+\a, 17
|
||||
vadduwm 8+\a, 8+\a, 18
|
||||
vadduwm 12+\a, 12+\a, 19
|
||||
.endm
|
||||
|
||||
addition 0
|
||||
addition 1
|
||||
addition 2
|
||||
addition 3
|
||||
|
||||
# load text/cipher
|
||||
lxvw4x vs0, 0, rSRC
|
||||
lxvw4x vs1, r17, rSRC
|
||||
lxvw4x vs2, r18, rSRC
|
||||
lxvw4x vs3, r19, rSRC
|
||||
lxvw4x vs4, r20, rSRC
|
||||
lxvw4x vs5, r21, rSRC
|
||||
lxvw4x vs6, r22, rSRC
|
||||
lxvw4x vs7, r23, rSRC
|
||||
lxvw4x vs8, r24, rSRC
|
||||
lxvw4x vs9, r25, rSRC
|
||||
lxvw4x vs10, r26, rSRC
|
||||
lxvw4x vs11, r27, rSRC
|
||||
lxvw4x vs12, r28, rSRC
|
||||
lxvw4x vs13, r29, rSRC
|
||||
lxvw4x vs14, r30, rSRC
|
||||
lxvw4x vs15, r31, rSRC
|
||||
# xor (encrypt/decrypt)
|
||||
xxlxor vs0, vs0, vs32
|
||||
xxlxor vs1, vs1, vs36
|
||||
xxlxor vs2, vs2, vs40
|
||||
xxlxor vs3, vs3, vs44
|
||||
xxlxor vs4, vs4, vs33
|
||||
xxlxor vs5, vs5, vs37
|
||||
xxlxor vs6, vs6, vs41
|
||||
xxlxor vs7, vs7, vs45
|
||||
xxlxor vs8, vs8, vs34
|
||||
xxlxor vs9, vs9, vs38
|
||||
xxlxor vs10, vs10, vs42
|
||||
xxlxor vs11, vs11, vs46
|
||||
xxlxor vs12, vs12, vs35
|
||||
xxlxor vs13, vs13, vs39
|
||||
xxlxor vs14, vs14, vs43
|
||||
xxlxor vs15, vs15, vs47
|
||||
# store cipher/text
|
||||
stxvw4x vs0, 0, rDST
|
||||
stxvw4x vs1, r17, rDST
|
||||
stxvw4x vs2, r18, rDST
|
||||
stxvw4x vs3, r19, rDST
|
||||
stxvw4x vs4, r20, rDST
|
||||
stxvw4x vs5, r21, rDST
|
||||
stxvw4x vs6, r22, rDST
|
||||
stxvw4x vs7, r23, rDST
|
||||
stxvw4x vs8, r24, rDST
|
||||
stxvw4x vs9, r25, rDST
|
||||
stxvw4x vs10, r26, rDST
|
||||
stxvw4x vs11, r27, rDST
|
||||
stxvw4x vs12, r28, rDST
|
||||
stxvw4x vs13, r29, rDST
|
||||
stxvw4x vs14, r30, rDST
|
||||
stxvw4x vs15, r31, rDST
|
||||
|
||||
# src/dst increment
|
||||
addi rSRC, rSRC, 256
|
||||
addi rDST, rDST, 256
|
||||
|
||||
# counter increment
|
||||
vadduwm v24, v24, v25
|
||||
|
||||
bdnz mainloop
|
||||
|
||||
lastblock:
|
||||
# reminder
|
||||
mulld r16, r16, r15
|
||||
subf. r16, r16, rSIZE
|
||||
|
||||
# check reminder
|
||||
beq exitsub
|
||||
|
||||
addi r14, r14, -256
|
||||
# last block x4
|
||||
# init 16 vectors (4 states x4)
|
||||
vor v0, v20, v20
|
||||
vor v1, v21, v21
|
||||
vor v2, v22, v22
|
||||
vor v3, v23, v23
|
||||
vspltw v4, v17, v0
|
||||
vspltw v5, v17, v1
|
||||
vspltw v6, v17, v2
|
||||
vspltw v7, v17, v3
|
||||
vspltw v8, v18, v0
|
||||
vspltw v9, v18, v1
|
||||
vspltw v10, v18, v2
|
||||
vspltw v11, v18, v3
|
||||
vor v12, v24, v24
|
||||
vspltw v13, v19, v1
|
||||
vspltw v14, v19, v2
|
||||
vspltw v15, v19, v3
|
||||
|
||||
doubleround # 1
|
||||
doubleround # 2
|
||||
doubleround # 3
|
||||
doubleround # 4
|
||||
doubleround # 5
|
||||
doubleround # 6
|
||||
doubleround # 7
|
||||
doubleround # 8
|
||||
doubleround # 9
|
||||
doubleround # 10
|
||||
|
||||
vadduwm v12, v12, v24
|
||||
|
||||
convert 0
|
||||
convert 4
|
||||
convert 8
|
||||
convert 12
|
||||
|
||||
addition 0
|
||||
addition 1
|
||||
addition 2
|
||||
addition 3
|
||||
|
||||
# store vectors
|
||||
stxvw4x vs32, 0, r14
|
||||
stxvw4x vs36, r17, r14
|
||||
stxvw4x vs40, r18, r14
|
||||
stxvw4x vs44, r19, r14
|
||||
stxvw4x vs33, r20, r14
|
||||
stxvw4x vs37, r21, r14
|
||||
stxvw4x vs41, r22, r14
|
||||
stxvw4x vs45, r23, r14
|
||||
stxvw4x vs34, r24, r14
|
||||
stxvw4x vs38, r25, r14
|
||||
stxvw4x vs42, r26, r14
|
||||
stxvw4x vs46, r27, r14
|
||||
stxvw4x vs35, r28, r14
|
||||
stxvw4x vs39, r29, r14
|
||||
stxvw4x vs43, r30, r14
|
||||
stxvw4x vs47, r31, r14
|
||||
|
||||
mtctr r16
|
||||
addi rSIZE, r14, -1
|
||||
addi rSRC, rSRC, -1
|
||||
addi rDST, rDST, -1
|
||||
xorlast:
|
||||
lbzu r15, 1(rSIZE)
|
||||
lbzu r16, 1(rSRC)
|
||||
xor r15, r15, r16
|
||||
stbu r15, 1(rDST)
|
||||
bdnz xorlast
|
||||
|
||||
# zeroing last block
|
||||
xxlxor vs0, vs0, vs0
|
||||
stxvw4x vs0, 0, r14
|
||||
stxvw4x vs0, r17, r14
|
||||
stxvw4x vs0, r18, r14
|
||||
stxvw4x vs0, r19, r14
|
||||
stxvw4x vs0, r20, r14
|
||||
stxvw4x vs0, r21, r14
|
||||
stxvw4x vs0, r22, r14
|
||||
stxvw4x vs0, r23, r14
|
||||
stxvw4x vs0, r24, r14
|
||||
stxvw4x vs0, r25, r14
|
||||
stxvw4x vs0, r26, r14
|
||||
stxvw4x vs0, r27, r14
|
||||
stxvw4x vs0, r28, r14
|
||||
stxvw4x vs0, r29, r14
|
||||
stxvw4x vs0, r30, r14
|
||||
stxvw4x vs0, r31, r14
|
||||
|
||||
exitsub:
|
||||
# zeroing volatile registers
|
||||
xxlxor vs0, vs0, vs0
|
||||
xxlxor vs1, vs1, vs1
|
||||
xxlxor vs2, vs2, vs2
|
||||
xxlxor vs3, vs3, vs3
|
||||
xxlxor vs4, vs4, vs4
|
||||
xxlxor vs5, vs5, vs5
|
||||
xxlxor vs6, vs6, vs6
|
||||
xxlxor vs7, vs7, vs7
|
||||
xxlxor vs8, vs8, vs8
|
||||
xxlxor vs9, vs9, vs9
|
||||
xxlxor vs10, vs10, vs10
|
||||
xxlxor vs11, vs11, vs11
|
||||
xxlxor vs12, vs12, vs12
|
||||
xxlxor vs13, vs13, vs13
|
||||
|
||||
xxlxor vs32, vs32, vs32
|
||||
xxlxor vs33, vs33, vs33
|
||||
xxlxor vs34, vs34, vs34
|
||||
xxlxor vs35, vs35, vs35
|
||||
xxlxor vs36, vs36, vs36
|
||||
xxlxor vs37, vs37, vs37
|
||||
xxlxor vs38, vs38, vs38
|
||||
xxlxor vs39, vs39, vs39
|
||||
xxlxor vs40, vs40, vs40
|
||||
xxlxor vs41, vs41, vs41
|
||||
xxlxor vs42, vs42, vs42
|
||||
xxlxor vs43, vs43, vs43
|
||||
xxlxor vs44, vs44, vs44
|
||||
xxlxor vs45, vs45, vs45
|
||||
xxlxor vs46, vs46, vs46
|
||||
xxlxor vs47, vs47, vs47
|
||||
xxlxor vs48, vs48, vs48
|
||||
xxlxor vs49, vs49, vs49
|
||||
xxlxor vs50, vs50, vs50
|
||||
xxlxor vs51, vs51, vs51
|
||||
|
||||
li rSIZE, 0
|
||||
li rDST, 0
|
||||
li rSRC, 0
|
||||
li rKEY, 0
|
||||
li rNONCE, 0
|
||||
li rCNTR, 0
|
||||
|
||||
# epilogue
|
||||
addi r14, sp, -160
|
||||
|
||||
li r16, -16
|
||||
li r17, -32
|
||||
li r18, -48
|
||||
li r19, -64
|
||||
li r20, -80
|
||||
li r21, -96
|
||||
li r22, -112
|
||||
li r23, -128
|
||||
li r24, -144
|
||||
li r25, -160
|
||||
li r26, -176
|
||||
li r27, -192
|
||||
li r28, -208
|
||||
|
||||
# load f14, f15
|
||||
lxvw4x vs14, 0, r14
|
||||
lxvw4x vs15, r16, r14
|
||||
|
||||
# load v20 - v31
|
||||
lxvw4x vs52, r17, r14
|
||||
lxvw4x vs53, r18, r14
|
||||
lxvw4x vs54, r19, r14
|
||||
lxvw4x vs55, r20, r14
|
||||
lxvw4x vs56, r21, r14
|
||||
lxvw4x vs57, r22, r14
|
||||
lxvw4x vs58, r23, r14
|
||||
lxvw4x vs59, r24, r14
|
||||
lxvw4x vs60, r25, r14
|
||||
lxvw4x vs61, r26, r14
|
||||
lxvw4x vs62, r27, r14
|
||||
lxvw4x vs63, r28, r14
|
||||
|
||||
ld r14, -8(sp)
|
||||
ld r15, -16(sp)
|
||||
ld r16, -24(sp)
|
||||
ld r17, -32(sp)
|
||||
ld r18, -40(sp)
|
||||
ld r19, -48(sp)
|
||||
ld r20, -56(sp)
|
||||
ld r21, -64(sp)
|
||||
ld r22, -72(sp)
|
||||
ld r23, -80(sp)
|
||||
ld r24, -88(sp)
|
||||
ld r25, -96(sp)
|
||||
ld r26, -104(sp)
|
||||
ld r27, -112(sp)
|
||||
ld r28, -120(sp)
|
||||
ld r29, -128(sp)
|
||||
ld r30, -136(sp)
|
||||
ld r31, -144(sp)
|
||||
|
||||
blr
|
||||
588
security/nss/lib/freebl/chacha20poly1305-ppc.c
Normal file
588
security/nss/lib/freebl/chacha20poly1305-ppc.c
Normal file
|
|
@ -0,0 +1,588 @@
|
|||
/* MIT License
|
||||
*
|
||||
* Copyright (c) 2016-2020 INRIA, CMU and Microsoft Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "Hacl_Chacha20Poly1305_32.h"
|
||||
|
||||
/* Forward declaration from chacha20-ppc64le.S */
|
||||
void chacha20vsx(uint32_t len, uint8_t *output, uint8_t *block, uint8_t *k,
|
||||
uint8_t *nonce, uint32_t ctr);
|
||||
|
||||
static inline void
|
||||
poly1305_padded_32(uint64_t *ctx, uint32_t len, uint8_t *text)
|
||||
{
|
||||
uint32_t n = len / (uint32_t)16U;
|
||||
uint32_t r = len % (uint32_t)16U;
|
||||
uint8_t *blocks = text;
|
||||
uint8_t *rem = text + n * (uint32_t)16U;
|
||||
uint64_t *pre0 = ctx + (uint32_t)5U;
|
||||
uint64_t *acc0 = ctx;
|
||||
uint32_t nb = n * (uint32_t)16U / (uint32_t)16U;
|
||||
uint32_t rem1 = n * (uint32_t)16U % (uint32_t)16U;
|
||||
for (uint32_t i = (uint32_t)0U; i < nb; i++) {
|
||||
uint8_t *block = blocks + i * (uint32_t)16U;
|
||||
uint64_t e[5U] = { 0U };
|
||||
uint64_t u0 = load64_le(block);
|
||||
uint64_t lo = u0;
|
||||
uint64_t u = load64_le(block + (uint32_t)8U);
|
||||
uint64_t hi = u;
|
||||
uint64_t f0 = lo;
|
||||
uint64_t f1 = hi;
|
||||
uint64_t f010 = f0 & (uint64_t)0x3ffffffU;
|
||||
uint64_t f110 = f0 >> (uint32_t)26U & (uint64_t)0x3ffffffU;
|
||||
uint64_t f20 = f0 >> (uint32_t)52U | (f1 & (uint64_t)0x3fffU) << (uint32_t)12U;
|
||||
uint64_t f30 = f1 >> (uint32_t)14U & (uint64_t)0x3ffffffU;
|
||||
uint64_t f40 = f1 >> (uint32_t)40U;
|
||||
uint64_t f01 = f010;
|
||||
uint64_t f111 = f110;
|
||||
uint64_t f2 = f20;
|
||||
uint64_t f3 = f30;
|
||||
uint64_t f41 = f40;
|
||||
e[0U] = f01;
|
||||
e[1U] = f111;
|
||||
e[2U] = f2;
|
||||
e[3U] = f3;
|
||||
e[4U] = f41;
|
||||
uint64_t b = (uint64_t)0x1000000U;
|
||||
uint64_t mask = b;
|
||||
uint64_t f4 = e[4U];
|
||||
e[4U] = f4 | mask;
|
||||
uint64_t *r1 = pre0;
|
||||
uint64_t *r5 = pre0 + (uint32_t)5U;
|
||||
uint64_t r0 = r1[0U];
|
||||
uint64_t r11 = r1[1U];
|
||||
uint64_t r2 = r1[2U];
|
||||
uint64_t r3 = r1[3U];
|
||||
uint64_t r4 = r1[4U];
|
||||
uint64_t r51 = r5[1U];
|
||||
uint64_t r52 = r5[2U];
|
||||
uint64_t r53 = r5[3U];
|
||||
uint64_t r54 = r5[4U];
|
||||
uint64_t f10 = e[0U];
|
||||
uint64_t f11 = e[1U];
|
||||
uint64_t f12 = e[2U];
|
||||
uint64_t f13 = e[3U];
|
||||
uint64_t f14 = e[4U];
|
||||
uint64_t a0 = acc0[0U];
|
||||
uint64_t a1 = acc0[1U];
|
||||
uint64_t a2 = acc0[2U];
|
||||
uint64_t a3 = acc0[3U];
|
||||
uint64_t a4 = acc0[4U];
|
||||
uint64_t a01 = a0 + f10;
|
||||
uint64_t a11 = a1 + f11;
|
||||
uint64_t a21 = a2 + f12;
|
||||
uint64_t a31 = a3 + f13;
|
||||
uint64_t a41 = a4 + f14;
|
||||
uint64_t a02 = r0 * a01;
|
||||
uint64_t a12 = r11 * a01;
|
||||
uint64_t a22 = r2 * a01;
|
||||
uint64_t a32 = r3 * a01;
|
||||
uint64_t a42 = r4 * a01;
|
||||
uint64_t a03 = a02 + r54 * a11;
|
||||
uint64_t a13 = a12 + r0 * a11;
|
||||
uint64_t a23 = a22 + r11 * a11;
|
||||
uint64_t a33 = a32 + r2 * a11;
|
||||
uint64_t a43 = a42 + r3 * a11;
|
||||
uint64_t a04 = a03 + r53 * a21;
|
||||
uint64_t a14 = a13 + r54 * a21;
|
||||
uint64_t a24 = a23 + r0 * a21;
|
||||
uint64_t a34 = a33 + r11 * a21;
|
||||
uint64_t a44 = a43 + r2 * a21;
|
||||
uint64_t a05 = a04 + r52 * a31;
|
||||
uint64_t a15 = a14 + r53 * a31;
|
||||
uint64_t a25 = a24 + r54 * a31;
|
||||
uint64_t a35 = a34 + r0 * a31;
|
||||
uint64_t a45 = a44 + r11 * a31;
|
||||
uint64_t a06 = a05 + r51 * a41;
|
||||
uint64_t a16 = a15 + r52 * a41;
|
||||
uint64_t a26 = a25 + r53 * a41;
|
||||
uint64_t a36 = a35 + r54 * a41;
|
||||
uint64_t a46 = a45 + r0 * a41;
|
||||
uint64_t t0 = a06;
|
||||
uint64_t t1 = a16;
|
||||
uint64_t t2 = a26;
|
||||
uint64_t t3 = a36;
|
||||
uint64_t t4 = a46;
|
||||
uint64_t mask26 = (uint64_t)0x3ffffffU;
|
||||
uint64_t z0 = t0 >> (uint32_t)26U;
|
||||
uint64_t z1 = t3 >> (uint32_t)26U;
|
||||
uint64_t x0 = t0 & mask26;
|
||||
uint64_t x3 = t3 & mask26;
|
||||
uint64_t x1 = t1 + z0;
|
||||
uint64_t x4 = t4 + z1;
|
||||
uint64_t z01 = x1 >> (uint32_t)26U;
|
||||
uint64_t z11 = x4 >> (uint32_t)26U;
|
||||
uint64_t t = z11 << (uint32_t)2U;
|
||||
uint64_t z12 = z11 + t;
|
||||
uint64_t x11 = x1 & mask26;
|
||||
uint64_t x41 = x4 & mask26;
|
||||
uint64_t x2 = t2 + z01;
|
||||
uint64_t x01 = x0 + z12;
|
||||
uint64_t z02 = x2 >> (uint32_t)26U;
|
||||
uint64_t z13 = x01 >> (uint32_t)26U;
|
||||
uint64_t x21 = x2 & mask26;
|
||||
uint64_t x02 = x01 & mask26;
|
||||
uint64_t x31 = x3 + z02;
|
||||
uint64_t x12 = x11 + z13;
|
||||
uint64_t z03 = x31 >> (uint32_t)26U;
|
||||
uint64_t x32 = x31 & mask26;
|
||||
uint64_t x42 = x41 + z03;
|
||||
uint64_t o0 = x02;
|
||||
uint64_t o1 = x12;
|
||||
uint64_t o2 = x21;
|
||||
uint64_t o3 = x32;
|
||||
uint64_t o4 = x42;
|
||||
acc0[0U] = o0;
|
||||
acc0[1U] = o1;
|
||||
acc0[2U] = o2;
|
||||
acc0[3U] = o3;
|
||||
acc0[4U] = o4;
|
||||
}
|
||||
if (rem1 > (uint32_t)0U) {
|
||||
uint8_t *last = blocks + nb * (uint32_t)16U;
|
||||
uint64_t e[5U] = { 0U };
|
||||
uint8_t tmp[16U] = { 0U };
|
||||
memcpy(tmp, last, rem1 * sizeof(last[0U]));
|
||||
uint64_t u0 = load64_le(tmp);
|
||||
uint64_t lo = u0;
|
||||
uint64_t u = load64_le(tmp + (uint32_t)8U);
|
||||
uint64_t hi = u;
|
||||
uint64_t f0 = lo;
|
||||
uint64_t f1 = hi;
|
||||
uint64_t f010 = f0 & (uint64_t)0x3ffffffU;
|
||||
uint64_t f110 = f0 >> (uint32_t)26U & (uint64_t)0x3ffffffU;
|
||||
uint64_t f20 = f0 >> (uint32_t)52U | (f1 & (uint64_t)0x3fffU) << (uint32_t)12U;
|
||||
uint64_t f30 = f1 >> (uint32_t)14U & (uint64_t)0x3ffffffU;
|
||||
uint64_t f40 = f1 >> (uint32_t)40U;
|
||||
uint64_t f01 = f010;
|
||||
uint64_t f111 = f110;
|
||||
uint64_t f2 = f20;
|
||||
uint64_t f3 = f30;
|
||||
uint64_t f4 = f40;
|
||||
e[0U] = f01;
|
||||
e[1U] = f111;
|
||||
e[2U] = f2;
|
||||
e[3U] = f3;
|
||||
e[4U] = f4;
|
||||
uint64_t b = (uint64_t)1U << rem1 * (uint32_t)8U % (uint32_t)26U;
|
||||
uint64_t mask = b;
|
||||
uint64_t fi = e[rem1 * (uint32_t)8U / (uint32_t)26U];
|
||||
e[rem1 * (uint32_t)8U / (uint32_t)26U] = fi | mask;
|
||||
uint64_t *r1 = pre0;
|
||||
uint64_t *r5 = pre0 + (uint32_t)5U;
|
||||
uint64_t r0 = r1[0U];
|
||||
uint64_t r11 = r1[1U];
|
||||
uint64_t r2 = r1[2U];
|
||||
uint64_t r3 = r1[3U];
|
||||
uint64_t r4 = r1[4U];
|
||||
uint64_t r51 = r5[1U];
|
||||
uint64_t r52 = r5[2U];
|
||||
uint64_t r53 = r5[3U];
|
||||
uint64_t r54 = r5[4U];
|
||||
uint64_t f10 = e[0U];
|
||||
uint64_t f11 = e[1U];
|
||||
uint64_t f12 = e[2U];
|
||||
uint64_t f13 = e[3U];
|
||||
uint64_t f14 = e[4U];
|
||||
uint64_t a0 = acc0[0U];
|
||||
uint64_t a1 = acc0[1U];
|
||||
uint64_t a2 = acc0[2U];
|
||||
uint64_t a3 = acc0[3U];
|
||||
uint64_t a4 = acc0[4U];
|
||||
uint64_t a01 = a0 + f10;
|
||||
uint64_t a11 = a1 + f11;
|
||||
uint64_t a21 = a2 + f12;
|
||||
uint64_t a31 = a3 + f13;
|
||||
uint64_t a41 = a4 + f14;
|
||||
uint64_t a02 = r0 * a01;
|
||||
uint64_t a12 = r11 * a01;
|
||||
uint64_t a22 = r2 * a01;
|
||||
uint64_t a32 = r3 * a01;
|
||||
uint64_t a42 = r4 * a01;
|
||||
uint64_t a03 = a02 + r54 * a11;
|
||||
uint64_t a13 = a12 + r0 * a11;
|
||||
uint64_t a23 = a22 + r11 * a11;
|
||||
uint64_t a33 = a32 + r2 * a11;
|
||||
uint64_t a43 = a42 + r3 * a11;
|
||||
uint64_t a04 = a03 + r53 * a21;
|
||||
uint64_t a14 = a13 + r54 * a21;
|
||||
uint64_t a24 = a23 + r0 * a21;
|
||||
uint64_t a34 = a33 + r11 * a21;
|
||||
uint64_t a44 = a43 + r2 * a21;
|
||||
uint64_t a05 = a04 + r52 * a31;
|
||||
uint64_t a15 = a14 + r53 * a31;
|
||||
uint64_t a25 = a24 + r54 * a31;
|
||||
uint64_t a35 = a34 + r0 * a31;
|
||||
uint64_t a45 = a44 + r11 * a31;
|
||||
uint64_t a06 = a05 + r51 * a41;
|
||||
uint64_t a16 = a15 + r52 * a41;
|
||||
uint64_t a26 = a25 + r53 * a41;
|
||||
uint64_t a36 = a35 + r54 * a41;
|
||||
uint64_t a46 = a45 + r0 * a41;
|
||||
uint64_t t0 = a06;
|
||||
uint64_t t1 = a16;
|
||||
uint64_t t2 = a26;
|
||||
uint64_t t3 = a36;
|
||||
uint64_t t4 = a46;
|
||||
uint64_t mask26 = (uint64_t)0x3ffffffU;
|
||||
uint64_t z0 = t0 >> (uint32_t)26U;
|
||||
uint64_t z1 = t3 >> (uint32_t)26U;
|
||||
uint64_t x0 = t0 & mask26;
|
||||
uint64_t x3 = t3 & mask26;
|
||||
uint64_t x1 = t1 + z0;
|
||||
uint64_t x4 = t4 + z1;
|
||||
uint64_t z01 = x1 >> (uint32_t)26U;
|
||||
uint64_t z11 = x4 >> (uint32_t)26U;
|
||||
uint64_t t = z11 << (uint32_t)2U;
|
||||
uint64_t z12 = z11 + t;
|
||||
uint64_t x11 = x1 & mask26;
|
||||
uint64_t x41 = x4 & mask26;
|
||||
uint64_t x2 = t2 + z01;
|
||||
uint64_t x01 = x0 + z12;
|
||||
uint64_t z02 = x2 >> (uint32_t)26U;
|
||||
uint64_t z13 = x01 >> (uint32_t)26U;
|
||||
uint64_t x21 = x2 & mask26;
|
||||
uint64_t x02 = x01 & mask26;
|
||||
uint64_t x31 = x3 + z02;
|
||||
uint64_t x12 = x11 + z13;
|
||||
uint64_t z03 = x31 >> (uint32_t)26U;
|
||||
uint64_t x32 = x31 & mask26;
|
||||
uint64_t x42 = x41 + z03;
|
||||
uint64_t o0 = x02;
|
||||
uint64_t o1 = x12;
|
||||
uint64_t o2 = x21;
|
||||
uint64_t o3 = x32;
|
||||
uint64_t o4 = x42;
|
||||
acc0[0U] = o0;
|
||||
acc0[1U] = o1;
|
||||
acc0[2U] = o2;
|
||||
acc0[3U] = o3;
|
||||
acc0[4U] = o4;
|
||||
}
|
||||
uint8_t tmp[16U] = { 0U };
|
||||
memcpy(tmp, rem, r * sizeof(rem[0U]));
|
||||
if (r > (uint32_t)0U) {
|
||||
uint64_t *pre = ctx + (uint32_t)5U;
|
||||
uint64_t *acc = ctx;
|
||||
uint64_t e[5U] = { 0U };
|
||||
uint64_t u0 = load64_le(tmp);
|
||||
uint64_t lo = u0;
|
||||
uint64_t u = load64_le(tmp + (uint32_t)8U);
|
||||
uint64_t hi = u;
|
||||
uint64_t f0 = lo;
|
||||
uint64_t f1 = hi;
|
||||
uint64_t f010 = f0 & (uint64_t)0x3ffffffU;
|
||||
uint64_t f110 = f0 >> (uint32_t)26U & (uint64_t)0x3ffffffU;
|
||||
uint64_t f20 = f0 >> (uint32_t)52U | (f1 & (uint64_t)0x3fffU) << (uint32_t)12U;
|
||||
uint64_t f30 = f1 >> (uint32_t)14U & (uint64_t)0x3ffffffU;
|
||||
uint64_t f40 = f1 >> (uint32_t)40U;
|
||||
uint64_t f01 = f010;
|
||||
uint64_t f111 = f110;
|
||||
uint64_t f2 = f20;
|
||||
uint64_t f3 = f30;
|
||||
uint64_t f41 = f40;
|
||||
e[0U] = f01;
|
||||
e[1U] = f111;
|
||||
e[2U] = f2;
|
||||
e[3U] = f3;
|
||||
e[4U] = f41;
|
||||
uint64_t b = (uint64_t)0x1000000U;
|
||||
uint64_t mask = b;
|
||||
uint64_t f4 = e[4U];
|
||||
e[4U] = f4 | mask;
|
||||
uint64_t *r1 = pre;
|
||||
uint64_t *r5 = pre + (uint32_t)5U;
|
||||
uint64_t r0 = r1[0U];
|
||||
uint64_t r11 = r1[1U];
|
||||
uint64_t r2 = r1[2U];
|
||||
uint64_t r3 = r1[3U];
|
||||
uint64_t r4 = r1[4U];
|
||||
uint64_t r51 = r5[1U];
|
||||
uint64_t r52 = r5[2U];
|
||||
uint64_t r53 = r5[3U];
|
||||
uint64_t r54 = r5[4U];
|
||||
uint64_t f10 = e[0U];
|
||||
uint64_t f11 = e[1U];
|
||||
uint64_t f12 = e[2U];
|
||||
uint64_t f13 = e[3U];
|
||||
uint64_t f14 = e[4U];
|
||||
uint64_t a0 = acc[0U];
|
||||
uint64_t a1 = acc[1U];
|
||||
uint64_t a2 = acc[2U];
|
||||
uint64_t a3 = acc[3U];
|
||||
uint64_t a4 = acc[4U];
|
||||
uint64_t a01 = a0 + f10;
|
||||
uint64_t a11 = a1 + f11;
|
||||
uint64_t a21 = a2 + f12;
|
||||
uint64_t a31 = a3 + f13;
|
||||
uint64_t a41 = a4 + f14;
|
||||
uint64_t a02 = r0 * a01;
|
||||
uint64_t a12 = r11 * a01;
|
||||
uint64_t a22 = r2 * a01;
|
||||
uint64_t a32 = r3 * a01;
|
||||
uint64_t a42 = r4 * a01;
|
||||
uint64_t a03 = a02 + r54 * a11;
|
||||
uint64_t a13 = a12 + r0 * a11;
|
||||
uint64_t a23 = a22 + r11 * a11;
|
||||
uint64_t a33 = a32 + r2 * a11;
|
||||
uint64_t a43 = a42 + r3 * a11;
|
||||
uint64_t a04 = a03 + r53 * a21;
|
||||
uint64_t a14 = a13 + r54 * a21;
|
||||
uint64_t a24 = a23 + r0 * a21;
|
||||
uint64_t a34 = a33 + r11 * a21;
|
||||
uint64_t a44 = a43 + r2 * a21;
|
||||
uint64_t a05 = a04 + r52 * a31;
|
||||
uint64_t a15 = a14 + r53 * a31;
|
||||
uint64_t a25 = a24 + r54 * a31;
|
||||
uint64_t a35 = a34 + r0 * a31;
|
||||
uint64_t a45 = a44 + r11 * a31;
|
||||
uint64_t a06 = a05 + r51 * a41;
|
||||
uint64_t a16 = a15 + r52 * a41;
|
||||
uint64_t a26 = a25 + r53 * a41;
|
||||
uint64_t a36 = a35 + r54 * a41;
|
||||
uint64_t a46 = a45 + r0 * a41;
|
||||
uint64_t t0 = a06;
|
||||
uint64_t t1 = a16;
|
||||
uint64_t t2 = a26;
|
||||
uint64_t t3 = a36;
|
||||
uint64_t t4 = a46;
|
||||
uint64_t mask26 = (uint64_t)0x3ffffffU;
|
||||
uint64_t z0 = t0 >> (uint32_t)26U;
|
||||
uint64_t z1 = t3 >> (uint32_t)26U;
|
||||
uint64_t x0 = t0 & mask26;
|
||||
uint64_t x3 = t3 & mask26;
|
||||
uint64_t x1 = t1 + z0;
|
||||
uint64_t x4 = t4 + z1;
|
||||
uint64_t z01 = x1 >> (uint32_t)26U;
|
||||
uint64_t z11 = x4 >> (uint32_t)26U;
|
||||
uint64_t t = z11 << (uint32_t)2U;
|
||||
uint64_t z12 = z11 + t;
|
||||
uint64_t x11 = x1 & mask26;
|
||||
uint64_t x41 = x4 & mask26;
|
||||
uint64_t x2 = t2 + z01;
|
||||
uint64_t x01 = x0 + z12;
|
||||
uint64_t z02 = x2 >> (uint32_t)26U;
|
||||
uint64_t z13 = x01 >> (uint32_t)26U;
|
||||
uint64_t x21 = x2 & mask26;
|
||||
uint64_t x02 = x01 & mask26;
|
||||
uint64_t x31 = x3 + z02;
|
||||
uint64_t x12 = x11 + z13;
|
||||
uint64_t z03 = x31 >> (uint32_t)26U;
|
||||
uint64_t x32 = x31 & mask26;
|
||||
uint64_t x42 = x41 + z03;
|
||||
uint64_t o0 = x02;
|
||||
uint64_t o1 = x12;
|
||||
uint64_t o2 = x21;
|
||||
uint64_t o3 = x32;
|
||||
uint64_t o4 = x42;
|
||||
acc[0U] = o0;
|
||||
acc[1U] = o1;
|
||||
acc[2U] = o2;
|
||||
acc[3U] = o3;
|
||||
acc[4U] = o4;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
poly1305_do_32(
|
||||
uint8_t *k,
|
||||
uint32_t aadlen,
|
||||
uint8_t *aad,
|
||||
uint32_t mlen,
|
||||
uint8_t *m,
|
||||
uint8_t *out)
|
||||
{
|
||||
uint64_t ctx[25U] = { 0U };
|
||||
uint8_t block[16U] = { 0U };
|
||||
Hacl_Poly1305_32_poly1305_init(ctx, k);
|
||||
poly1305_padded_32(ctx, aadlen, aad);
|
||||
poly1305_padded_32(ctx, mlen, m);
|
||||
store64_le(block, (uint64_t)aadlen);
|
||||
store64_le(block + (uint32_t)8U, (uint64_t)mlen);
|
||||
uint64_t *pre = ctx + (uint32_t)5U;
|
||||
uint64_t *acc = ctx;
|
||||
uint64_t e[5U] = { 0U };
|
||||
uint64_t u0 = load64_le(block);
|
||||
uint64_t lo = u0;
|
||||
uint64_t u = load64_le(block + (uint32_t)8U);
|
||||
uint64_t hi = u;
|
||||
uint64_t f0 = lo;
|
||||
uint64_t f1 = hi;
|
||||
uint64_t f010 = f0 & (uint64_t)0x3ffffffU;
|
||||
uint64_t f110 = f0 >> (uint32_t)26U & (uint64_t)0x3ffffffU;
|
||||
uint64_t f20 = f0 >> (uint32_t)52U | (f1 & (uint64_t)0x3fffU) << (uint32_t)12U;
|
||||
uint64_t f30 = f1 >> (uint32_t)14U & (uint64_t)0x3ffffffU;
|
||||
uint64_t f40 = f1 >> (uint32_t)40U;
|
||||
uint64_t f01 = f010;
|
||||
uint64_t f111 = f110;
|
||||
uint64_t f2 = f20;
|
||||
uint64_t f3 = f30;
|
||||
uint64_t f41 = f40;
|
||||
e[0U] = f01;
|
||||
e[1U] = f111;
|
||||
e[2U] = f2;
|
||||
e[3U] = f3;
|
||||
e[4U] = f41;
|
||||
uint64_t b = (uint64_t)0x1000000U;
|
||||
uint64_t mask = b;
|
||||
uint64_t f4 = e[4U];
|
||||
e[4U] = f4 | mask;
|
||||
uint64_t *r = pre;
|
||||
uint64_t *r5 = pre + (uint32_t)5U;
|
||||
uint64_t r0 = r[0U];
|
||||
uint64_t r1 = r[1U];
|
||||
uint64_t r2 = r[2U];
|
||||
uint64_t r3 = r[3U];
|
||||
uint64_t r4 = r[4U];
|
||||
uint64_t r51 = r5[1U];
|
||||
uint64_t r52 = r5[2U];
|
||||
uint64_t r53 = r5[3U];
|
||||
uint64_t r54 = r5[4U];
|
||||
uint64_t f10 = e[0U];
|
||||
uint64_t f11 = e[1U];
|
||||
uint64_t f12 = e[2U];
|
||||
uint64_t f13 = e[3U];
|
||||
uint64_t f14 = e[4U];
|
||||
uint64_t a0 = acc[0U];
|
||||
uint64_t a1 = acc[1U];
|
||||
uint64_t a2 = acc[2U];
|
||||
uint64_t a3 = acc[3U];
|
||||
uint64_t a4 = acc[4U];
|
||||
uint64_t a01 = a0 + f10;
|
||||
uint64_t a11 = a1 + f11;
|
||||
uint64_t a21 = a2 + f12;
|
||||
uint64_t a31 = a3 + f13;
|
||||
uint64_t a41 = a4 + f14;
|
||||
uint64_t a02 = r0 * a01;
|
||||
uint64_t a12 = r1 * a01;
|
||||
uint64_t a22 = r2 * a01;
|
||||
uint64_t a32 = r3 * a01;
|
||||
uint64_t a42 = r4 * a01;
|
||||
uint64_t a03 = a02 + r54 * a11;
|
||||
uint64_t a13 = a12 + r0 * a11;
|
||||
uint64_t a23 = a22 + r1 * a11;
|
||||
uint64_t a33 = a32 + r2 * a11;
|
||||
uint64_t a43 = a42 + r3 * a11;
|
||||
uint64_t a04 = a03 + r53 * a21;
|
||||
uint64_t a14 = a13 + r54 * a21;
|
||||
uint64_t a24 = a23 + r0 * a21;
|
||||
uint64_t a34 = a33 + r1 * a21;
|
||||
uint64_t a44 = a43 + r2 * a21;
|
||||
uint64_t a05 = a04 + r52 * a31;
|
||||
uint64_t a15 = a14 + r53 * a31;
|
||||
uint64_t a25 = a24 + r54 * a31;
|
||||
uint64_t a35 = a34 + r0 * a31;
|
||||
uint64_t a45 = a44 + r1 * a31;
|
||||
uint64_t a06 = a05 + r51 * a41;
|
||||
uint64_t a16 = a15 + r52 * a41;
|
||||
uint64_t a26 = a25 + r53 * a41;
|
||||
uint64_t a36 = a35 + r54 * a41;
|
||||
uint64_t a46 = a45 + r0 * a41;
|
||||
uint64_t t0 = a06;
|
||||
uint64_t t1 = a16;
|
||||
uint64_t t2 = a26;
|
||||
uint64_t t3 = a36;
|
||||
uint64_t t4 = a46;
|
||||
uint64_t mask26 = (uint64_t)0x3ffffffU;
|
||||
uint64_t z0 = t0 >> (uint32_t)26U;
|
||||
uint64_t z1 = t3 >> (uint32_t)26U;
|
||||
uint64_t x0 = t0 & mask26;
|
||||
uint64_t x3 = t3 & mask26;
|
||||
uint64_t x1 = t1 + z0;
|
||||
uint64_t x4 = t4 + z1;
|
||||
uint64_t z01 = x1 >> (uint32_t)26U;
|
||||
uint64_t z11 = x4 >> (uint32_t)26U;
|
||||
uint64_t t = z11 << (uint32_t)2U;
|
||||
uint64_t z12 = z11 + t;
|
||||
uint64_t x11 = x1 & mask26;
|
||||
uint64_t x41 = x4 & mask26;
|
||||
uint64_t x2 = t2 + z01;
|
||||
uint64_t x01 = x0 + z12;
|
||||
uint64_t z02 = x2 >> (uint32_t)26U;
|
||||
uint64_t z13 = x01 >> (uint32_t)26U;
|
||||
uint64_t x21 = x2 & mask26;
|
||||
uint64_t x02 = x01 & mask26;
|
||||
uint64_t x31 = x3 + z02;
|
||||
uint64_t x12 = x11 + z13;
|
||||
uint64_t z03 = x31 >> (uint32_t)26U;
|
||||
uint64_t x32 = x31 & mask26;
|
||||
uint64_t x42 = x41 + z03;
|
||||
uint64_t o0 = x02;
|
||||
uint64_t o1 = x12;
|
||||
uint64_t o2 = x21;
|
||||
uint64_t o3 = x32;
|
||||
uint64_t o4 = x42;
|
||||
acc[0U] = o0;
|
||||
acc[1U] = o1;
|
||||
acc[2U] = o2;
|
||||
acc[3U] = o3;
|
||||
acc[4U] = o4;
|
||||
Hacl_Poly1305_32_poly1305_finish(out, k, ctx);
|
||||
}
|
||||
|
||||
void
|
||||
Chacha20Poly1305_vsx_aead_encrypt(
|
||||
uint8_t *k,
|
||||
uint8_t *n,
|
||||
uint32_t aadlen,
|
||||
uint8_t *aad,
|
||||
uint32_t mlen,
|
||||
uint8_t *m,
|
||||
uint8_t *cipher,
|
||||
uint8_t *mac)
|
||||
{
|
||||
chacha20vsx(mlen, cipher, m, k, n, (uint32_t)1U);
|
||||
uint8_t tmp[64U] = { 0U };
|
||||
chacha20vsx((uint32_t)64U, tmp, tmp, k, n, (uint32_t)0U);
|
||||
uint8_t *key = tmp;
|
||||
poly1305_do_32(key, aadlen, aad, mlen, cipher, mac);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Chacha20Poly1305_vsx_aead_decrypt(
|
||||
uint8_t *k,
|
||||
uint8_t *n,
|
||||
uint32_t aadlen,
|
||||
uint8_t *aad,
|
||||
uint32_t mlen,
|
||||
uint8_t *m,
|
||||
uint8_t *cipher,
|
||||
uint8_t *mac)
|
||||
{
|
||||
uint8_t computed_mac[16U] = { 0U };
|
||||
uint8_t tmp[64U] = { 0U };
|
||||
chacha20vsx((uint32_t)64U, tmp, tmp, k, n, (uint32_t)0U);
|
||||
uint8_t *key = tmp;
|
||||
poly1305_do_32(key, aadlen, aad, mlen, cipher, computed_mac);
|
||||
uint8_t res = (uint8_t)255U;
|
||||
for (uint32_t i = (uint32_t)0U; i < (uint32_t)16U; i++) {
|
||||
uint8_t uu____0 = FStar_UInt8_eq_mask(computed_mac[i], mac[i]);
|
||||
res = uu____0 & res;
|
||||
}
|
||||
uint8_t z = res;
|
||||
if (z == (uint8_t)255U) {
|
||||
chacha20vsx(mlen, m, cipher, k, n, (uint32_t)1U);
|
||||
return (uint32_t)0U;
|
||||
}
|
||||
return (uint32_t)1U;
|
||||
}
|
||||
|
|
@ -13,91 +13,135 @@
|
|||
#include "secerr.h"
|
||||
#include "blapit.h"
|
||||
#include "blapii.h"
|
||||
|
||||
#ifndef NSS_DISABLE_CHACHAPOLY
|
||||
#include "chacha20poly1305.h"
|
||||
// Forward declaration from "Hacl_Chacha20_Vec128.h".
|
||||
extern void Hacl_Chacha20_Vec128_chacha20(uint8_t *output, uint8_t *plain,
|
||||
uint32_t len, uint8_t *k, uint8_t *n1,
|
||||
uint32_t ctr);
|
||||
// Forward declaration from "Hacl_Chacha20.h".
|
||||
extern void Hacl_Chacha20_chacha20(uint8_t *output, uint8_t *plain, uint32_t len,
|
||||
uint8_t *k, uint8_t *n1, uint32_t ctr);
|
||||
|
||||
#if defined(HAVE_INT128_SUPPORT) && (defined(NSS_X86_OR_X64) || defined(__aarch64__))
|
||||
/* Use HACL* Poly1305 on 64-bit Intel and ARM */
|
||||
#include "verified/Hacl_Poly1305_64.h"
|
||||
#define NSS_POLY1305_64 1
|
||||
#define Hacl_Poly1305_update Hacl_Poly1305_64_update
|
||||
#define Hacl_Poly1305_mk_state Hacl_Poly1305_64_mk_state
|
||||
#define Hacl_Poly1305_init Hacl_Poly1305_64_init
|
||||
#define Hacl_Poly1305_finish Hacl_Poly1305_64_finish
|
||||
typedef Hacl_Impl_Poly1305_64_State_poly1305_state Hacl_Impl_Poly1305_State_poly1305_state;
|
||||
#else
|
||||
/* All other platforms get the 32-bit poly1305 HACL* implementation. */
|
||||
#include "verified/Hacl_Poly1305_32.h"
|
||||
#define NSS_POLY1305_32 1
|
||||
#define Hacl_Poly1305_update Hacl_Poly1305_32_update
|
||||
#define Hacl_Poly1305_mk_state Hacl_Poly1305_32_mk_state
|
||||
#define Hacl_Poly1305_init Hacl_Poly1305_32_init
|
||||
#define Hacl_Poly1305_finish Hacl_Poly1305_32_finish
|
||||
typedef Hacl_Impl_Poly1305_32_State_poly1305_state Hacl_Impl_Poly1305_State_poly1305_state;
|
||||
#endif /* HAVE_INT128_SUPPORT */
|
||||
// There are three implementations of ChaCha20Poly1305:
|
||||
// 1) 128-bit with AVX hardware acceleration used on x64
|
||||
// 2) 256-bit with AVX2 hardware acceleration used on x64
|
||||
// 3) 32-bit used on all other platforms
|
||||
|
||||
static void
|
||||
Poly1305PadUpdate(Hacl_Impl_Poly1305_State_poly1305_state state,
|
||||
unsigned char *block, const unsigned char *p,
|
||||
const unsigned int pLen)
|
||||
// On x64 when AVX2 and other necessary registers are available,
|
||||
// the 256bit-verctorized version will be used. When AVX2 features
|
||||
// are unavailable or disabled but AVX registers are available, the
|
||||
// 128bit-vectorized version will be used. In all other cases the
|
||||
// scalar version of the HACL* code will be used.
|
||||
|
||||
// Instead of including the headers (they bring other things we don't want),
|
||||
// we declare the functions here.
|
||||
// Usage is guarded by runtime checks of required hardware features.
|
||||
|
||||
// Forward declaration from Hacl_Chacha20_Vec128.h and Hacl_Chacha20Poly1305_128.h.
|
||||
extern void Hacl_Chacha20_Vec128_chacha20_encrypt_128(uint32_t len, uint8_t *out,
|
||||
uint8_t *text, uint8_t *key,
|
||||
uint8_t *n1, uint32_t ctr);
|
||||
extern void
|
||||
Hacl_Chacha20Poly1305_128_aead_encrypt(uint8_t *k, uint8_t *n1, uint32_t aadlen,
|
||||
uint8_t *aad, uint32_t mlen, uint8_t *m,
|
||||
uint8_t *cipher, uint8_t *mac);
|
||||
extern uint32_t
|
||||
Hacl_Chacha20Poly1305_128_aead_decrypt(uint8_t *k, uint8_t *n1, uint32_t aadlen,
|
||||
uint8_t *aad, uint32_t mlen, uint8_t *m,
|
||||
uint8_t *cipher, uint8_t *mac);
|
||||
|
||||
// Forward declaration from Hacl_Chacha20_Vec256.h and Hacl_Chacha20Poly1305_256.h.
|
||||
extern void Hacl_Chacha20_Vec256_chacha20_encrypt_256(uint32_t len, uint8_t *out,
|
||||
uint8_t *text, uint8_t *key,
|
||||
uint8_t *n1, uint32_t ctr);
|
||||
extern void
|
||||
Hacl_Chacha20Poly1305_256_aead_encrypt(uint8_t *k, uint8_t *n1, uint32_t aadlen,
|
||||
uint8_t *aad, uint32_t mlen, uint8_t *m,
|
||||
uint8_t *cipher, uint8_t *mac);
|
||||
extern uint32_t
|
||||
Hacl_Chacha20Poly1305_256_aead_decrypt(uint8_t *k, uint8_t *n1, uint32_t aadlen,
|
||||
uint8_t *aad, uint32_t mlen, uint8_t *m,
|
||||
uint8_t *cipher, uint8_t *mac);
|
||||
|
||||
// Forward declaration from Hacl_Chacha20.h and Hacl_Chacha20Poly1305_32.h.
|
||||
extern void Hacl_Chacha20_chacha20_encrypt(uint32_t len, uint8_t *out,
|
||||
uint8_t *text, uint8_t *key,
|
||||
uint8_t *n1, uint32_t ctr);
|
||||
extern void
|
||||
Hacl_Chacha20Poly1305_32_aead_encrypt(uint8_t *k, uint8_t *n1, uint32_t aadlen,
|
||||
uint8_t *aad, uint32_t mlen, uint8_t *m,
|
||||
uint8_t *cipher, uint8_t *mac);
|
||||
extern uint32_t
|
||||
Hacl_Chacha20Poly1305_32_aead_decrypt(uint8_t *k, uint8_t *n1, uint32_t aadlen,
|
||||
uint8_t *aad, uint32_t mlen, uint8_t *m,
|
||||
uint8_t *cipher, uint8_t *mac);
|
||||
|
||||
// Forward declaration from chacha20-ppc64le.S
|
||||
void chacha20vsx(uint32_t len, uint8_t *output, uint8_t *block, uint8_t *k,
|
||||
uint8_t *nonce, uint32_t ctr);
|
||||
|
||||
// Forward declaration from chacha20poly1305-ppc.c
|
||||
extern void
|
||||
Chacha20Poly1305_vsx_aead_encrypt(uint8_t *k, uint8_t *n1, uint32_t aadlen,
|
||||
uint8_t *aad, uint32_t mlen, uint8_t *m,
|
||||
uint8_t *cipher, uint8_t *mac);
|
||||
extern uint32_t
|
||||
Chacha20Poly1305_vsx_aead_decrypt(uint8_t *k, uint8_t *n1, uint32_t aadlen,
|
||||
uint8_t *aad, uint32_t mlen, uint8_t *m,
|
||||
uint8_t *cipher, uint8_t *mac);
|
||||
|
||||
SECStatus
|
||||
ChaCha20_InitContext(ChaCha20Context *ctx, const unsigned char *key,
|
||||
unsigned int keyLen, const unsigned char *nonce,
|
||||
unsigned int nonceLen, PRUint32 ctr)
|
||||
{
|
||||
unsigned int pRemLen = pLen % 16;
|
||||
Hacl_Poly1305_update(state, (uint8_t *)p, (pLen / 16));
|
||||
if (pRemLen > 0) {
|
||||
memcpy(block, p + (pLen - pRemLen), pRemLen);
|
||||
Hacl_Poly1305_update(state, block, 1);
|
||||
#ifdef NSS_DISABLE_CHACHAPOLY
|
||||
return SECFailure;
|
||||
#else
|
||||
if (keyLen != 32) {
|
||||
PORT_SetError(SEC_ERROR_BAD_KEY);
|
||||
return SECFailure;
|
||||
}
|
||||
if (nonceLen != 12) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
}
|
||||
|
||||
/* Poly1305Do writes the Poly1305 authenticator of the given additional data
|
||||
* and ciphertext to |out|. */
|
||||
static void
|
||||
Poly1305Do(unsigned char *out, const unsigned char *ad, unsigned int adLen,
|
||||
const unsigned char *ciphertext, unsigned int ciphertextLen,
|
||||
const unsigned char key[32])
|
||||
{
|
||||
#ifdef NSS_POLY1305_64
|
||||
uint64_t stateStack[6U] = { 0U };
|
||||
size_t offset = 3;
|
||||
#elif defined NSS_POLY1305_32
|
||||
uint32_t stateStack[10U] = { 0U };
|
||||
size_t offset = 5;
|
||||
#else
|
||||
#error "This can't happen."
|
||||
ctx->counter = ctr;
|
||||
PORT_Memcpy(ctx->key, key, sizeof(ctx->key));
|
||||
PORT_Memcpy(ctx->nonce, nonce, sizeof(ctx->nonce));
|
||||
|
||||
return SECSuccess;
|
||||
#endif
|
||||
}
|
||||
|
||||
ChaCha20Context *
|
||||
ChaCha20_CreateContext(const unsigned char *key, unsigned int keyLen,
|
||||
const unsigned char *nonce, unsigned int nonceLen,
|
||||
PRUint32 ctr)
|
||||
{
|
||||
#ifdef NSS_DISABLE_CHACHAPOLY
|
||||
return NULL;
|
||||
#else
|
||||
ChaCha20Context *ctx;
|
||||
|
||||
ctx = PORT_New(ChaCha20Context);
|
||||
if (ctx == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ChaCha20_InitContext(ctx, key, keyLen, nonce, nonceLen, ctr) != SECSuccess) {
|
||||
PORT_Free(ctx);
|
||||
ctx = NULL;
|
||||
}
|
||||
|
||||
return ctx;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
ChaCha20_DestroyContext(ChaCha20Context *ctx, PRBool freeit)
|
||||
{
|
||||
#ifndef NSS_DISABLE_CHACHAPOLY
|
||||
PORT_Memset(ctx, 0, sizeof(*ctx));
|
||||
if (freeit) {
|
||||
PORT_Free(ctx);
|
||||
}
|
||||
#endif
|
||||
Hacl_Impl_Poly1305_State_poly1305_state state =
|
||||
Hacl_Poly1305_mk_state(stateStack, stateStack + offset);
|
||||
|
||||
unsigned char block[16] = { 0 };
|
||||
Hacl_Poly1305_init(state, (uint8_t *)key);
|
||||
|
||||
Poly1305PadUpdate(state, block, ad, adLen);
|
||||
memset(block, 0, 16);
|
||||
Poly1305PadUpdate(state, block, ciphertext, ciphertextLen);
|
||||
|
||||
unsigned int i;
|
||||
unsigned int j;
|
||||
for (i = 0, j = adLen; i < 8; i++, j >>= 8) {
|
||||
block[i] = j;
|
||||
}
|
||||
for (i = 8, j = ciphertextLen; i < 16; i++, j >>= 8) {
|
||||
block[i] = j;
|
||||
}
|
||||
|
||||
Hacl_Poly1305_update(state, block, 1);
|
||||
Hacl_Poly1305_finish(state, out, (uint8_t *)(key + 16));
|
||||
#undef NSS_POLY1305_64
|
||||
#undef NSS_POLY1305_32
|
||||
}
|
||||
#endif /* NSS_DISABLE_CHACHAPOLY */
|
||||
|
||||
SECStatus
|
||||
ChaCha20Poly1305_InitContext(ChaCha20Poly1305Context *ctx,
|
||||
|
|
@ -162,10 +206,31 @@ void
|
|||
ChaCha20Xor(uint8_t *output, uint8_t *block, uint32_t len, uint8_t *k,
|
||||
uint8_t *nonce, uint32_t ctr)
|
||||
{
|
||||
if (ssse3_support() || arm_neon_support()) {
|
||||
Hacl_Chacha20_Vec128_chacha20(output, block, len, k, nonce, ctr);
|
||||
} else {
|
||||
Hacl_Chacha20_chacha20(output, block, len, k, nonce, ctr);
|
||||
#ifdef NSS_X64
|
||||
#ifndef NSS_DISABLE_AVX2
|
||||
if (avx2_support()) {
|
||||
Hacl_Chacha20_Vec256_chacha20_encrypt_256(len, output, block, k, nonce, ctr);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NSS_DISABLE_SSE3
|
||||
if (ssse3_support() && sse4_1_support() && avx_support()) {
|
||||
Hacl_Chacha20_Vec128_chacha20_encrypt_128(len, output, block, k, nonce, ctr);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#elif defined(__powerpc64__) && defined(__LITTLE_ENDIAN__) && \
|
||||
!defined(NSS_DISABLE_ALTIVEC) && !defined(NSS_DISABLE_CRYPTO_VSX)
|
||||
if (ppc_crypto_support()) {
|
||||
chacha20vsx(len, output, block, k, nonce, ctr);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
{
|
||||
Hacl_Chacha20_chacha20_encrypt(len, output, block, k, nonce, ctr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif /* NSS_DISABLE_CHACHAPOLY */
|
||||
|
|
@ -178,9 +243,12 @@ ChaCha20_Xor(unsigned char *output, const unsigned char *block, unsigned int len
|
|||
return SECFailure;
|
||||
#else
|
||||
// ChaCha has a 64 octet block, with a 32-bit block counter.
|
||||
if (sizeof(len) > 4 && len >= (1ULL << (6 + 32))) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
if (sizeof(len) > 4) {
|
||||
unsigned long long len_ull = len;
|
||||
if (len_ull >= (1ULL << (6 + 32))) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
}
|
||||
ChaCha20Xor(output, (uint8_t *)block, len, (uint8_t *)k,
|
||||
(uint8_t *)nonce, ctr);
|
||||
|
|
@ -198,34 +266,60 @@ ChaCha20Poly1305_Seal(const ChaCha20Poly1305Context *ctx, unsigned char *output,
|
|||
#ifdef NSS_DISABLE_CHACHAPOLY
|
||||
return SECFailure;
|
||||
#else
|
||||
unsigned char block[64];
|
||||
unsigned char tag[16];
|
||||
|
||||
if (nonceLen != 12) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
// ChaCha has a 64 octet block, with a 32-bit block counter.
|
||||
if (sizeof(inputLen) > 4 && inputLen >= (1ULL << (6 + 32))) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
if (sizeof(inputLen) > 4) {
|
||||
unsigned long long inputLen_ull = inputLen;
|
||||
if (inputLen_ull >= (1ULL << (6 + 32))) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
}
|
||||
if (maxOutputLen < inputLen + ctx->tagLen) {
|
||||
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
PORT_Memset(block, 0, sizeof(block));
|
||||
// Generate a block of keystream. The first 32 bytes will be the poly1305
|
||||
// key. The remainder of the block is discarded.
|
||||
ChaCha20Xor(block, (uint8_t *)block, sizeof(block), (uint8_t *)ctx->key,
|
||||
(uint8_t *)nonce, 0);
|
||||
ChaCha20Xor(output, (uint8_t *)input, inputLen, (uint8_t *)ctx->key,
|
||||
(uint8_t *)nonce, 1);
|
||||
#ifdef NSS_X64
|
||||
#ifndef NSS_DISABLE_AVX2
|
||||
if (avx2_support()) {
|
||||
Hacl_Chacha20Poly1305_256_aead_encrypt(
|
||||
(uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, inputLen,
|
||||
(uint8_t *)input, output, output + inputLen);
|
||||
goto finish;
|
||||
}
|
||||
#endif
|
||||
|
||||
Poly1305Do(tag, ad, adLen, output, inputLen, block);
|
||||
PORT_Memcpy(output + inputLen, tag, ctx->tagLen);
|
||||
#ifndef NSS_DISABLE_SSE3
|
||||
if (ssse3_support() && sse4_1_support() && avx_support()) {
|
||||
Hacl_Chacha20Poly1305_128_aead_encrypt(
|
||||
(uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, inputLen,
|
||||
(uint8_t *)input, output, output + inputLen);
|
||||
goto finish;
|
||||
}
|
||||
#endif
|
||||
|
||||
#elif defined(__powerpc64__) && defined(__LITTLE_ENDIAN__) && \
|
||||
!defined(NSS_DISABLE_ALTIVEC) && !defined(NSS_DISABLE_CRYPTO_VSX)
|
||||
if (ppc_crypto_support()) {
|
||||
Chacha20Poly1305_vsx_aead_encrypt(
|
||||
(uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, inputLen,
|
||||
(uint8_t *)input, output, output + inputLen);
|
||||
goto finish;
|
||||
}
|
||||
#endif
|
||||
{
|
||||
Hacl_Chacha20Poly1305_32_aead_encrypt(
|
||||
(uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, inputLen,
|
||||
(uint8_t *)input, output, output + inputLen);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
finish:
|
||||
*outputLen = inputLen + ctx->tagLen;
|
||||
return SECSuccess;
|
||||
#endif
|
||||
|
|
@ -241,8 +335,6 @@ ChaCha20Poly1305_Open(const ChaCha20Poly1305Context *ctx, unsigned char *output,
|
|||
#ifdef NSS_DISABLE_CHACHAPOLY
|
||||
return SECFailure;
|
||||
#else
|
||||
unsigned char block[64];
|
||||
unsigned char tag[16];
|
||||
unsigned int ciphertextLen;
|
||||
|
||||
if (nonceLen != 12) {
|
||||
|
|
@ -264,20 +356,195 @@ ChaCha20Poly1305_Open(const ChaCha20Poly1305Context *ctx, unsigned char *output,
|
|||
return SECFailure;
|
||||
}
|
||||
|
||||
PORT_Memset(block, 0, sizeof(block));
|
||||
// Generate a block of keystream. The first 32 bytes will be the poly1305
|
||||
// key. The remainder of the block is discarded.
|
||||
ChaCha20Xor(block, (uint8_t *)block, sizeof(block), (uint8_t *)ctx->key,
|
||||
(uint8_t *)nonce, 0);
|
||||
Poly1305Do(tag, ad, adLen, input, ciphertextLen, block);
|
||||
if (NSS_SecureMemcmp(tag, &input[ciphertextLen], ctx->tagLen) != 0) {
|
||||
uint32_t res = 1;
|
||||
#ifdef NSS_X64
|
||||
#ifndef NSS_DISABLE_AVX2
|
||||
if (avx2_support()) {
|
||||
res = Hacl_Chacha20Poly1305_256_aead_decrypt(
|
||||
(uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, ciphertextLen,
|
||||
(uint8_t *)output, (uint8_t *)input, (uint8_t *)input + ciphertextLen);
|
||||
goto finish;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NSS_DISABLE_SSE3
|
||||
if (ssse3_support() && sse4_1_support() && avx_support()) {
|
||||
res = Hacl_Chacha20Poly1305_128_aead_decrypt(
|
||||
(uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, ciphertextLen,
|
||||
(uint8_t *)output, (uint8_t *)input, (uint8_t *)input + ciphertextLen);
|
||||
goto finish;
|
||||
}
|
||||
#endif
|
||||
|
||||
#elif defined(__powerpc64__) && defined(__LITTLE_ENDIAN__) && \
|
||||
!defined(NSS_DISABLE_ALTIVEC) && !defined(NSS_DISABLE_CRYPTO_VSX)
|
||||
if (ppc_crypto_support()) {
|
||||
res = Chacha20Poly1305_vsx_aead_decrypt(
|
||||
(uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, ciphertextLen,
|
||||
(uint8_t *)output, (uint8_t *)input, (uint8_t *)input + ciphertextLen);
|
||||
goto finish;
|
||||
}
|
||||
#endif
|
||||
{
|
||||
res = Hacl_Chacha20Poly1305_32_aead_decrypt(
|
||||
(uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, ciphertextLen,
|
||||
(uint8_t *)output, (uint8_t *)input, (uint8_t *)input + ciphertextLen);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
finish:
|
||||
if (res) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DATA);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
*outputLen = ciphertextLen;
|
||||
return SECSuccess;
|
||||
#endif
|
||||
}
|
||||
|
||||
SECStatus
|
||||
ChaCha20Poly1305_Encrypt(const ChaCha20Poly1305Context *ctx,
|
||||
unsigned char *output, unsigned int *outputLen,
|
||||
unsigned int maxOutputLen, const unsigned char *input,
|
||||
unsigned int inputLen, const unsigned char *nonce,
|
||||
unsigned int nonceLen, const unsigned char *ad,
|
||||
unsigned int adLen, unsigned char *outTag)
|
||||
{
|
||||
#ifdef NSS_DISABLE_CHACHAPOLY
|
||||
return SECFailure;
|
||||
#else
|
||||
|
||||
if (nonceLen != 12) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
// ChaCha has a 64 octet block, with a 32-bit block counter.
|
||||
if (sizeof(inputLen) > 4) {
|
||||
unsigned long long inputLen_ull = inputLen;
|
||||
if (inputLen_ull >= (1ULL << (6 + 32))) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
}
|
||||
if (maxOutputLen < inputLen) {
|
||||
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
#ifdef NSS_X64
|
||||
#ifndef NSS_DISABLE_AVX2
|
||||
if (avx2_support()) {
|
||||
Hacl_Chacha20Poly1305_256_aead_encrypt(
|
||||
(uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, inputLen,
|
||||
(uint8_t *)input, output, outTag);
|
||||
goto finish;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NSS_DISABLE_SSE3
|
||||
if (ssse3_support() && sse4_1_support() && avx_support()) {
|
||||
Hacl_Chacha20Poly1305_128_aead_encrypt(
|
||||
(uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, inputLen,
|
||||
(uint8_t *)input, output, outTag);
|
||||
goto finish;
|
||||
}
|
||||
#endif
|
||||
#elif defined(__powerpc64__) && defined(__LITTLE_ENDIAN__) && \
|
||||
!defined(NSS_DISABLE_ALTIVEC) && !defined(NSS_DISABLE_CRYPTO_VSX)
|
||||
if (ppc_crypto_support()) {
|
||||
Chacha20Poly1305_vsx_aead_encrypt(
|
||||
(uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, inputLen,
|
||||
(uint8_t *)input, output, outTag);
|
||||
goto finish;
|
||||
}
|
||||
#endif
|
||||
{
|
||||
Hacl_Chacha20Poly1305_32_aead_encrypt(
|
||||
(uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, inputLen,
|
||||
(uint8_t *)input, output, outTag);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
finish:
|
||||
*outputLen = inputLen;
|
||||
return SECSuccess;
|
||||
#endif
|
||||
}
|
||||
|
||||
SECStatus
|
||||
ChaCha20Poly1305_Decrypt(const ChaCha20Poly1305Context *ctx,
|
||||
unsigned char *output, unsigned int *outputLen,
|
||||
unsigned int maxOutputLen, const unsigned char *input,
|
||||
unsigned int inputLen, const unsigned char *nonce,
|
||||
unsigned int nonceLen, const unsigned char *ad,
|
||||
unsigned int adLen, const unsigned char *tagIn)
|
||||
{
|
||||
#ifdef NSS_DISABLE_CHACHAPOLY
|
||||
return SECFailure;
|
||||
#else
|
||||
unsigned int ciphertextLen;
|
||||
|
||||
if (nonceLen != 12) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
ciphertextLen = inputLen;
|
||||
if (maxOutputLen < ciphertextLen) {
|
||||
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
// ChaCha has a 64 octet block, with a 32-bit block counter.
|
||||
if (sizeof(inputLen) > 4) {
|
||||
unsigned long long inputLen_ull = inputLen;
|
||||
if (inputLen_ull >= (1ULL << (6 + 32))) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t res = 1;
|
||||
#ifdef NSS_X64
|
||||
#ifndef NSS_DISABLE_AVX2
|
||||
if (avx2_support()) {
|
||||
res = Hacl_Chacha20Poly1305_256_aead_decrypt(
|
||||
(uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, ciphertextLen,
|
||||
(uint8_t *)output, (uint8_t *)input, (uint8_t *)tagIn);
|
||||
goto finish;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NSS_DISABLE_SSE3
|
||||
if (ssse3_support() && sse4_1_support() && avx_support()) {
|
||||
res = Hacl_Chacha20Poly1305_128_aead_decrypt(
|
||||
(uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, ciphertextLen,
|
||||
(uint8_t *)output, (uint8_t *)input, (uint8_t *)tagIn);
|
||||
goto finish;
|
||||
}
|
||||
#endif
|
||||
|
||||
#elif defined(__powerpc64__) && defined(__LITTLE_ENDIAN__) && \
|
||||
!defined(NSS_DISABLE_ALTIVEC) && !defined(NSS_DISABLE_CRYPTO_VSX)
|
||||
if (ppc_crypto_support()) {
|
||||
res = Chacha20Poly1305_vsx_aead_decrypt(
|
||||
(uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, ciphertextLen,
|
||||
(uint8_t *)output, (uint8_t *)input, (uint8_t *)tagIn);
|
||||
goto finish;
|
||||
}
|
||||
#endif
|
||||
{
|
||||
res = Hacl_Chacha20Poly1305_32_aead_decrypt(
|
||||
(uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, ciphertextLen,
|
||||
(uint8_t *)output, (uint8_t *)input, (uint8_t *)tagIn);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
finish:
|
||||
if (res) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DATA);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
ChaCha20Xor(output, (uint8_t *)input, ciphertextLen, (uint8_t *)ctx->key,
|
||||
(uint8_t *)nonce, 1);
|
||||
|
||||
*outputLen = ciphertextLen;
|
||||
return SECSuccess;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -12,4 +12,10 @@ struct ChaCha20Poly1305ContextStr {
|
|||
unsigned char tagLen;
|
||||
};
|
||||
|
||||
struct ChaCha20ContextStr {
|
||||
unsigned char key[32];
|
||||
unsigned char nonce[12];
|
||||
PRUint32 counter;
|
||||
};
|
||||
|
||||
#endif /* _CHACHA20_POLY1305_H_ */
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ struct CMACContextStr {
|
|||
union {
|
||||
AESContext *aes;
|
||||
} cipher;
|
||||
int blockSize;
|
||||
unsigned int blockSize;
|
||||
|
||||
/* Internal keys which are conditionally used by the algorithm. Derived
|
||||
* from encrypting the NULL block. We leave the storing of (and the
|
||||
|
|
@ -210,7 +210,7 @@ SECStatus
|
|||
CMAC_Update(CMACContext *ctx, const unsigned char *data,
|
||||
unsigned int data_len)
|
||||
{
|
||||
int data_index = 0;
|
||||
unsigned int data_index = 0;
|
||||
if (ctx == NULL) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
|
|
|
|||
|
|
@ -47,10 +47,6 @@ endif
|
|||
|
||||
ifeq (,$(filter-out WIN%,$(OS_TARGET)))
|
||||
|
||||
# don't want the 32 in the shared library name
|
||||
SHARED_LIBRARY = $(OBJDIR)/$(DLL_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX)
|
||||
|
||||
RES = $(OBJDIR)/$(LIBRARY_NAME).res
|
||||
RESNAME = freebl.rc
|
||||
|
||||
ifdef NS_USE_GCC
|
||||
|
|
|
|||
|
|
@ -13,7 +13,9 @@
|
|||
#include "secerr.h"
|
||||
|
||||
#ifdef USE_HW_AES
|
||||
#ifdef NSS_X86_OR_X64
|
||||
#include "intel-aes.h"
|
||||
#endif
|
||||
#include "rijndael.h"
|
||||
#endif
|
||||
|
||||
|
|
@ -207,7 +209,7 @@ CTR_Update(CTRContext *ctr, unsigned char *outbuf,
|
|||
return SECSuccess;
|
||||
}
|
||||
|
||||
#if defined(USE_HW_AES) && defined(_MSC_VER)
|
||||
#if defined(USE_HW_AES) && defined(_MSC_VER) && defined(NSS_X86_OR_X64)
|
||||
SECStatus
|
||||
CTR_Update_HW_AES(CTRContext *ctr, unsigned char *outbuf,
|
||||
unsigned int *outlen, unsigned int maxout,
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifdef FREEBL_NO_DEPEND
|
||||
#include "stubs.h"
|
||||
#include "../stubs.h"
|
||||
#endif
|
||||
|
||||
#include "blapi.h"
|
||||
#include "blapii.h"
|
||||
#include "../blapi.h"
|
||||
#include "../blapii.h"
|
||||
#include "secerr.h"
|
||||
#ifdef XP_UNIX_XXX
|
||||
#include <stddef.h> /* for ptrdiff_t */
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifdef FREEBL_NO_DEPEND
|
||||
#include "stubs.h"
|
||||
#include "../stubs.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -416,12 +416,23 @@ SEED_decrypt(const unsigned char s[SEED_BLOCK_SIZE],
|
|||
void
|
||||
SEED_ecb_encrypt(const unsigned char *in,
|
||||
unsigned char *out,
|
||||
size_t inLen,
|
||||
const SEED_KEY_SCHEDULE *ks, int enc)
|
||||
{
|
||||
if (enc) {
|
||||
SEED_encrypt(in, out, ks);
|
||||
while (inLen > 0) {
|
||||
SEED_encrypt(in, out, ks);
|
||||
out += SEED_BLOCK_SIZE;
|
||||
in += SEED_BLOCK_SIZE;
|
||||
inLen -= SEED_BLOCK_SIZE;
|
||||
}
|
||||
} else {
|
||||
SEED_decrypt(in, out, ks);
|
||||
while (inLen > 0) {
|
||||
SEED_decrypt(in, out, ks);
|
||||
out += SEED_BLOCK_SIZE;
|
||||
in += SEED_BLOCK_SIZE;
|
||||
inLen -= SEED_BLOCK_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -602,7 +613,7 @@ SEED_Encrypt(SEEDContext *cx, unsigned char *out, unsigned int *outLen,
|
|||
|
||||
switch (cx->mode) {
|
||||
case NSS_SEED:
|
||||
SEED_ecb_encrypt(in, out, &cx->ks, 1);
|
||||
SEED_ecb_encrypt(in, out, inLen, &cx->ks, 1);
|
||||
*outLen = inLen;
|
||||
break;
|
||||
|
||||
|
|
@ -642,7 +653,7 @@ SEED_Decrypt(SEEDContext *cx, unsigned char *out, unsigned int *outLen,
|
|||
|
||||
switch (cx->mode) {
|
||||
case NSS_SEED:
|
||||
SEED_ecb_encrypt(in, out, &cx->ks, 0);
|
||||
SEED_ecb_encrypt(in, out, inLen, &cx->ks, 0);
|
||||
*outLen = inLen;
|
||||
break;
|
||||
|
||||
|
|
@ -113,7 +113,7 @@ void SEED_decrypt(const unsigned char s[SEED_BLOCK_SIZE],
|
|||
const SEED_KEY_SCHEDULE *ks);
|
||||
|
||||
void SEED_ecb_encrypt(const unsigned char *in, unsigned char *out,
|
||||
const SEED_KEY_SCHEDULE *ks, int enc);
|
||||
size_t inLen, const SEED_KEY_SCHEDULE *ks, int enc);
|
||||
void SEED_cbc_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const SEED_KEY_SCHEDULE *ks,
|
||||
unsigned char ivec[SEED_BLOCK_SIZE], int enc);
|
||||
|
|
@ -99,7 +99,8 @@ RNG_GenerateGlobalRandomBytes(void *dest, size_t len)
|
|||
|
||||
memset(dest, 0, len);
|
||||
memcpy(dest, globalBytes, PR_MIN(len, GLOBAL_BYTES_SIZE));
|
||||
Hacl_Chacha20_chacha20(dest, (uint8_t *)dest, len, (uint8_t *)key, nonce, 0);
|
||||
Hacl_Chacha20_chacha20_encrypt(len, (uint8_t *)dest, (uint8_t *)dest,
|
||||
(uint8_t *)key, nonce, 0);
|
||||
ChaCha20Poly1305_DestroyContext(cx, PR_TRUE);
|
||||
|
||||
PZ_Unlock(rng_lock);
|
||||
|
|
@ -154,7 +155,9 @@ PRNGTEST_RunHealthTests()
|
|||
}
|
||||
|
||||
SECStatus
|
||||
PRNGTEST_Instantiate_Kat()
|
||||
PRNGTEST_Instantiate_Kat(const PRUint8 *entropy, unsigned int entropy_len,
|
||||
const PRUint8 *nonce, unsigned int nonce_len,
|
||||
const PRUint8 *personal_string, unsigned int ps_len)
|
||||
{
|
||||
return SECFailure;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ DH_GenParam(int primeLen, DHParams **params)
|
|||
CHECK_MPI_OK(mp_init(&h));
|
||||
CHECK_MPI_OK(mp_init(&psub1));
|
||||
CHECK_MPI_OK(mp_init(&test));
|
||||
/* generate prime with MPI, uses Miller-Rabin to generate strong prime. */
|
||||
/* generate prime with MPI, uses Miller-Rabin to generate safe prime. */
|
||||
CHECK_SEC_OK(generate_prime(&p, primeLen));
|
||||
/* construct Sophie-Germain prime q = (p-1)/2. */
|
||||
CHECK_MPI_OK(mp_sub_d(&p, 1, &psub1));
|
||||
|
|
@ -257,17 +257,17 @@ DH_Derive(SECItem *publicValue,
|
|||
}
|
||||
|
||||
/*
|
||||
* We check to make sure that ZZ is not equal to 1 or -1 mod p.
|
||||
* We check to make sure that ZZ is not equal to 0, 1 or -1 mod p.
|
||||
* This helps guard against small subgroup attacks, since an attacker
|
||||
* using a subgroup of size N will produce 1 or -1 with probability 1/N.
|
||||
* using a subgroup of size N will produce 0, 1 or -1 with probability 1/N.
|
||||
* When the protocol is executed within a properly large subgroup, the
|
||||
* probability of this result will be negligibly small. For example,
|
||||
* with a strong prime of the form 2p+1, the probability will be 1/p.
|
||||
* with a safe prime of the form 2q+1, the probability will be 1/q.
|
||||
*
|
||||
* We return MP_BADARG because this is probably the result of a bad
|
||||
* public value or a bad prime having been provided.
|
||||
*/
|
||||
if (mp_cmp_d(&ZZ, 1) == 0 ||
|
||||
if (mp_cmp_d(&ZZ, 0) == 0 || mp_cmp_d(&ZZ, 1) == 0 ||
|
||||
mp_cmp(&ZZ, &psub1) == 0) {
|
||||
err = MP_BADARG;
|
||||
goto cleanup;
|
||||
|
|
@ -413,6 +413,35 @@ cleanup:
|
|||
return SECSuccess;
|
||||
}
|
||||
|
||||
/* Test counts based on the fact the prime and subprime
|
||||
* were given to us */
|
||||
static int
|
||||
dh_prime_testcount(int prime_length)
|
||||
{
|
||||
if (prime_length < 1024) {
|
||||
return 50;
|
||||
} else if (prime_length < 2048) {
|
||||
return 40;
|
||||
} else if (prime_length < 3072) {
|
||||
return 56;
|
||||
}
|
||||
return 64;
|
||||
}
|
||||
|
||||
PRBool
|
||||
KEA_PrimeCheck(SECItem *prime)
|
||||
{
|
||||
mp_int p;
|
||||
mp_err err = 0;
|
||||
MP_DIGITS(&p) = 0;
|
||||
CHECK_MPI_OK(mp_init(&p));
|
||||
SECITEM_TO_MPINT(*prime, &p);
|
||||
CHECK_MPI_OK(mpp_pprime_secure(&p, dh_prime_testcount(prime->len)));
|
||||
cleanup:
|
||||
mp_clear(&p);
|
||||
return err ? PR_FALSE : PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
KEA_Verify(SECItem *Y, SECItem *prime, SECItem *subPrime)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -145,6 +145,7 @@ prng_Hash_df(PRUint8 *requested_bytes, unsigned int no_of_bytes_to_return,
|
|||
requested_bytes += hash_return_len;
|
||||
no_of_bytes_to_return -= hash_return_len;
|
||||
}
|
||||
SHA256_DestroyContext(&ctx, PR_FALSE);
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
|
|
@ -197,6 +198,7 @@ prng_initEntropy(void)
|
|||
SHA256_End(&ctx, globalrng->previousEntropyHash, NULL,
|
||||
sizeof(globalrng->previousEntropyHash));
|
||||
PORT_Memset(block, 0, sizeof(block));
|
||||
SHA256_DestroyContext(&ctx, PR_FALSE);
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -244,6 +246,7 @@ prng_getEntropy(PRUint8 *buffer, size_t requestLength)
|
|||
}
|
||||
|
||||
out:
|
||||
PORT_Memset(hash, 0, sizeof hash);
|
||||
PORT_Memset(block, 0, sizeof block);
|
||||
return rv;
|
||||
}
|
||||
|
|
@ -388,6 +391,7 @@ prng_Hashgen(RNGContext *rng, PRUint8 *returned_bytes,
|
|||
* This increments data if no_of_returned_bytes is not zero */
|
||||
carry = no_of_returned_bytes;
|
||||
PRNG_ADD_CARRY_ONLY(data, (sizeof data) - 1, carry);
|
||||
SHA256_DestroyContext(&ctx, PR_FALSE);
|
||||
}
|
||||
PORT_Memset(data, 0, sizeof data);
|
||||
PORT_Memset(thisHash, 0, sizeof thisHash);
|
||||
|
|
@ -430,6 +434,7 @@ prng_generateNewBytes(RNGContext *rng,
|
|||
SHA256_End(&ctx, w, NULL, sizeof w);
|
||||
PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), w, sizeof w, carry)
|
||||
PORT_Memset(w, 0, sizeof w);
|
||||
SHA256_DestroyContext(&ctx, PR_FALSE);
|
||||
#undef w
|
||||
}
|
||||
|
||||
|
|
@ -450,6 +455,7 @@ prng_generateNewBytes(RNGContext *rng,
|
|||
PRNG_ADD_CARRY_ONLY(rng->reseed_counter, (sizeof rng->reseed_counter) - 1, carry);
|
||||
|
||||
/* if the prng failed, don't return any output, signal softoken */
|
||||
PORT_Memset(H, 0, sizeof H);
|
||||
if (!rng->isValid) {
|
||||
PORT_Memset(returned_bytes, 0, no_of_returned_bytes);
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
|
|
|
|||
|
|
@ -260,7 +260,7 @@ DSA_NewRandom(PLArenaPool *arena, const SECItem *q, SECItem *seed)
|
|||
PORT_SetError(SEC_ERROR_NEED_RANDOM);
|
||||
loser:
|
||||
if (arena != NULL) {
|
||||
SECITEM_FreeItem(seed, PR_FALSE);
|
||||
SECITEM_ZfreeItem(seed, PR_FALSE);
|
||||
}
|
||||
return SECFailure;
|
||||
}
|
||||
|
|
@ -295,7 +295,7 @@ DSA_NewKey(const PQGParams *params, DSAPrivateKey **privKey)
|
|||
rv = dsa_NewKeyExtended(params, &seed, privKey);
|
||||
}
|
||||
}
|
||||
SECITEM_FreeItem(&seed, PR_FALSE);
|
||||
SECITEM_ZfreeItem(&seed, PR_FALSE);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
@ -403,6 +403,8 @@ dsa_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest,
|
|||
CHECK_MPI_OK(mp_exptmod(&g, &t, &p, &r)); /* r = g**t mod p */
|
||||
/* r is now g**(k+q*fuzz) == g**k mod p */
|
||||
CHECK_MPI_OK(mp_mod(&r, &q, &r)); /* r = r mod q */
|
||||
/* make sure fuzz is cleared off the stack and not optimized away */
|
||||
*(volatile mp_digit *)&fuzz = 0;
|
||||
|
||||
/*
|
||||
** FIPS 186-1, Section 5, Step 2
|
||||
|
|
@ -415,14 +417,14 @@ dsa_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest,
|
|||
goto cleanup;
|
||||
}
|
||||
SECITEM_TO_MPINT(t2, &t); /* t <-$ Zq */
|
||||
SECITEM_FreeItem(&t2, PR_FALSE);
|
||||
SECITEM_ZfreeItem(&t2, PR_FALSE);
|
||||
if (DSA_NewRandom(NULL, &key->params.subPrime, &t2) != SECSuccess) {
|
||||
PORT_SetError(SEC_ERROR_NEED_RANDOM);
|
||||
rv = SECFailure;
|
||||
goto cleanup;
|
||||
}
|
||||
SECITEM_TO_MPINT(t2, &ar); /* ar <-$ Zq */
|
||||
SECITEM_FreeItem(&t2, PR_FALSE);
|
||||
SECITEM_ZfreeItem(&t2, PR_FALSE);
|
||||
|
||||
/* Using mp_invmod on k directly would leak bits from k. */
|
||||
CHECK_MPI_OK(mp_mul(&k, &ar, &k)); /* k = k * ar */
|
||||
|
|
@ -530,6 +532,7 @@ DSA_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest)
|
|||
rv = dsa_SignDigest(key, signature, digest, kSeed);
|
||||
} while (rv != SECSuccess && PORT_GetError() == SEC_ERROR_NEED_RANDOM &&
|
||||
--retries > 0);
|
||||
PORT_Memset(kSeed, 0, sizeof kSeed);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
@ -670,6 +673,7 @@ DSA_VerifyDigest(DSAPublicKey *key, const SECItem *signature,
|
|||
verified = SECSuccess; /* Signature verified. */
|
||||
}
|
||||
cleanup:
|
||||
PORT_Memset(localDigestData, 0, sizeof localDigestData);
|
||||
mp_clear(&p);
|
||||
mp_clear(&q);
|
||||
mp_clear(&g);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#endif
|
||||
|
||||
#include "blapi.h"
|
||||
#include "blapii.h"
|
||||
#include "prerr.h"
|
||||
#include "secerr.h"
|
||||
#include "secmpi.h"
|
||||
|
|
@ -15,6 +16,8 @@
|
|||
#include "ec.h"
|
||||
#include "ecl.h"
|
||||
|
||||
#define EC_DOUBLECHECK PR_FALSE
|
||||
|
||||
static const ECMethod kMethods[] = {
|
||||
{ ECCurve25519,
|
||||
ec_Curve25519_pt_mul,
|
||||
|
|
@ -62,7 +65,7 @@ ec_points_mul(const ECParams *params, const mp_int *k1, const mp_int *k2,
|
|||
ECGroup *group = NULL;
|
||||
SECStatus rv = SECFailure;
|
||||
mp_err err = MP_OKAY;
|
||||
int len;
|
||||
unsigned int len;
|
||||
|
||||
#if EC_DEBUG
|
||||
int i;
|
||||
|
|
@ -96,7 +99,7 @@ ec_points_mul(const ECParams *params, const mp_int *k1, const mp_int *k2,
|
|||
#endif
|
||||
|
||||
/* NOTE: We only support uncompressed points for now */
|
||||
len = (params->fieldID.size + 7) >> 3;
|
||||
len = (((unsigned int)params->fieldID.size) + 7) >> 3;
|
||||
if (pointP != NULL) {
|
||||
if ((pointP->data[0] != EC_POINT_FORM_UNCOMPRESSED) ||
|
||||
(pointP->len != (2 * len + 1))) {
|
||||
|
|
@ -146,6 +149,10 @@ ec_points_mul(const ECParams *params, const mp_int *k1, const mp_int *k2,
|
|||
CHECK_MPI_OK(ECPoints_mul(group, k1, NULL, NULL, NULL, &Qx, &Qy));
|
||||
}
|
||||
|
||||
/* our ECC codes uses large stack variables to store intermediate results,
|
||||
* clear our stack before returning to prevent CSP leakage */
|
||||
BLAPI_CLEAR_STACK(2048)
|
||||
|
||||
/* Construct the SECItem representation of point Q */
|
||||
pointQ->data[0] = EC_POINT_FORM_UNCOMPRESSED;
|
||||
CHECK_MPI_OK(mp_to_fixlen_octets(&Qx, pointQ->data + 1,
|
||||
|
|
@ -428,7 +435,7 @@ EC_ValidatePublicKey(ECParams *ecParams, SECItem *publicValue)
|
|||
ECGroup *group = NULL;
|
||||
SECStatus rv = SECFailure;
|
||||
mp_err err = MP_OKAY;
|
||||
int len;
|
||||
unsigned int len;
|
||||
|
||||
if (!ecParams || ecParams->name == ECCurve_noName ||
|
||||
!publicValue || !publicValue->len) {
|
||||
|
|
@ -448,7 +455,7 @@ EC_ValidatePublicKey(ECParams *ecParams, SECItem *publicValue)
|
|||
}
|
||||
|
||||
/* NOTE: We only support uncompressed points for now */
|
||||
len = (ecParams->fieldID.size + 7) >> 3;
|
||||
len = (((unsigned int)ecParams->fieldID.size) + 7) >> 3;
|
||||
if (publicValue->data[0] != EC_POINT_FORM_UNCOMPRESSED) {
|
||||
PORT_SetError(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM);
|
||||
return SECFailure;
|
||||
|
|
@ -531,7 +538,6 @@ ECDH_Derive(SECItem *publicValue,
|
|||
unsigned int len = 0;
|
||||
SECItem pointQ = { siBuffer, NULL, 0 };
|
||||
mp_int k; /* to hold the private value */
|
||||
mp_int cofactor;
|
||||
mp_err err = MP_OKAY;
|
||||
#if EC_DEBUG
|
||||
int i;
|
||||
|
|
@ -596,11 +602,13 @@ ECDH_Derive(SECItem *publicValue,
|
|||
(mp_size)privateValue->len));
|
||||
|
||||
if (withCofactor && (ecParams->cofactor != 1)) {
|
||||
mp_int cofactor;
|
||||
/* multiply k with the cofactor */
|
||||
MP_DIGITS(&cofactor) = 0;
|
||||
CHECK_MPI_OK(mp_init(&cofactor));
|
||||
mp_set(&cofactor, ecParams->cofactor);
|
||||
CHECK_MPI_OK(mp_mul(&k, &cofactor, &k));
|
||||
mp_clear(&cofactor);
|
||||
}
|
||||
|
||||
/* Multiply our private key and peer's public point */
|
||||
|
|
@ -645,9 +653,10 @@ cleanup:
|
|||
* on the digest using the given key and the random value kb (used in
|
||||
* computing s).
|
||||
*/
|
||||
SECStatus
|
||||
ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature,
|
||||
const SECItem *digest, const unsigned char *kb, const int kblen)
|
||||
|
||||
static SECStatus
|
||||
ec_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature,
|
||||
const SECItem *digest, const unsigned char *kb, const int kblen)
|
||||
{
|
||||
SECStatus rv = SECFailure;
|
||||
mp_int x1;
|
||||
|
|
@ -858,7 +867,7 @@ cleanup:
|
|||
mp_clear(&ar);
|
||||
|
||||
if (t2) {
|
||||
PORT_Free(t2);
|
||||
PORT_ZFree(t2, 2 * ecParams->order.len);
|
||||
}
|
||||
|
||||
if (kGpoint.data) {
|
||||
|
|
@ -878,6 +887,34 @@ cleanup:
|
|||
return rv;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature,
|
||||
const SECItem *digest, const unsigned char *kb, const int kblen)
|
||||
{
|
||||
#if EC_DEBUG || EC_DOUBLECHECK
|
||||
|
||||
SECItem *signature2 = SECITEM_AllocItem(NULL, NULL, signature->len);
|
||||
SECStatus signSuccess = ec_SignDigestWithSeed(key, signature, digest, kb, kblen);
|
||||
SECStatus signSuccessDouble = ec_SignDigestWithSeed(key, signature2, digest, kb, kblen);
|
||||
int signaturesEqual = NSS_SecureMemcmp(signature, signature2, signature->len);
|
||||
SECStatus rv;
|
||||
if ((signaturesEqual == 0) && (signSuccess == SECSuccess) && (signSuccessDouble == SECSuccess)) {
|
||||
rv = SECSuccess;
|
||||
} else {
|
||||
rv = SECFailure;
|
||||
}
|
||||
|
||||
#if EC_DEBUG
|
||||
printf("ECDSA signing with seed %s after signing twice\n", (rv == SECSuccess) ? "succeeded" : "failed");
|
||||
#endif
|
||||
|
||||
SECITEM_FreeItem(signature2, PR_TRUE);
|
||||
return rv;
|
||||
#else
|
||||
return ec_SignDigestWithSeed(key, signature, digest, kb, kblen);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
** Computes the ECDSA signature on the digest using the given key
|
||||
** and a random seed.
|
||||
|
|
|
|||
|
|
@ -3,12 +3,22 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ecl-priv.h"
|
||||
#include "../verified/Hacl_Curve25519.h"
|
||||
|
||||
#if HACL_CAN_COMPILE_INLINE_ASM
|
||||
#include "../verified/Hacl_Curve25519_64.h"
|
||||
#else
|
||||
#include "../verified/Hacl_Curve25519_51.h"
|
||||
#endif
|
||||
|
||||
SECStatus
|
||||
ec_Curve25519_mul(uint8_t *mypublic, const uint8_t *secret, const uint8_t *basepoint)
|
||||
{
|
||||
// Note: this cast is safe because HaCl* state has a post-condition that only "mypublic" changed.
|
||||
Hacl_Curve25519_crypto_scalarmult(mypublic, (uint8_t *)secret, (uint8_t *)basepoint);
|
||||
// Note: this cast is safe because HaCl* state has a post-condition that only "mypublic" changed.
|
||||
#if defined HACL_CAN_COMPILE_INLINE_ASM
|
||||
Hacl_Curve25519_64_ecdh(mypublic, (uint8_t *)secret, (uint8_t *)basepoint);
|
||||
#else
|
||||
Hacl_Curve25519_51_ecdh(mypublic, (uint8_t *)secret, (uint8_t *)basepoint);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,38 +13,31 @@
|
|||
#define KU_DIGITAL_SIGNATURE (0x80) /* bit 0 */
|
||||
#define KU_KEY_AGREEMENT (0x08) /* bit 4 */
|
||||
|
||||
static const PRUint8 irr256[32] =
|
||||
{ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
static const PRUint8 a256[32] =
|
||||
{ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC };
|
||||
static const PRUint8 b256[32] =
|
||||
{ 0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55,
|
||||
0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6,
|
||||
0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B };
|
||||
static const PRUint8 x256[32] =
|
||||
{ 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5,
|
||||
0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0,
|
||||
0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96 };
|
||||
static const PRUint8 y256[32] =
|
||||
{ 0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B, 0x8E, 0xE7, 0xEB, 0x4A,
|
||||
0x7C, 0x0F, 0x9E, 0x16, 0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE,
|
||||
0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5 };
|
||||
static const PRUint8 order256[32] =
|
||||
{ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
|
||||
0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51 };
|
||||
static const PRUint8 base256[66] =
|
||||
{ 0x04, 0x00,
|
||||
0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5,
|
||||
0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0,
|
||||
0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96,
|
||||
0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B, 0x8E, 0xE7, 0xEB, 0x4A,
|
||||
0x7C, 0x0F, 0x9E, 0x16, 0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE,
|
||||
0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5 };
|
||||
static const PRUint8 irr256[32] = { 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
static const PRUint8 a256[32] = { 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC };
|
||||
static const PRUint8 b256[32] = { 0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55,
|
||||
0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6,
|
||||
0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B };
|
||||
static const PRUint8 x256[32] = { 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5,
|
||||
0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0,
|
||||
0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96 };
|
||||
static const PRUint8 y256[32] = { 0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B, 0x8E, 0xE7, 0xEB, 0x4A,
|
||||
0x7C, 0x0F, 0x9E, 0x16, 0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE,
|
||||
0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5 };
|
||||
static const PRUint8 order256[32] = { 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
|
||||
0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51 };
|
||||
static const PRUint8 base256[66] = { 0x04, 0x00,
|
||||
0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5,
|
||||
0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0,
|
||||
0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96,
|
||||
0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B, 0x8E, 0xE7, 0xEB, 0x4A,
|
||||
0x7C, 0x0F, 0x9E, 0x16, 0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE,
|
||||
0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5 };
|
||||
|
||||
static const ECCurveBytes ecCurve_NIST_P256 = {
|
||||
"NIST-P256", ECField_GFp, 256,
|
||||
|
|
@ -53,46 +46,39 @@ static const ECCurveBytes ecCurve_NIST_P256 = {
|
|||
KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT
|
||||
};
|
||||
|
||||
static const PRUint8 irr384[48] =
|
||||
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
static const PRUint8 a384[48] =
|
||||
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC };
|
||||
static const PRUint8 b384[48] =
|
||||
{ 0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B,
|
||||
0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12,
|
||||
0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D,
|
||||
0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF };
|
||||
static const PRUint8 x384[48] =
|
||||
{ 0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E,
|
||||
0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98,
|
||||
0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D,
|
||||
0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7 };
|
||||
static const PRUint8 y384[48] =
|
||||
{ 0x36, 0x17, 0xDE, 0x4A, 0x96, 0x26, 0x2C, 0x6F, 0x5D, 0x9E, 0x98, 0xBF,
|
||||
0x92, 0x92, 0xDC, 0x29, 0xF8, 0xF4, 0x1D, 0xBD, 0x28, 0x9A, 0x14, 0x7C,
|
||||
0xE9, 0xDA, 0x31, 0x13, 0xB5, 0xF0, 0xB8, 0xC0, 0x0A, 0x60, 0xB1, 0xCE,
|
||||
0x1D, 0x7E, 0x81, 0x9D, 0x7A, 0x43, 0x1D, 0x7C, 0x90, 0xEA, 0x0E, 0x5F };
|
||||
static const PRUint8 order384[48] =
|
||||
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2,
|
||||
0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73 };
|
||||
static const PRUint8 base384[98] =
|
||||
{ 0x04, 0x00,
|
||||
0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E,
|
||||
0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98,
|
||||
0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D,
|
||||
0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7,
|
||||
0x36, 0x17, 0xDE, 0x4A, 0x96, 0x26, 0x2C, 0x6F, 0x5D, 0x9E, 0x98, 0xBF,
|
||||
0x92, 0x92, 0xDC, 0x29, 0xF8, 0xF4, 0x1D, 0xBD, 0x28, 0x9A, 0x14, 0x7C,
|
||||
0xE9, 0xDA, 0x31, 0x13, 0xB5, 0xF0, 0xB8, 0xC0, 0x0A, 0x60, 0xB1, 0xCE,
|
||||
0x1D, 0x7E, 0x81, 0x9D, 0x7A, 0x43, 0x1D, 0x7C, 0x90, 0xEA, 0x0E, 0x5F };
|
||||
static const PRUint8 irr384[48] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
static const PRUint8 a384[48] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC };
|
||||
static const PRUint8 b384[48] = { 0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B,
|
||||
0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12,
|
||||
0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D,
|
||||
0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF };
|
||||
static const PRUint8 x384[48] = { 0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E,
|
||||
0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98,
|
||||
0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D,
|
||||
0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7 };
|
||||
static const PRUint8 y384[48] = { 0x36, 0x17, 0xDE, 0x4A, 0x96, 0x26, 0x2C, 0x6F, 0x5D, 0x9E, 0x98, 0xBF,
|
||||
0x92, 0x92, 0xDC, 0x29, 0xF8, 0xF4, 0x1D, 0xBD, 0x28, 0x9A, 0x14, 0x7C,
|
||||
0xE9, 0xDA, 0x31, 0x13, 0xB5, 0xF0, 0xB8, 0xC0, 0x0A, 0x60, 0xB1, 0xCE,
|
||||
0x1D, 0x7E, 0x81, 0x9D, 0x7A, 0x43, 0x1D, 0x7C, 0x90, 0xEA, 0x0E, 0x5F };
|
||||
static const PRUint8 order384[48] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2,
|
||||
0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73 };
|
||||
static const PRUint8 base384[98] = { 0x04, 0x00,
|
||||
0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E,
|
||||
0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98,
|
||||
0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D,
|
||||
0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7,
|
||||
0x36, 0x17, 0xDE, 0x4A, 0x96, 0x26, 0x2C, 0x6F, 0x5D, 0x9E, 0x98, 0xBF,
|
||||
0x92, 0x92, 0xDC, 0x29, 0xF8, 0xF4, 0x1D, 0xBD, 0x28, 0x9A, 0x14, 0x7C,
|
||||
0xE9, 0xDA, 0x31, 0x13, 0xB5, 0xF0, 0xB8, 0xC0, 0x0A, 0x60, 0xB1, 0xCE,
|
||||
0x1D, 0x7E, 0x81, 0x9D, 0x7A, 0x43, 0x1D, 0x7C, 0x90, 0xEA, 0x0E, 0x5F };
|
||||
|
||||
static const ECCurveBytes ecCurve_NIST_P384 = {
|
||||
"NIST-P384", ECField_GFp, 384,
|
||||
|
|
@ -101,64 +87,57 @@ static const ECCurveBytes ecCurve_NIST_P384 = {
|
|||
KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT
|
||||
};
|
||||
|
||||
static const PRUint8 irr521[66] =
|
||||
{ 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
static const PRUint8 a521[66] =
|
||||
{ 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC };
|
||||
static const PRUint8 b521[66] =
|
||||
{ 0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A,
|
||||
0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3,
|
||||
0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19,
|
||||
0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1,
|
||||
0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45,
|
||||
0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00 };
|
||||
static const PRUint8 x521[66] =
|
||||
{ 0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E,
|
||||
0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F,
|
||||
0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B,
|
||||
0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF,
|
||||
0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E,
|
||||
0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66 };
|
||||
static const PRUint8 y521[66] =
|
||||
{ 0x01, 0x18, 0x39, 0x29, 0x6A, 0x78, 0x9A, 0x3B, 0xC0, 0x04, 0x5C, 0x8A,
|
||||
0x5F, 0xB4, 0x2C, 0x7D, 0x1B, 0xD9, 0x98, 0xF5, 0x44, 0x49, 0x57, 0x9B,
|
||||
0x44, 0x68, 0x17, 0xAF, 0xBD, 0x17, 0x27, 0x3E, 0x66, 0x2C, 0x97, 0xEE,
|
||||
0x72, 0x99, 0x5E, 0xF4, 0x26, 0x40, 0xC5, 0x50, 0xB9, 0x01, 0x3F, 0xAD,
|
||||
0x07, 0x61, 0x35, 0x3C, 0x70, 0x86, 0xA2, 0x72, 0xC2, 0x40, 0x88, 0xBE,
|
||||
0x94, 0x76, 0x9F, 0xD1, 0x66, 0x50 };
|
||||
static const PRUint8 order521[66] =
|
||||
{ 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86,
|
||||
0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09,
|
||||
0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F,
|
||||
0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09 };
|
||||
static const PRUint8 base521[134] =
|
||||
{
|
||||
0x04, 0x00,
|
||||
0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E,
|
||||
0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F,
|
||||
0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B,
|
||||
0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF,
|
||||
0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E,
|
||||
0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66,
|
||||
0x01, 0x18, 0x39, 0x29, 0x6A, 0x78, 0x9A, 0x3B, 0xC0, 0x04, 0x5C, 0x8A,
|
||||
0x5F, 0xB4, 0x2C, 0x7D, 0x1B, 0xD9, 0x98, 0xF5, 0x44, 0x49, 0x57, 0x9B,
|
||||
0x44, 0x68, 0x17, 0xAF, 0xBD, 0x17, 0x27, 0x3E, 0x66, 0x2C, 0x97, 0xEE,
|
||||
0x72, 0x99, 0x5E, 0xF4, 0x26, 0x40, 0xC5, 0x50, 0xB9, 0x01, 0x3F, 0xAD,
|
||||
0x07, 0x61, 0x35, 0x3C, 0x70, 0x86, 0xA2, 0x72, 0xC2, 0x40, 0x88, 0xBE,
|
||||
0x94, 0x76, 0x9F, 0xD1, 0x66, 0x50
|
||||
};
|
||||
static const PRUint8 irr521[66] = { 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
static const PRUint8 a521[66] = { 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC };
|
||||
static const PRUint8 b521[66] = { 0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A,
|
||||
0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3,
|
||||
0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19,
|
||||
0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1,
|
||||
0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45,
|
||||
0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00 };
|
||||
static const PRUint8 x521[66] = { 0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E,
|
||||
0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F,
|
||||
0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B,
|
||||
0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF,
|
||||
0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E,
|
||||
0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66 };
|
||||
static const PRUint8 y521[66] = { 0x01, 0x18, 0x39, 0x29, 0x6A, 0x78, 0x9A, 0x3B, 0xC0, 0x04, 0x5C, 0x8A,
|
||||
0x5F, 0xB4, 0x2C, 0x7D, 0x1B, 0xD9, 0x98, 0xF5, 0x44, 0x49, 0x57, 0x9B,
|
||||
0x44, 0x68, 0x17, 0xAF, 0xBD, 0x17, 0x27, 0x3E, 0x66, 0x2C, 0x97, 0xEE,
|
||||
0x72, 0x99, 0x5E, 0xF4, 0x26, 0x40, 0xC5, 0x50, 0xB9, 0x01, 0x3F, 0xAD,
|
||||
0x07, 0x61, 0x35, 0x3C, 0x70, 0x86, 0xA2, 0x72, 0xC2, 0x40, 0x88, 0xBE,
|
||||
0x94, 0x76, 0x9F, 0xD1, 0x66, 0x50 };
|
||||
static const PRUint8 order521[66] = { 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86,
|
||||
0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09,
|
||||
0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F,
|
||||
0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09 };
|
||||
static const PRUint8 base521[134] = {
|
||||
0x04, 0x00,
|
||||
0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E,
|
||||
0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F,
|
||||
0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B,
|
||||
0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF,
|
||||
0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E,
|
||||
0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66,
|
||||
0x01, 0x18, 0x39, 0x29, 0x6A, 0x78, 0x9A, 0x3B, 0xC0, 0x04, 0x5C, 0x8A,
|
||||
0x5F, 0xB4, 0x2C, 0x7D, 0x1B, 0xD9, 0x98, 0xF5, 0x44, 0x49, 0x57, 0x9B,
|
||||
0x44, 0x68, 0x17, 0xAF, 0xBD, 0x17, 0x27, 0x3E, 0x66, 0x2C, 0x97, 0xEE,
|
||||
0x72, 0x99, 0x5E, 0xF4, 0x26, 0x40, 0xC5, 0x50, 0xB9, 0x01, 0x3F, 0xAD,
|
||||
0x07, 0x61, 0x35, 0x3C, 0x70, 0x86, 0xA2, 0x72, 0xC2, 0x40, 0x88, 0xBE,
|
||||
0x94, 0x76, 0x9F, 0xD1, 0x66, 0x50
|
||||
};
|
||||
|
||||
static const ECCurveBytes ecCurve_NIST_P521 = {
|
||||
"NIST-P521", ECField_GFp, 521,
|
||||
|
|
@ -167,37 +146,30 @@ static const ECCurveBytes ecCurve_NIST_P521 = {
|
|||
KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT
|
||||
};
|
||||
|
||||
static const PRUint8 irr25519[32] =
|
||||
{ 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f };
|
||||
static const PRUint8 a25519[32] =
|
||||
{ 0x06, 0x6d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
static const PRUint8 b25519[32] =
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
static const PRUint8 x25519[32] =
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09 };
|
||||
static const PRUint8 y25519[32] =
|
||||
{ 0xd9, 0xd3, 0xce, 0x7e, 0xa2, 0xc5, 0xe9, 0x29, 0xb2, 0x61, 0x7c, 0x6d,
|
||||
0x7e, 0x4d, 0x3d, 0x92, 0x4c, 0xd1, 0x48, 0x77, 0x2c, 0xdd, 0x1e, 0xe0,
|
||||
0xb4, 0x86, 0xa0, 0xb8, 0xa1, 0x19, 0xae, 0x20 };
|
||||
static const PRUint8 order25519[32] =
|
||||
{ 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2,
|
||||
0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 };
|
||||
static const PRUint8 base25519[66] =
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,
|
||||
0xd9, 0xd3, 0xce, 0x7e, 0xa2, 0xc5, 0xe9, 0x29, 0xb2, 0x61, 0x7c, 0x6d,
|
||||
0x7e, 0x4d, 0x3d, 0x92, 0x4c, 0xd1, 0x48, 0x77, 0x2c, 0xdd, 0x1e, 0xe0,
|
||||
0xb4, 0x86, 0xa0, 0xb8, 0xa1, 0x19, 0xae, 0x20, 0x00, 0x04 };
|
||||
static const PRUint8 irr25519[32] = { 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f };
|
||||
static const PRUint8 a25519[32] = { 0x06, 0x6d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
static const PRUint8 b25519[32] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
static const PRUint8 x25519[32] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09 };
|
||||
static const PRUint8 y25519[32] = { 0xd9, 0xd3, 0xce, 0x7e, 0xa2, 0xc5, 0xe9, 0x29, 0xb2, 0x61, 0x7c, 0x6d,
|
||||
0x7e, 0x4d, 0x3d, 0x92, 0x4c, 0xd1, 0x48, 0x77, 0x2c, 0xdd, 0x1e, 0xe0,
|
||||
0xb4, 0x86, 0xa0, 0xb8, 0xa1, 0x19, 0xae, 0x20 };
|
||||
static const PRUint8 order25519[32] = { 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2,
|
||||
0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 };
|
||||
static const PRUint8 base25519[66] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,
|
||||
0xd9, 0xd3, 0xce, 0x7e, 0xa2, 0xc5, 0xe9, 0x29, 0xb2, 0x61, 0x7c, 0x6d,
|
||||
0x7e, 0x4d, 0x3d, 0x92, 0x4c, 0xd1, 0x48, 0x77, 0x2c, 0xdd, 0x1e, 0xe0,
|
||||
0xb4, 0x86, 0xa0, 0xb8, 0xa1, 0x19, 0xae, 0x20, 0x00, 0x04 };
|
||||
|
||||
static const ECCurveBytes ecCurve_25519 = {
|
||||
"Curve25519", ECField_GFp, 255,
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ SECStatus
|
|||
ec_Curve25519_pt_validate(const SECItem *px)
|
||||
{
|
||||
PRUint8 *p;
|
||||
int i;
|
||||
PRUint64 i;
|
||||
PRUint8 forbiddenValues[12][32] = {
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ static const limb kPrecomputed[NLIMBS * 2 * 15 * 2] = {
|
|||
0x87d43b7, 0x37ab11b, 0x19d292ce, 0xf8d4692, 0x18c3053f, 0x8863e13, 0x4c146c0, 0x6bdf55a, 0x4e4457d,
|
||||
0x16152289, 0xac78ec2, 0x1a59c5a2, 0x2028b97, 0x71c2d01, 0x295851f, 0x404747b, 0x878558d, 0x7d29aa4,
|
||||
0x13d8341f, 0x8daefd7, 0x139c972d, 0x6b7ea75, 0xd4a9dde, 0xff163d8, 0x81d55d7, 0xa5bef68, 0xb7b30d8,
|
||||
0xbe73d6f, 0xaa88141, 0xd976c81, 0x7e7a9cc, 0x18beb771, 0xd773cbd, 0x13f51951, 0x9d0c177, 0x1c49a78,
|
||||
0xbe73d6f, 0xaa88141, 0xd976c81, 0x7e7a9cc, 0x18beb771, 0xd773cbd, 0x13f51951, 0x9d0c177, 0x1c49a78
|
||||
};
|
||||
|
||||
/* Field element operations:
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ ec_GFp_pt_mul_aff(const mp_int *n, const mp_int *px, const mp_int *py,
|
|||
}
|
||||
}
|
||||
#else /* double and add/subtract method from \
|
||||
* standard */
|
||||
* standard */
|
||||
/* k3 = 3 * k */
|
||||
MP_CHECKOK(mp_set_int(&k3, 3));
|
||||
MP_CHECKOK(mp_mul(&k, &k3, &k3));
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ ec_GFp_pt_mul_jm_wNAF(const mp_int *n, const mp_int *px, const mp_int *py,
|
|||
mp_int raz4;
|
||||
mp_int scratch[MAX_SCRATCH];
|
||||
signed char *naf = NULL;
|
||||
int i, orderBitSize;
|
||||
int i, orderBitSize = 0;
|
||||
|
||||
MP_DIGITS(&rz) = 0;
|
||||
MP_DIGITS(&raz4) = 0;
|
||||
|
|
@ -289,6 +289,9 @@ CLEANUP:
|
|||
mp_clear(&tpy);
|
||||
mp_clear(&rz);
|
||||
mp_clear(&raz4);
|
||||
if (naf) {
|
||||
memset(naf, 0, orderBitSize + 1);
|
||||
}
|
||||
free(naf);
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -17,6 +17,7 @@
|
|||
#include "prtypes.h"
|
||||
#include "secitem.h"
|
||||
#include "pkcs11t.h"
|
||||
#include "cmac.h"
|
||||
|
||||
#include "ec.h" /* Required for EC */
|
||||
|
||||
|
|
@ -45,7 +46,8 @@ static void INIT_FUNCTION bl_startup_tests(void);
|
|||
#if defined(XP_WIN) && !defined(NSS_NO_INIT_SUPPORT)
|
||||
#include <windows.h>
|
||||
|
||||
BOOL WINAPI DllMain(
|
||||
BOOL WINAPI
|
||||
DllMain(
|
||||
HINSTANCE hinstDLL, // handle to DLL module
|
||||
DWORD fdwReason, // reason for calling function
|
||||
LPVOID lpReserved) // reserved
|
||||
|
|
@ -99,6 +101,7 @@ BOOL WINAPI DllMain(
|
|||
#define FIPS_AES_BLOCK_SIZE 16 /* 128-bits */
|
||||
#define FIPS_AES_ENCRYPT_LENGTH 16 /* 128-bits */
|
||||
#define FIPS_AES_DECRYPT_LENGTH 16 /* 128-bits */
|
||||
#define FIPS_AES_CMAC_LENGTH 16 /* 128-bits */
|
||||
#define FIPS_AES_128_KEY_SIZE 16 /* 128-bits */
|
||||
#define FIPS_AES_192_KEY_SIZE 24 /* 192-bits */
|
||||
#define FIPS_AES_256_KEY_SIZE 32 /* 256-bits */
|
||||
|
|
@ -280,12 +283,10 @@ static SECStatus
|
|||
freebl_fips_AES_PowerUpSelfTest(int aes_key_size)
|
||||
{
|
||||
/* AES Known Key (up to 256-bits). */
|
||||
static const PRUint8 aes_known_key[] =
|
||||
{ "AES-128 RIJNDAELLEADNJIR 821-SEA" };
|
||||
static const PRUint8 aes_known_key[] = { "AES-128 RIJNDAELLEADNJIR 821-SEA" };
|
||||
|
||||
/* AES-CBC Known Initialization Vector (128-bits). */
|
||||
static const PRUint8 aes_cbc_known_initialization_vector[] =
|
||||
{ "SecurityytiruceS" };
|
||||
static const PRUint8 aes_cbc_known_initialization_vector[] = { "SecurityytiruceS" };
|
||||
|
||||
/* AES Known Plaintext (128-bits). (blocksize is 128-bits) */
|
||||
static const PRUint8 aes_known_plaintext[] = { "NetscapeepacsteN" };
|
||||
|
|
@ -310,6 +311,11 @@ freebl_fips_AES_PowerUpSelfTest(int aes_key_size)
|
|||
0x8b, 0xde, 0xbf, 0x16, 0x5e, 0x57, 0x6b, 0x4f
|
||||
};
|
||||
|
||||
static const PRUint8 aes_cmac128_known_ciphertext[] = {
|
||||
0x54, 0x11, 0xe2, 0x57, 0xbd, 0x2a, 0xdf, 0x9d,
|
||||
0x1a, 0x89, 0x72, 0x80, 0x84, 0x4c, 0x7e, 0x93
|
||||
};
|
||||
|
||||
/* AES Known Ciphertext (192-bit key). */
|
||||
static const PRUint8 aes_ecb192_known_ciphertext[] = {
|
||||
0xa0, 0x18, 0x62, 0xed, 0x88, 0x19, 0xcb, 0x62,
|
||||
|
|
@ -328,6 +334,11 @@ freebl_fips_AES_PowerUpSelfTest(int aes_key_size)
|
|||
0x90, 0x2e, 0x44, 0xbb, 0x52, 0x03, 0xe9, 0x07
|
||||
};
|
||||
|
||||
static const PRUint8 aes_cmac192_known_ciphertext[] = {
|
||||
0x0e, 0x07, 0x99, 0x1e, 0xf6, 0xee, 0xfa, 0x2c,
|
||||
0x1b, 0xfc, 0xce, 0x94, 0x92, 0x2d, 0xf1, 0xab
|
||||
};
|
||||
|
||||
/* AES Known Ciphertext (256-bit key). */
|
||||
static const PRUint8 aes_ecb256_known_ciphertext[] = {
|
||||
0xdb, 0xa6, 0x52, 0x01, 0x8a, 0x70, 0xae, 0x66,
|
||||
|
|
@ -346,6 +357,12 @@ freebl_fips_AES_PowerUpSelfTest(int aes_key_size)
|
|||
0xf4, 0xb0, 0xc1, 0x8c, 0x86, 0x51, 0xf5, 0xa1
|
||||
};
|
||||
|
||||
static const PRUint8 aes_cmac256_known_ciphertext[] = {
|
||||
0xc1, 0x26, 0x69, 0x32, 0x51, 0x13, 0x65, 0xac,
|
||||
0x71, 0x23, 0xe4, 0xe7, 0xb9, 0x0c, 0x88, 0x9f
|
||||
|
||||
};
|
||||
|
||||
const PRUint8 *aes_ecb_known_ciphertext =
|
||||
(aes_key_size == FIPS_AES_128_KEY_SIZE) ? aes_ecb128_known_ciphertext : (aes_key_size == FIPS_AES_192_KEY_SIZE) ? aes_ecb192_known_ciphertext : aes_ecb256_known_ciphertext;
|
||||
|
||||
|
|
@ -355,13 +372,17 @@ freebl_fips_AES_PowerUpSelfTest(int aes_key_size)
|
|||
const PRUint8 *aes_gcm_known_ciphertext =
|
||||
(aes_key_size == FIPS_AES_128_KEY_SIZE) ? aes_gcm128_known_ciphertext : (aes_key_size == FIPS_AES_192_KEY_SIZE) ? aes_gcm192_known_ciphertext : aes_gcm256_known_ciphertext;
|
||||
|
||||
const PRUint8 *aes_cmac_known_ciphertext =
|
||||
(aes_key_size == FIPS_AES_128_KEY_SIZE) ? aes_cmac128_known_ciphertext : (aes_key_size == FIPS_AES_192_KEY_SIZE) ? aes_cmac192_known_ciphertext : aes_cmac256_known_ciphertext;
|
||||
|
||||
/* AES variables. */
|
||||
PRUint8 aes_computed_ciphertext[FIPS_AES_ENCRYPT_LENGTH * 2];
|
||||
PRUint8 aes_computed_plaintext[FIPS_AES_DECRYPT_LENGTH * 2];
|
||||
AESContext *aes_context;
|
||||
CMACContext *cmac_context;
|
||||
unsigned int aes_bytes_encrypted;
|
||||
unsigned int aes_bytes_decrypted;
|
||||
CK_GCM_PARAMS gcmParams;
|
||||
CK_NSS_GCM_PARAMS gcmParams;
|
||||
SECStatus aes_status;
|
||||
|
||||
/*check if aes_key_size is 128, 192, or 256 bits */
|
||||
|
|
@ -547,6 +568,44 @@ freebl_fips_AES_PowerUpSelfTest(int aes_key_size)
|
|||
return (SECFailure);
|
||||
}
|
||||
|
||||
/******************************************************/
|
||||
/* AES-CMAC Known Answer Encryption Test. */
|
||||
/******************************************************/
|
||||
cmac_context = CMAC_Create(CMAC_AES, aes_known_key, aes_key_size);
|
||||
|
||||
if (cmac_context == NULL) {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
return (SECFailure);
|
||||
}
|
||||
|
||||
aes_status = CMAC_Begin(cmac_context);
|
||||
if (aes_status != SECSuccess) {
|
||||
CMAC_Destroy(cmac_context, PR_TRUE);
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return (SECFailure);
|
||||
}
|
||||
|
||||
aes_status = CMAC_Update(cmac_context, aes_known_plaintext,
|
||||
FIPS_AES_DECRYPT_LENGTH);
|
||||
if (aes_status != SECSuccess) {
|
||||
CMAC_Destroy(cmac_context, PR_TRUE);
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return (SECFailure);
|
||||
}
|
||||
|
||||
aes_status = CMAC_Finish(cmac_context, aes_computed_ciphertext,
|
||||
&aes_bytes_encrypted, FIPS_AES_CMAC_LENGTH);
|
||||
|
||||
CMAC_Destroy(cmac_context, PR_TRUE);
|
||||
|
||||
if ((aes_status != SECSuccess) ||
|
||||
(aes_bytes_encrypted != FIPS_AES_CMAC_LENGTH) ||
|
||||
(PORT_Memcmp(aes_computed_ciphertext, aes_cmac_known_ciphertext,
|
||||
FIPS_AES_CMAC_LENGTH) != 0)) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return (SECFailure);
|
||||
}
|
||||
|
||||
return (SECSuccess);
|
||||
}
|
||||
|
||||
|
|
@ -743,6 +802,170 @@ freebl_fips_HMAC_PowerUpSelfTest(void)
|
|||
return (SECSuccess);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
freebl_fips_TLS_PowerUpSelfTest(void)
|
||||
{
|
||||
static const PRUint8 TLS_known_secret_key[] = {
|
||||
"Firefox and ThunderBird are awesome!"
|
||||
};
|
||||
|
||||
static const PRUint8 TLS_known_secret_key_length = sizeof TLS_known_secret_key;
|
||||
|
||||
/* known tls prf with sha1/md5 */
|
||||
static const PRUint8 known_TLS_PRF[] = {
|
||||
0x87, 0x4c, 0xc0, 0xc5, 0x15, 0x14, 0x2b, 0xdc,
|
||||
0x73, 0x48, 0x9e, 0x88, 0x9d, 0xf5, 0x83, 0x2f,
|
||||
0x2d, 0x66, 0x1e, 0x78, 0x6c, 0x54, 0x78, 0x29,
|
||||
0xb9, 0xa4, 0x4c, 0x90, 0x5e, 0xa2, 0xe6, 0x5c,
|
||||
0xf1, 0x4f, 0xb5, 0x95, 0xa5, 0x54, 0xc0, 0x9f,
|
||||
0x84, 0x47, 0xb4, 0x4c, 0xda, 0xae, 0x19, 0x29,
|
||||
0x2b, 0x91, 0x2a, 0x81, 0x9d, 0x3a, 0x30, 0x40,
|
||||
0xc5, 0xdf, 0xbb, 0xfa, 0xd8, 0x4c, 0xbc, 0x18
|
||||
};
|
||||
|
||||
/* known SHA256 tls mac */
|
||||
static const PRUint8 known_TLS_SHA256[] = {
|
||||
0x66, 0xd6, 0x94, 0xd4, 0x0d, 0x32, 0x61, 0x38,
|
||||
0x26, 0xf6, 0x8b, 0xfe, 0x9e, 0xac, 0xa2, 0xf5,
|
||||
0x40, 0x52, 0x74, 0x3f, 0xbe, 0xb8, 0xca, 0x94,
|
||||
0xc3, 0x64, 0xd6, 0x02, 0xf5, 0x88, 0x98, 0x35,
|
||||
0x73, 0x9f, 0xce, 0xaa, 0x68, 0xe3, 0x7c, 0x93,
|
||||
0x30, 0x21, 0x45, 0xec, 0xe9, 0x8f, 0x1c, 0x7e,
|
||||
0xd1, 0x54, 0xf5, 0xbe, 0xff, 0xc8, 0xd7, 0x72,
|
||||
0x7f, 0x9c, 0x0c, 0x7f, 0xa9, 0xd3, 0x4a, 0xd2
|
||||
};
|
||||
|
||||
#ifdef NSS_FULL_POST
|
||||
/* known SHA224 tls mac */
|
||||
static const PRUint8 known_TLS_SHA224[] = {
|
||||
0xd8, 0x68, 0x15, 0xff, 0xa1, 0xa2, 0x5e, 0x16,
|
||||
0xce, 0xb1, 0xfd, 0xbd, 0xda, 0x39, 0xbc, 0xa7,
|
||||
0x27, 0x32, 0x78, 0x94, 0x66, 0xf0, 0x84, 0xcf,
|
||||
0x46, 0xc0, 0x22, 0x76, 0xdc, 0x6b, 0x2e, 0xed,
|
||||
0x1d, 0x2d, 0xd2, 0x93, 0xfd, 0xae, 0xca, 0xf9,
|
||||
0xe0, 0x4c, 0x17, 0x23, 0x22, 0x5a, 0x73, 0x93,
|
||||
0x20, 0x0a, 0xbd, 0xa0, 0x72, 0xf8, 0x8b, 0x74,
|
||||
0xfb, 0xf1, 0xab, 0xb7, 0xe0, 0xec, 0x34, 0xc9
|
||||
};
|
||||
|
||||
/* known SHA384 tls mac */
|
||||
static const PRUint8 known_TLS_SHA384[] = {
|
||||
0xb2, 0xac, 0x06, 0x10, 0xad, 0x50, 0xd5, 0xdc,
|
||||
0xdb, 0x01, 0xea, 0xa6, 0x2d, 0x8a, 0x34, 0xb6,
|
||||
0xeb, 0x84, 0xbc, 0x37, 0xc9, 0x9f, 0xa1, 0x9c,
|
||||
0xd5, 0xbd, 0x4e, 0x66, 0x16, 0x24, 0xe5, 0x3d,
|
||||
0xce, 0x74, 0xe0, 0x30, 0x41, 0x5c, 0xdb, 0xb7,
|
||||
0x52, 0x1d, 0x2d, 0x4d, 0x9b, 0xbe, 0x6b, 0x86,
|
||||
0xda, 0x8a, 0xca, 0x73, 0x39, 0xb4, 0xc7, 0x8f,
|
||||
0x03, 0xb1, 0xf9, 0x7e, 0x65, 0xae, 0x17, 0x10
|
||||
};
|
||||
|
||||
/* known SHA512 tls mac */
|
||||
static const PRUint8 known_TLS_SHA512[] = {
|
||||
0x73, 0x21, 0x4f, 0x40, 0x81, 0x1e, 0x90, 0xa1,
|
||||
0x16, 0x40, 0x1e, 0x33, 0x69, 0xc5, 0x00, 0xc7,
|
||||
0xc4, 0x81, 0xa3, 0x4f, 0xa7, 0xcc, 0x4a, 0xeb,
|
||||
0x1a, 0x66, 0x00, 0x82, 0x52, 0xe2, 0x2f, 0x69,
|
||||
0x14, 0x59, 0x05, 0x7c, 0xb0, 0x32, 0xce, 0xcc,
|
||||
0xb7, 0xc9, 0xab, 0x0f, 0x73, 0x00, 0xe5, 0x52,
|
||||
0x9d, 0x6b, 0x0e, 0x66, 0x4b, 0xb3, 0x0b, 0x0d,
|
||||
0x34, 0x53, 0x97, 0x13, 0x84, 0x18, 0x31, 0x7a
|
||||
};
|
||||
#endif
|
||||
|
||||
SECStatus status;
|
||||
PRUint8 tls_computed[HASH_LENGTH_MAX];
|
||||
SECItem secret;
|
||||
SECItem seed;
|
||||
SECItem result;
|
||||
const char *tls_label = "fips test label";
|
||||
|
||||
secret.data = (unsigned char *)TLS_known_secret_key;
|
||||
secret.len = TLS_known_secret_key_length;
|
||||
seed.data = (unsigned char *)known_hash_message;
|
||||
seed.len = FIPS_KNOWN_HASH_MESSAGE_LENGTH;
|
||||
result.data = tls_computed;
|
||||
result.len = sizeof(tls_computed);
|
||||
|
||||
/***************************************************/
|
||||
/* TLS 1.0 PRF Known Answer Test */
|
||||
/***************************************************/
|
||||
|
||||
status = TLS_PRF(&secret, tls_label, &seed, &result, PR_TRUE);
|
||||
|
||||
if ((status != SECSuccess) ||
|
||||
(result.len != HASH_LENGTH_MAX) ||
|
||||
(PORT_Memcmp(tls_computed, known_TLS_PRF,
|
||||
HASH_LENGTH_MAX) != 0)) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return (SECFailure);
|
||||
}
|
||||
|
||||
/***************************************************/
|
||||
/* TLS 1.2 SHA-256 Known Answer Test. */
|
||||
/***************************************************/
|
||||
|
||||
status = TLS_P_hash(HASH_AlgSHA256, &secret, tls_label,
|
||||
&seed, &result, PR_TRUE);
|
||||
|
||||
if ((status != SECSuccess) ||
|
||||
(result.len != HASH_LENGTH_MAX) ||
|
||||
(PORT_Memcmp(tls_computed, known_TLS_SHA256,
|
||||
HASH_LENGTH_MAX) != 0)) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return (SECFailure);
|
||||
}
|
||||
|
||||
#ifdef NSS_FULL_POST
|
||||
/***************************************************/
|
||||
/* TLS 1.2 SHA-224 Known Answer Test. */
|
||||
/***************************************************/
|
||||
|
||||
status = TLS_P_hash(HASH_AlgSHA224, &secret, tls_label,
|
||||
&seed, &result, PR_TRUE);
|
||||
|
||||
if ((status != SECSuccess) ||
|
||||
(result.len != HASH_LENGTH_MAX) ||
|
||||
(PORT_Memcmp(tls_computed, known_TLS_SHA224,
|
||||
HASH_LENGTH_MAX) != 0)) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return (SECFailure);
|
||||
}
|
||||
|
||||
/***************************************************/
|
||||
/* TLS 1.2 SHA-384 Known Answer Test. */
|
||||
/***************************************************/
|
||||
|
||||
status = TLS_P_hash(HASH_AlgSHA384, &secret, tls_label,
|
||||
&seed, &result, PR_TRUE);
|
||||
|
||||
if ((status != SECSuccess) ||
|
||||
(result.len != HASH_LENGTH_MAX) ||
|
||||
(PORT_Memcmp(tls_computed, known_TLS_SHA384,
|
||||
HASH_LENGTH_MAX) != 0)) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return (SECFailure);
|
||||
}
|
||||
|
||||
/***************************************************/
|
||||
/* TLS 1.2 SHA-512 Known Answer Test. */
|
||||
/***************************************************/
|
||||
|
||||
status = TLS_P_hash(HASH_AlgSHA512, &secret, tls_label,
|
||||
&seed, &result, PR_TRUE);
|
||||
|
||||
if ((status != SECSuccess) ||
|
||||
(result.len != HASH_LENGTH_MAX) ||
|
||||
(PORT_Memcmp(tls_computed, known_TLS_SHA512,
|
||||
HASH_LENGTH_MAX) != 0)) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return (SECFailure);
|
||||
}
|
||||
#endif
|
||||
|
||||
return (SECSuccess);
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
freebl_fips_SHA_PowerUpSelfTest(void)
|
||||
{
|
||||
|
|
@ -1300,7 +1523,7 @@ freebl_fips_ECDH_Test(ECParams *ecparams)
|
|||
0x16, 0xf3, 0x85, 0xa2, 0x41, 0xf3, 0x7f, 0xc4,
|
||||
0x0b, 0x56, 0x47, 0xee, 0xa7, 0x74, 0xb9, 0xdb,
|
||||
0xe1, 0xfa, 0x22, 0xe9, 0x04, 0xf1, 0xb6, 0x12,
|
||||
0x4b, 0x44, 0x8a, 0xbb, 0xbc, 0x08, 0x2b, 0xa7,
|
||||
0x4b, 0x44, 0x8a, 0xbb, 0xbc, 0x08, 0x2b, 0xa7
|
||||
};
|
||||
|
||||
SECItem ecdh_priv_2, ecdh_pub_1;
|
||||
|
|
@ -1383,7 +1606,8 @@ freebl_fips_EC_PowerUpSelfTest()
|
|||
0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07
|
||||
};
|
||||
static const ECParams ec_known_P256_Params = {
|
||||
NULL, ec_params_named, /* arena, type */
|
||||
NULL,
|
||||
ec_params_named, /* arena, type */
|
||||
/* fieldID */
|
||||
{ 256, ec_field_GFp, /* size and type */
|
||||
{ { siBuffer, (unsigned char *)p256_prime, sizeof(p256_prime) } }, /* u.prime */
|
||||
|
|
@ -1418,7 +1642,7 @@ freebl_fips_EC_PowerUpSelfTest()
|
|||
0xa7, 0xd2, 0x20, 0xdd, 0x45, 0xf9, 0x2b, 0xdd,
|
||||
0xda, 0x98, 0x99, 0x5b, 0x1c, 0x02, 0x3a, 0x27,
|
||||
0x8b, 0x7d, 0xb6, 0xed, 0x0e, 0xe0, 0xa7, 0xac,
|
||||
0xaa, 0x36, 0x2c, 0xfa, 0x1a, 0xdf, 0x0d, 0xe1,
|
||||
0xaa, 0x36, 0x2c, 0xfa, 0x1a, 0xdf, 0x0d, 0xe1
|
||||
};
|
||||
|
||||
ECParams ecparams;
|
||||
|
|
@ -1797,12 +2021,6 @@ freebl_fipsPowerUpSelfTest(unsigned int tests)
|
|||
/* SHA-X Power-Up SelfTest(s). */
|
||||
rv = freebl_fips_SHA_PowerUpSelfTest();
|
||||
|
||||
if (rv != SECSuccess)
|
||||
return rv;
|
||||
|
||||
/* RNG Power-Up SelfTest(s). */
|
||||
rv = freebl_fips_RNG_PowerUpSelfTest();
|
||||
|
||||
if (rv != SECSuccess)
|
||||
return rv;
|
||||
}
|
||||
|
|
@ -1812,6 +2030,12 @@ freebl_fipsPowerUpSelfTest(unsigned int tests)
|
|||
* standalone */
|
||||
if (tests & DO_REST) {
|
||||
|
||||
/* RNG Power-Up SelfTest(s). */
|
||||
rv = freebl_fips_RNG_PowerUpSelfTest();
|
||||
|
||||
if (rv != SECSuccess)
|
||||
return rv;
|
||||
|
||||
/* DES3 Power-Up SelfTest(s). */
|
||||
rv = freebl_fips_DES3_PowerUpSelfTest();
|
||||
|
||||
|
|
@ -1839,6 +2063,12 @@ freebl_fipsPowerUpSelfTest(unsigned int tests)
|
|||
/* HMAC SHA-X Power-Up SelfTest(s). */
|
||||
rv = freebl_fips_HMAC_PowerUpSelfTest();
|
||||
|
||||
if (rv != SECSuccess)
|
||||
return rv;
|
||||
|
||||
/* TLS PRF Power-Up SelfTest(s). */
|
||||
rv = freebl_fips_TLS_PowerUpSelfTest();
|
||||
|
||||
if (rv != SECSuccess)
|
||||
return rv;
|
||||
|
||||
|
|
@ -1986,7 +2216,7 @@ bl_startup_tests(void)
|
|||
* power on selftest failed.
|
||||
*/
|
||||
SECStatus
|
||||
BL_FIPSEntryOK(PRBool freebl_only)
|
||||
BL_FIPSEntryOK(PRBool freebl_only, PRBool rerun)
|
||||
{
|
||||
#ifdef NSS_NO_INIT_SUPPORT
|
||||
/* this should only be set on platforms that can't handle one of the INIT
|
||||
|
|
@ -1999,6 +2229,14 @@ BL_FIPSEntryOK(PRBool freebl_only)
|
|||
bl_startup_tests();
|
||||
}
|
||||
#endif
|
||||
if (rerun) {
|
||||
/* reset the flags */
|
||||
self_tests_freebl_ran = PR_FALSE;
|
||||
self_tests_success = PR_FALSE;
|
||||
self_tests_success = PR_FALSE;
|
||||
self_tests_freebl_success = PR_FALSE;
|
||||
bl_startup_tests();
|
||||
}
|
||||
/* if the general self tests succeeded, we're done */
|
||||
if (self_tests_success) {
|
||||
return SECSuccess;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
'<(DEPTH)/exports.gyp:nss_exports'
|
||||
],
|
||||
'conditions': [
|
||||
[ 'cc_is_clang==1', {
|
||||
[ 'cc_is_clang==1 and force_integrated_as!=1', {
|
||||
'cflags': [
|
||||
'-no-integrated-as',
|
||||
],
|
||||
|
|
@ -54,28 +54,55 @@
|
|||
],
|
||||
},
|
||||
{
|
||||
# TODO: make this so that all hardware accelerated code is in here.
|
||||
'target_name': 'hw-acc-crypto',
|
||||
'target_name': 'hw-acc-crypto-avx',
|
||||
'type': 'static_library',
|
||||
'sources': [
|
||||
'verified/Hacl_Chacha20_Vec128.c',
|
||||
],
|
||||
# 'sources': [
|
||||
# All AVX hardware accelerated crypto currently requires x64
|
||||
# ],
|
||||
'dependencies': [
|
||||
'<(DEPTH)/exports.gyp:nss_exports'
|
||||
],
|
||||
'conditions': [
|
||||
[ 'target_arch=="ia32" or target_arch=="x64"', {
|
||||
[ 'target_arch=="x64"', {
|
||||
'cflags': [
|
||||
'-mssse3'
|
||||
'-mssse3',
|
||||
'-msse4.1',
|
||||
'-msse4.2'
|
||||
],
|
||||
'cflags_mozilla': [
|
||||
'-mssse3'
|
||||
'-mssse3',
|
||||
'-msse4.1',
|
||||
'-msse4.2',
|
||||
'-mpclmul',
|
||||
'-maes',
|
||||
'-mavx',
|
||||
],
|
||||
# GCC doesn't define this.
|
||||
'defines': [
|
||||
'__SSSE3__',
|
||||
],
|
||||
}],
|
||||
[ 'OS=="linux" or OS=="android" or OS=="dragonfly" or OS=="freebsd" or \
|
||||
OS=="netbsd" or OS=="openbsd"', {
|
||||
'cflags': [
|
||||
'-mpclmul',
|
||||
'-maes',
|
||||
'-mavx',
|
||||
],
|
||||
}],
|
||||
# macOS build doesn't use cflags.
|
||||
[ 'OS=="mac" or OS=="ios"', {
|
||||
'xcode_settings': {
|
||||
'OTHER_CFLAGS': [
|
||||
'-mssse3',
|
||||
'-msse4.1',
|
||||
'-msse4.2',
|
||||
'-mpclmul',
|
||||
'-maes',
|
||||
'-mavx',
|
||||
],
|
||||
},
|
||||
}],
|
||||
[ 'target_arch=="arm"', {
|
||||
# Gecko doesn't support non-NEON platform on Android, but tier-3
|
||||
# platform such as Linux/arm will need it
|
||||
|
|
@ -83,6 +110,82 @@
|
|||
'-mfpu=neon'
|
||||
],
|
||||
}],
|
||||
[ 'target_arch=="x64"', {
|
||||
'sources': [
|
||||
'verified/Hacl_Poly1305_128.c',
|
||||
'verified/Hacl_Chacha20_Vec128.c',
|
||||
'verified/Hacl_Chacha20Poly1305_128.c',
|
||||
],
|
||||
}],
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'hw-acc-crypto-avx2',
|
||||
'type': 'static_library',
|
||||
# 'sources': [
|
||||
# All AVX2 hardware accelerated crypto currently requires x64
|
||||
# ],
|
||||
'dependencies': [
|
||||
'<(DEPTH)/exports.gyp:nss_exports'
|
||||
],
|
||||
'conditions': [
|
||||
[ 'target_arch=="x64"', {
|
||||
'cflags': [
|
||||
'-mssse3',
|
||||
'-msse4.1',
|
||||
'-msse4.2'
|
||||
],
|
||||
'cflags_mozilla': [
|
||||
'-mssse3',
|
||||
'-msse4.1',
|
||||
'-msse4.2',
|
||||
'-mpclmul',
|
||||
'-maes',
|
||||
'-mavx',
|
||||
'-mavx2',
|
||||
],
|
||||
# GCC doesn't define this.
|
||||
'defines': [
|
||||
'__SSSE3__',
|
||||
],
|
||||
}],
|
||||
[ 'OS=="linux" or OS=="android" or OS=="dragonfly" or OS=="freebsd" or \
|
||||
OS=="netbsd" or OS=="openbsd"', {
|
||||
'cflags': [
|
||||
'-mpclmul',
|
||||
'-maes',
|
||||
'-mavx',
|
||||
'-mavx2',
|
||||
],
|
||||
}],
|
||||
# macOS build doesn't use cflags.
|
||||
[ 'OS=="mac" or OS=="ios"', {
|
||||
'xcode_settings': {
|
||||
'OTHER_CFLAGS': [
|
||||
'-mssse3',
|
||||
'-msse4.1',
|
||||
'-msse4.2',
|
||||
'-mpclmul',
|
||||
'-maes',
|
||||
'-mavx',
|
||||
'-mavx2',
|
||||
],
|
||||
},
|
||||
}],
|
||||
[ 'target_arch=="arm"', {
|
||||
# Gecko doesn't support non-NEON platform on Android, but tier-3
|
||||
# platform such as Linux/arm will need it
|
||||
'cflags_mozilla': [
|
||||
'-mfpu=neon'
|
||||
],
|
||||
}],
|
||||
[ 'target_arch=="x64"', {
|
||||
'sources': [
|
||||
'verified/Hacl_Poly1305_256.c',
|
||||
'verified/Hacl_Chacha20_Vec256.c',
|
||||
'verified/Hacl_Chacha20Poly1305_256.c',
|
||||
],
|
||||
}],
|
||||
],
|
||||
},
|
||||
{
|
||||
|
|
@ -116,6 +219,57 @@
|
|||
}]
|
||||
]
|
||||
},
|
||||
{
|
||||
'target_name': 'sha-x86_c_lib',
|
||||
'type': 'static_library',
|
||||
'sources': [
|
||||
'sha256-x86.c'
|
||||
],
|
||||
'dependencies': [
|
||||
'<(DEPTH)/exports.gyp:nss_exports'
|
||||
],
|
||||
'cflags': [
|
||||
'-msha',
|
||||
'-mssse3',
|
||||
'-msse4.1'
|
||||
],
|
||||
'cflags_mozilla': [
|
||||
'-msha',
|
||||
'-mssse3',
|
||||
'-msse4.1'
|
||||
],
|
||||
'conditions': [
|
||||
# macOS build doesn't use cflags.
|
||||
[ 'OS=="mac" or OS=="ios"', {
|
||||
'xcode_settings': {
|
||||
'OTHER_CFLAGS': [
|
||||
'-msha',
|
||||
'-mssse3',
|
||||
'-msse4.1'
|
||||
],
|
||||
},
|
||||
}]
|
||||
]
|
||||
},
|
||||
{
|
||||
'target_name': 'gcm-aes-arm32-neon_c_lib',
|
||||
'type': 'static_library',
|
||||
'sources': [
|
||||
'gcm-arm32-neon.c'
|
||||
],
|
||||
'dependencies': [
|
||||
'<(DEPTH)/exports.gyp:nss_exports'
|
||||
],
|
||||
'cflags': [
|
||||
'-march=armv7',
|
||||
'-mfpu=neon',
|
||||
'<@(softfp_cflags)',
|
||||
],
|
||||
'cflags_mozilla': [
|
||||
'-mfpu=neon',
|
||||
'<@(softfp_cflags)',
|
||||
]
|
||||
},
|
||||
{
|
||||
'target_name': 'gcm-aes-aarch64_c_lib',
|
||||
'type': 'static_library',
|
||||
|
|
@ -136,18 +290,167 @@
|
|||
'target_name': 'gcm-aes-ppc_c_lib',
|
||||
'type': 'static_library',
|
||||
'sources': [
|
||||
'gcm-ppc.c'
|
||||
'gcm-ppc.c',
|
||||
'sha512-p8.s',
|
||||
],
|
||||
'dependencies': [
|
||||
'<(DEPTH)/exports.gyp:nss_exports'
|
||||
],
|
||||
'cflags': [
|
||||
'-mcrypto',
|
||||
'-maltivec'
|
||||
'conditions': [
|
||||
[ 'disable_crypto_vsx==0', {
|
||||
'cflags': [
|
||||
'-mcrypto',
|
||||
'-maltivec'
|
||||
],
|
||||
'cflags_mozilla': [
|
||||
'-mcrypto',
|
||||
'-maltivec'
|
||||
],
|
||||
}, 'disable_crypto_vsx==1', {
|
||||
'cflags': [
|
||||
'-maltivec'
|
||||
],
|
||||
'cflags_mozilla': [
|
||||
'-maltivec'
|
||||
],
|
||||
}]
|
||||
]
|
||||
},
|
||||
{
|
||||
'target_name': 'gcm-aes-ppc_lib',
|
||||
'type': 'static_library',
|
||||
'sources': [
|
||||
'ppc-gcm.s',
|
||||
],
|
||||
'cflags_mozilla': [
|
||||
'-mcrypto',
|
||||
'-maltivec'
|
||||
'dependencies': [
|
||||
'<(DEPTH)/exports.gyp:nss_exports'
|
||||
],
|
||||
'conditions': [
|
||||
[ 'cc_is_clang==1 and force_integrated_as!=1', {
|
||||
'cflags': [
|
||||
'-no-integrated-as',
|
||||
],
|
||||
'cflags_mozilla': [
|
||||
'-no-integrated-as',
|
||||
],
|
||||
'asflags_mozilla': [
|
||||
'-no-integrated-as',
|
||||
],
|
||||
}],
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'ppc-gcm-wrap-nodepend_c_lib',
|
||||
'type': 'static_library',
|
||||
'sources': [
|
||||
'ppc-gcm-wrap.c',
|
||||
],
|
||||
'dependencies': [
|
||||
'<(DEPTH)/exports.gyp:nss_exports',
|
||||
'gcm-aes-ppc_lib',
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'ppc-gcm-wrap_c_lib',
|
||||
'type': 'static_library',
|
||||
'sources': [
|
||||
'ppc-gcm-wrap.c',
|
||||
],
|
||||
'dependencies': [
|
||||
'<(DEPTH)/exports.gyp:nss_exports',
|
||||
'gcm-aes-ppc_lib',
|
||||
],
|
||||
'defines!': [
|
||||
'FREEBL_NO_DEPEND',
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'gcm-sha512-nodepend-ppc_c_lib',
|
||||
'type': 'static_library',
|
||||
'sources': [
|
||||
'sha512.c',
|
||||
],
|
||||
'dependencies': [
|
||||
'<(DEPTH)/exports.gyp:nss_exports'
|
||||
],
|
||||
'conditions': [
|
||||
[ 'disable_crypto_vsx==0', {
|
||||
'cflags': [
|
||||
'-mcrypto',
|
||||
'-maltivec',
|
||||
'-mvsx',
|
||||
'-funroll-loops',
|
||||
'-fpeel-loops'
|
||||
],
|
||||
'cflags_mozilla': [
|
||||
'-mcrypto',
|
||||
'-maltivec',
|
||||
'-mvsx',
|
||||
'-funroll-loops',
|
||||
'-fpeel-loops'
|
||||
],
|
||||
}, 'disable_crypto_vsx==1', {
|
||||
'cflags': [
|
||||
'-maltivec',
|
||||
'-funroll-loops',
|
||||
'-fpeel-loops'
|
||||
],
|
||||
'cflags_mozilla': [
|
||||
'-maltivec',
|
||||
'-funroll-loops',
|
||||
'-fpeel-loops'
|
||||
],
|
||||
}]
|
||||
]
|
||||
},
|
||||
{
|
||||
'target_name': 'gcm-sha512-ppc_c_lib',
|
||||
'type': 'static_library',
|
||||
'sources': [
|
||||
'sha512.c',
|
||||
],
|
||||
'dependencies': [
|
||||
'<(DEPTH)/exports.gyp:nss_exports'
|
||||
],
|
||||
'conditions': [
|
||||
[ 'disable_crypto_vsx==0', {
|
||||
'cflags': [
|
||||
'-mcrypto',
|
||||
'-maltivec',
|
||||
'-mvsx',
|
||||
'-funroll-loops',
|
||||
'-fpeel-loops'
|
||||
],
|
||||
'cflags_mozilla': [
|
||||
'-mcrypto',
|
||||
'-maltivec',
|
||||
'-mvsx',
|
||||
'-funroll-loops',
|
||||
'-fpeel-loops'
|
||||
],
|
||||
}, 'disable_crypto_vsx==1', {
|
||||
'cflags': [
|
||||
'-maltivec',
|
||||
'-funroll-loops',
|
||||
'-fpeel-loops'
|
||||
],
|
||||
'cflags_mozilla': [
|
||||
'-maltivec',
|
||||
'-funroll-loops',
|
||||
'-fpeel-loops'
|
||||
],
|
||||
}]
|
||||
],
|
||||
'defines!': [
|
||||
'FREEBL_NO_DEPEND',
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'chacha20-ppc_lib',
|
||||
'type': 'static_library',
|
||||
'sources': [
|
||||
'chacha20poly1305-ppc.c',
|
||||
'chacha20-ppc64le.S',
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -155,6 +458,8 @@
|
|||
'type': 'static_library',
|
||||
'sources': [
|
||||
'aes-armv8.c',
|
||||
'sha1-armv8.c',
|
||||
'sha256-armv8.c',
|
||||
],
|
||||
'dependencies': [
|
||||
'<(DEPTH)/exports.gyp:nss_exports'
|
||||
|
|
@ -163,11 +468,13 @@
|
|||
[ 'target_arch=="arm"', {
|
||||
'cflags': [
|
||||
'-march=armv8-a',
|
||||
'-mfpu=crypto-neon-fp-armv8'
|
||||
'-mfpu=crypto-neon-fp-armv8',
|
||||
'<@(softfp_cflags)',
|
||||
],
|
||||
'cflags_mozilla': [
|
||||
'-march=armv8-a',
|
||||
'-mfpu=crypto-neon-fp-armv8'
|
||||
'-mfpu=crypto-neon-fp-armv8',
|
||||
'<@(softfp_cflags)',
|
||||
],
|
||||
}, 'target_arch=="arm64" or target_arch=="aarch64"', {
|
||||
'cflags': [
|
||||
|
|
@ -200,26 +507,61 @@
|
|||
],
|
||||
'dependencies': [
|
||||
'<(DEPTH)/exports.gyp:nss_exports',
|
||||
'hw-acc-crypto',
|
||||
'hw-acc-crypto-avx',
|
||||
'hw-acc-crypto-avx2',
|
||||
],
|
||||
'conditions': [
|
||||
[ 'target_arch=="ia32" or target_arch=="x64"', {
|
||||
'dependencies': [
|
||||
'gcm-aes-x86_c_lib',
|
||||
],
|
||||
}, 'disable_arm_hw_aes==0 and (target_arch=="arm" or target_arch=="arm64" or target_arch=="aarch64")', {
|
||||
}, '(disable_arm_hw_aes==0 or disable_arm_hw_sha1==0 or disable_arm_hw_sha2==0) and (target_arch=="arm" or target_arch=="arm64" or target_arch=="aarch64")', {
|
||||
'dependencies': [
|
||||
'armv8_c_lib'
|
||||
],
|
||||
}],
|
||||
[ '(target_arch=="ia32" or target_arch=="x64") and disable_intel_hw_sha==0', {
|
||||
'dependencies': [
|
||||
'sha-x86_c_lib',
|
||||
],
|
||||
}],
|
||||
[ 'disable_arm32_neon==0 and target_arch=="arm"', {
|
||||
'dependencies': [
|
||||
'gcm-aes-arm32-neon_c_lib',
|
||||
],
|
||||
}],
|
||||
[ 'disable_arm32_neon==1 and target_arch=="arm"', {
|
||||
'defines!': [
|
||||
'NSS_DISABLE_ARM32_NEON',
|
||||
],
|
||||
}],
|
||||
[ 'target_arch=="arm64" or target_arch=="aarch64"', {
|
||||
'dependencies': [
|
||||
'gcm-aes-aarch64_c_lib',
|
||||
],
|
||||
}],
|
||||
[ 'target_arch=="ppc64le"', {
|
||||
[ 'disable_altivec==0 and target_arch=="ppc64"', {
|
||||
'dependencies': [
|
||||
'gcm-aes-ppc_c_lib',
|
||||
'gcm-sha512-ppc_c_lib',
|
||||
],
|
||||
}],
|
||||
[ 'disable_altivec==0 and target_arch=="ppc64le"', {
|
||||
'dependencies': [
|
||||
'gcm-aes-ppc_c_lib',
|
||||
'gcm-sha512-ppc_c_lib',
|
||||
'chacha20-ppc_lib',
|
||||
'ppc-gcm-wrap_c_lib',
|
||||
],
|
||||
}],
|
||||
[ 'disable_altivec==1 and (target_arch=="ppc64" or target_arch=="ppc64le")', {
|
||||
'defines!': [
|
||||
'NSS_DISABLE_ALTIVEC',
|
||||
],
|
||||
}],
|
||||
[ 'disable_crypto_vsx==1 and (target_arch=="ppc" or target_arch=="ppc64" or target_arch=="ppc64le")', {
|
||||
'defines!': [
|
||||
'NSS_DISABLE_CRYPTO_VSX',
|
||||
],
|
||||
}],
|
||||
[ 'OS=="linux"', {
|
||||
|
|
@ -228,6 +570,7 @@
|
|||
'FREEBL_LOWHASH',
|
||||
'USE_HW_AES',
|
||||
'INTEL_GCM',
|
||||
'PPC_GCM',
|
||||
],
|
||||
'conditions': [
|
||||
[ 'target_arch=="x64"', {
|
||||
|
|
@ -251,7 +594,8 @@
|
|||
],
|
||||
'dependencies': [
|
||||
'<(DEPTH)/exports.gyp:nss_exports',
|
||||
'hw-acc-crypto',
|
||||
'hw-acc-crypto-avx',
|
||||
'hw-acc-crypto-avx2',
|
||||
],
|
||||
'conditions': [
|
||||
[ 'target_arch=="ia32" or target_arch=="x64"', {
|
||||
|
|
@ -263,14 +607,50 @@
|
|||
'armv8_c_lib',
|
||||
],
|
||||
}],
|
||||
[ '(target_arch=="ia32" or target_arch=="x64") and disable_intel_hw_sha==0', {
|
||||
'dependencies': [
|
||||
'sha-x86_c_lib',
|
||||
],
|
||||
}],
|
||||
[ 'disable_arm32_neon==0 and target_arch=="arm"', {
|
||||
'dependencies': [
|
||||
'gcm-aes-arm32-neon_c_lib',
|
||||
],
|
||||
}],
|
||||
[ 'disable_arm32_neon==1 and target_arch=="arm"', {
|
||||
'defines!': [
|
||||
'NSS_DISABLE_ARM32_NEON',
|
||||
],
|
||||
}],
|
||||
[ 'target_arch=="arm64" or target_arch=="aarch64"', {
|
||||
'dependencies': [
|
||||
'gcm-aes-aarch64_c_lib',
|
||||
],
|
||||
}],
|
||||
[ 'target_arch=="ppc64" or target_arch=="ppc64le"', {
|
||||
'dependencies': [
|
||||
'gcm-aes-ppc_c_lib',
|
||||
[ 'disable_altivec==0', {
|
||||
'conditions': [
|
||||
[ 'target_arch=="ppc64"', {
|
||||
'dependencies': [
|
||||
'gcm-aes-ppc_c_lib',
|
||||
'gcm-sha512-nodepend-ppc_c_lib',
|
||||
],
|
||||
}, 'target_arch=="ppc64le"', {
|
||||
'dependencies': [
|
||||
'gcm-aes-ppc_c_lib',
|
||||
'gcm-sha512-nodepend-ppc_c_lib',
|
||||
'ppc-gcm-wrap-nodepend_c_lib',
|
||||
],
|
||||
}],
|
||||
],
|
||||
}],
|
||||
[ 'disable_altivec==1 and (target_arch=="ppc64" or target_arch=="ppc64le")', {
|
||||
'defines!': [
|
||||
'NSS_DISABLE_ALTIVEC',
|
||||
],
|
||||
}],
|
||||
[ 'disable_crypto_vsx==1 and (target_arch=="ppc" or target_arch=="ppc64" or target_arch=="ppc64le")', {
|
||||
'defines!': [
|
||||
'NSS_DISABLE_CRYPTO_VSX',
|
||||
],
|
||||
}],
|
||||
[ 'OS!="linux"', {
|
||||
|
|
@ -291,7 +671,7 @@
|
|||
'intel-gcm-wrap_c_lib',
|
||||
],
|
||||
}],
|
||||
[ 'OS=="win" and cc_is_clang==1', {
|
||||
[ 'OS=="win" and (target_arch=="ia32" or target_arch=="x64") and cc_is_clang==1', {
|
||||
'dependencies': [
|
||||
'intel-gcm-wrap_c_lib',
|
||||
],
|
||||
|
|
@ -321,7 +701,8 @@
|
|||
'type': 'shared_library',
|
||||
'dependencies': [
|
||||
'<(DEPTH)/exports.gyp:nss_exports',
|
||||
'hw-acc-crypto',
|
||||
'hw-acc-crypto-avx',
|
||||
'hw-acc-crypto-avx2',
|
||||
],
|
||||
},
|
||||
{
|
||||
|
|
@ -337,7 +718,8 @@
|
|||
],
|
||||
'dependencies': [
|
||||
'<(DEPTH)/exports.gyp:nss_exports',
|
||||
'hw-acc-crypto',
|
||||
'hw-acc-crypto-avx',
|
||||
'hw-acc-crypto-avx2',
|
||||
],
|
||||
'asflags_mozilla': [
|
||||
'-mcpu=v9', '-Wa,-xarch=v9a'
|
||||
|
|
@ -379,6 +761,10 @@
|
|||
'mpi',
|
||||
'ecl',
|
||||
'verified',
|
||||
'verified/internal',
|
||||
'verified/karamel/include',
|
||||
'verified/karamel/krmllib/dist/minimal',
|
||||
'deprecated',
|
||||
],
|
||||
'defines': [
|
||||
'SHLIB_SUFFIX=\"<(dll_suffix)\"',
|
||||
|
|
@ -422,20 +808,49 @@
|
|||
},
|
||||
},
|
||||
}],
|
||||
[ '(OS=="win" or OS=="mac" or OS=="ios") and (target_arch=="ia32" or target_arch=="x64") and disable_intel_hw_sha==0', {
|
||||
'defines': [
|
||||
'USE_HW_SHA2',
|
||||
],
|
||||
}],
|
||||
[ '(OS=="win" or OS=="mac" or OS=="ios") and (target_arch=="arm64" or target_arch=="aarch64") and disable_arm_hw_aes==0', {
|
||||
'defines': [
|
||||
'USE_HW_AES',
|
||||
],
|
||||
}],
|
||||
[ '(OS=="win" or OS=="mac" or OS=="ios") and (target_arch=="arm64" or target_arch=="aarch64") and disable_arm_hw_sha1==0', {
|
||||
'defines': [
|
||||
'USE_HW_SHA1',
|
||||
],
|
||||
}],
|
||||
[ '(OS=="win" or OS=="mac" or OS=="ios") and (target_arch=="arm64" or target_arch=="aarch64") and disable_arm_hw_sha2==0', {
|
||||
'defines': [
|
||||
'USE_HW_SHA2',
|
||||
],
|
||||
}],
|
||||
[ 'cc_use_gnu_ld==1 and OS=="win" and target_arch=="x64"', {
|
||||
# mingw x64
|
||||
'defines': [
|
||||
'MP_IS_LITTLE_ENDIAN',
|
||||
],
|
||||
}],
|
||||
[ 'have_int128_support==1', {
|
||||
# Poly1305_256 requires the flag to run
|
||||
['target_arch=="x64"', {
|
||||
'defines':[
|
||||
'HACL_CAN_COMPILE_VEC128',
|
||||
'HACL_CAN_COMPILE_VEC256',
|
||||
],
|
||||
}],
|
||||
# MSVC has no __int128 type. Use emulated int128 and leave
|
||||
# have_int128_support as-is for Curve25519 impl. selection.
|
||||
[ 'have_int128_support==1 and (OS!="win" or cc_is_clang==1 or cc_is_gcc==1)', {
|
||||
'defines': [
|
||||
# The Makefile does version-tests on GCC, but we're not doing that here.
|
||||
'HAVE_INT128_SUPPORT',
|
||||
],
|
||||
}, {
|
||||
'defines': [
|
||||
'KRML_NOUINT128',
|
||||
'KRML_VERIFIED_UINT128',
|
||||
],
|
||||
}],
|
||||
[ 'OS=="linux"', {
|
||||
|
|
@ -443,6 +858,13 @@
|
|||
'FREEBL_LOWHASH',
|
||||
'FREEBL_NO_DEPEND',
|
||||
],
|
||||
'conditions': [
|
||||
[ 'disable_altivec==0 and target_arch=="ppc64le"', {
|
||||
'defines': [
|
||||
'PPC_GCM',
|
||||
],
|
||||
}],
|
||||
],
|
||||
}],
|
||||
[ 'OS=="linux" or OS=="android"', {
|
||||
'conditions': [
|
||||
|
|
@ -479,11 +901,26 @@
|
|||
'ARMHF',
|
||||
],
|
||||
}],
|
||||
[ 'disable_intel_hw_sha==0 and (target_arch=="ia32" or target_arch=="x64")', {
|
||||
'defines': [
|
||||
'USE_HW_SHA2',
|
||||
],
|
||||
}],
|
||||
[ 'disable_arm_hw_aes==0 and (target_arch=="arm" or target_arch=="arm64" or target_arch=="aarch64")', {
|
||||
'defines': [
|
||||
'USE_HW_AES',
|
||||
],
|
||||
}],
|
||||
[ 'disable_arm_hw_sha1==0 and (target_arch=="arm" or target_arch=="arm64" or target_arch=="aarch64")', {
|
||||
'defines': [
|
||||
'USE_HW_SHA1',
|
||||
],
|
||||
}],
|
||||
[ 'disable_arm_hw_sha2==0 and (target_arch=="arm" or target_arch=="arm64" or target_arch=="aarch64")', {
|
||||
'defines': [
|
||||
'USE_HW_SHA2',
|
||||
],
|
||||
}],
|
||||
],
|
||||
}],
|
||||
],
|
||||
|
|
@ -491,17 +928,16 @@
|
|||
'variables': {
|
||||
'module': 'nss',
|
||||
'conditions': [
|
||||
[ 'OS!="win"', {
|
||||
'conditions': [
|
||||
[ 'target_arch=="x64" or target_arch=="arm64" or target_arch=="aarch64"', {
|
||||
'have_int128_support%': 1,
|
||||
}, {
|
||||
'have_int128_support%': 0,
|
||||
}],
|
||||
],
|
||||
[ 'target_arch=="x64" or target_arch=="arm64" or target_arch=="aarch64"', {
|
||||
'have_int128_support%': 1,
|
||||
}, {
|
||||
'have_int128_support%': 0,
|
||||
}],
|
||||
[ 'target_arch=="arm"', {
|
||||
# When the compiler uses the softfloat ABI, we want to use the compatible softfp ABI when enabling NEON for these objects.
|
||||
# Confusingly, __SOFTFP__ is the name of the define for the softfloat ABI, not for the softfp ABI.
|
||||
'softfp_cflags': '<!(${CC:-cc} -o - -E -dM - ${CFLAGS} < /dev/null | grep __SOFTFP__ > /dev/null && echo -mfloat-abi=softfp || true)',
|
||||
}],
|
||||
],
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
{
|
||||
'sources': [
|
||||
'aeskeywrap.c',
|
||||
'alg2268.c',
|
||||
'cmac.c',
|
||||
'alghmac.c',
|
||||
'arcfive.c',
|
||||
|
|
@ -57,12 +56,11 @@
|
|||
'rijndael.c',
|
||||
'rsa.c',
|
||||
'rsapkcs.c',
|
||||
'seed.c',
|
||||
'sha512.c',
|
||||
'sha_fast.c',
|
||||
'shvfy.c',
|
||||
'sysrand.c',
|
||||
'tlsprfalg.c',
|
||||
'secmpi.c',
|
||||
],
|
||||
'conditions': [
|
||||
[ 'OS=="linux" or OS=="android"', {
|
||||
|
|
@ -71,11 +69,11 @@
|
|||
'sources': [
|
||||
'arcfour-amd64-gas.s',
|
||||
'mpi/mpi_amd64.c',
|
||||
'mpi/mpi_amd64_gas.s',
|
||||
'mpi/mpi_amd64_common.S',
|
||||
'mpi/mp_comba.c',
|
||||
],
|
||||
'conditions': [
|
||||
[ 'cc_is_clang==1 and fuzz!=1', {
|
||||
[ 'cc_is_clang==1 and fuzz!=1 and coverage!=1 and force_integrated_as!=1', {
|
||||
'cflags': [
|
||||
'-no-integrated-as',
|
||||
],
|
||||
|
|
@ -98,6 +96,12 @@
|
|||
'mpi/mpi_arm.c',
|
||||
],
|
||||
}],
|
||||
[ 'target_arch=="ppc64le"', {
|
||||
'sources': [
|
||||
'chacha20poly1305-ppc.c',
|
||||
'chacha20-ppc64le.S',
|
||||
],
|
||||
}]
|
||||
],
|
||||
}],
|
||||
[ 'OS=="win"', {
|
||||
|
|
@ -135,54 +139,43 @@
|
|||
}],
|
||||
],
|
||||
}],
|
||||
['target_arch=="ia32" or target_arch=="x64" or target_arch=="arm64" or target_arch=="aarch64"', {
|
||||
['have_int128_support==1', {
|
||||
'sources': [
|
||||
# All intel and 64-bit ARM architectures get the 64 bit version.
|
||||
# All intel x64 and 64-bit ARM architectures get the 64 bit version.
|
||||
'ecl/curve25519_64.c',
|
||||
'verified/Hacl_Curve25519.c',
|
||||
'verified/Hacl_Curve25519_51.c',
|
||||
],
|
||||
}, {
|
||||
'sources': [
|
||||
# All other architectures get the generic 32 bit implementation (slow!)
|
||||
# All other architectures get the generic 32 bit implementation.
|
||||
'ecl/curve25519_32.c',
|
||||
],
|
||||
}],
|
||||
['(target_arch!="ppc64" and target_arch!="ppc64le") or disable_altivec==1', {
|
||||
'sources': [
|
||||
# Gyp does not support per-file cflags, so working around like this.
|
||||
# ppc performance greatly benefits from specific flags.
|
||||
'sha512.c',
|
||||
],
|
||||
}],
|
||||
[ 'disable_chachapoly==0', {
|
||||
# The ChaCha20 code is linked in through the static ssse3-crypto lib on
|
||||
# all platforms that support SSSE3. There are runtime checks in place to
|
||||
# choose the correct ChaCha implementation at runtime.
|
||||
'sources': [
|
||||
'verified/Hacl_Chacha20.c',
|
||||
'verified/Hacl_Chacha20Poly1305_32.c',
|
||||
'verified/Hacl_Poly1305_32.c',
|
||||
],
|
||||
'conditions': [
|
||||
[ 'OS!="win"', {
|
||||
'conditions': [
|
||||
[ 'target_arch=="x64"', {
|
||||
'sources': [
|
||||
'verified/Hacl_Poly1305_64.c',
|
||||
],
|
||||
}, {
|
||||
# !Windows & !x64
|
||||
'conditions': [
|
||||
[ 'target_arch=="arm64" or target_arch=="aarch64"', {
|
||||
'sources': [
|
||||
'verified/Hacl_Poly1305_64.c',
|
||||
],
|
||||
}, {
|
||||
# !Windows & !x64 & !arm64 & !aarch64
|
||||
'sources': [
|
||||
'verified/Hacl_Poly1305_32.c',
|
||||
],
|
||||
}],
|
||||
],
|
||||
}],
|
||||
],
|
||||
}, {
|
||||
# Windows
|
||||
'sources': [
|
||||
'verified/Hacl_Poly1305_32.c',
|
||||
],
|
||||
}],
|
||||
}],
|
||||
[ 'disable_deprecated_seed==0', {
|
||||
'sources': [
|
||||
'deprecated/seed.c',
|
||||
],
|
||||
}],
|
||||
[ 'disable_deprecated_rc2==0', {
|
||||
'sources': [
|
||||
'deprecated/alg2268.c',
|
||||
],
|
||||
}],
|
||||
[ 'fuzz==1', {
|
||||
|
|
@ -216,12 +209,21 @@
|
|||
'MP_ASSEMBLY_SQUARE',
|
||||
'MP_ASSEMBLY_DIV_2DX1D',
|
||||
],
|
||||
}, 'target_arch=="x64"', {
|
||||
'sources': [
|
||||
'mpi/mpi_amd64.c',
|
||||
'mpi/mpi_amd64_common.S',
|
||||
'mpi/mp_comba.c',
|
||||
],
|
||||
'defines': [
|
||||
'MP_IS_LITTLE_ENDIAN',
|
||||
'MPI_AMD64',
|
||||
'MP_ASSEMBLY_MULTIPLY',
|
||||
'NSS_USE_COMBA',
|
||||
],
|
||||
}],
|
||||
],
|
||||
}],
|
||||
[ 'have_int128_support==0', {
|
||||
'sources': [ 'verified/FStar.c' ],
|
||||
}],
|
||||
],
|
||||
'ldflags': [
|
||||
'-Wl,-Bsymbolic'
|
||||
|
|
|
|||
202
security/nss/lib/freebl/gcm-arm32-neon.c
Normal file
202
security/nss/lib/freebl/gcm-arm32-neon.c
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifdef FREEBL_NO_DEPEND
|
||||
#include "stubs.h"
|
||||
#endif
|
||||
#include "blapii.h"
|
||||
#include "blapit.h"
|
||||
#include "gcm.h"
|
||||
#include "secerr.h"
|
||||
#include "prtypes.h"
|
||||
|
||||
#if defined(IS_LITTLE_ENDIAN)
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
SECStatus
|
||||
gcm_HashWrite_hw(gcmHashContext *ghash, unsigned char *outbuf)
|
||||
{
|
||||
vst1_u8(outbuf, vrev64_u8(vcreate_u8(ghash->x_high)));
|
||||
vst1_u8(outbuf + 8, vrev64_u8(vcreate_u8(ghash->x_low)));
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
/* Carry-less multiplication. a * b = ret. */
|
||||
static inline uint8x16_t
|
||||
clmul(const uint8x8_t a, const uint8x8_t b)
|
||||
{
|
||||
uint8x16_t d, e, f, g, h, i, j, k, l, m, n;
|
||||
uint8x8_t t_high, t_low;
|
||||
uint8x16_t t0, t1, t2, t3;
|
||||
const uint8x8_t k16 = vcreate_u8(0xffff);
|
||||
const uint8x8_t k32 = vcreate_u8(0xffffffff);
|
||||
const uint8x8_t k48 = vcreate_u8(0xffffffffffff);
|
||||
|
||||
// D = A * B
|
||||
d = vreinterpretq_u8_p16(vmull_p8(vreinterpret_p8_u8(a),
|
||||
vreinterpret_p8_u8(b)));
|
||||
// E = A * B1
|
||||
e = vreinterpretq_u8_p16(vmull_p8(vreinterpret_p8_u8(a),
|
||||
vreinterpret_p8_u8(vext_u8(b, b, 1))));
|
||||
// F = A1 * B
|
||||
f = vreinterpretq_u8_p16(vmull_p8(vreinterpret_p8_u8(vext_u8(a, a, 1)),
|
||||
vreinterpret_p8_u8(b)));
|
||||
// G = A * B2
|
||||
g = vreinterpretq_u8_p16(vmull_p8(vreinterpret_p8_u8(a),
|
||||
vreinterpret_p8_u8(vext_u8(b, b, 2))));
|
||||
// H = A2 * B
|
||||
h = vreinterpretq_u8_p16(vmull_p8(vreinterpret_p8_u8(vext_u8(a, a, 2)),
|
||||
vreinterpret_p8_u8(b)));
|
||||
// I = A * B3
|
||||
i = vreinterpretq_u8_p16(vmull_p8(vreinterpret_p8_u8(a),
|
||||
vreinterpret_p8_u8(vext_u8(b, b, 3))));
|
||||
// J = A3 * B
|
||||
j = vreinterpretq_u8_p16(vmull_p8(vreinterpret_p8_u8(vext_u8(a, a, 3)),
|
||||
vreinterpret_p8_u8(b)));
|
||||
// K = A * B4
|
||||
k = vreinterpretq_u8_p16(vmull_p8(vreinterpret_p8_u8(a),
|
||||
vreinterpret_p8_u8(vext_u8(b, b, 4))));
|
||||
// L = E + F
|
||||
l = veorq_u8(e, f);
|
||||
// M = G + H
|
||||
m = veorq_u8(g, h);
|
||||
// N = I + J
|
||||
n = veorq_u8(i, j);
|
||||
|
||||
// t0 = (L) (P0 + P1) << 8
|
||||
t_high = vget_high_u8(l);
|
||||
t_low = vget_low_u8(l);
|
||||
t_low = veor_u8(t_low, t_high);
|
||||
t_high = vand_u8(t_high, k48);
|
||||
t_low = veor_u8(t_low, t_high);
|
||||
t0 = vcombine_u8(t_low, t_high);
|
||||
t0 = vextq_u8(t0, t0, 15);
|
||||
|
||||
// t1 = (M) (P2 + P3) << 16
|
||||
t_high = vget_high_u8(m);
|
||||
t_low = vget_low_u8(m);
|
||||
t_low = veor_u8(t_low, t_high);
|
||||
t_high = vand_u8(t_high, k32);
|
||||
t_low = veor_u8(t_low, t_high);
|
||||
t1 = vcombine_u8(t_low, t_high);
|
||||
t1 = vextq_u8(t1, t1, 14);
|
||||
|
||||
// t2 = (N) (P4 + P5) << 24
|
||||
t_high = vget_high_u8(n);
|
||||
t_low = vget_low_u8(n);
|
||||
t_low = veor_u8(t_low, t_high);
|
||||
t_high = vand_u8(t_high, k16);
|
||||
t_low = veor_u8(t_low, t_high);
|
||||
t2 = vcombine_u8(t_low, t_high);
|
||||
t2 = vextq_u8(t2, t2, 13);
|
||||
|
||||
// t3 = (K) (P6 + P7) << 32
|
||||
t_high = vget_high_u8(k);
|
||||
t_low = vget_low_u8(k);
|
||||
t_low = veor_u8(t_low, t_high);
|
||||
t_high = vdup_n_u8(0);
|
||||
t3 = vcombine_u8(t_low, t_high);
|
||||
t3 = vextq_u8(t3, t3, 12);
|
||||
|
||||
t0 = veorq_u8(t0, t1);
|
||||
t2 = veorq_u8(t2, t3);
|
||||
return veorq_u8(veorq_u8(d, t0), t2);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
gcm_HashMult_hw(gcmHashContext *ghash, const unsigned char *buf,
|
||||
unsigned int count)
|
||||
{
|
||||
const uint8x8_t h_low = vcreate_u8(ghash->h_low);
|
||||
const uint8x8_t h_high = vcreate_u8(ghash->h_high);
|
||||
uint8x16_t ci;
|
||||
uint8x8_t ci_low;
|
||||
uint8x8_t ci_high;
|
||||
uint8x16_t z0, z2, z1a;
|
||||
uint8x16_t z_high, z_low;
|
||||
uint8x16_t t;
|
||||
int64x2_t t1, t2, t3;
|
||||
uint64x2_t z_low_l, z_low_r, z_high_l, z_high_r;
|
||||
size_t i;
|
||||
|
||||
ci = vcombine_u8(vcreate_u8(ghash->x_low), vcreate_u8(ghash->x_high));
|
||||
|
||||
for (i = 0; i < count; i++, buf += 16) {
|
||||
ci = veorq_u8(ci, vcombine_u8(vrev64_u8(vld1_u8(buf + 8)),
|
||||
vrev64_u8(vld1_u8(buf))));
|
||||
ci_high = vget_high_u8(ci);
|
||||
ci_low = vget_low_u8(ci);
|
||||
|
||||
/* Do binary mult ghash->X = C * ghash->H (Karatsuba). */
|
||||
z0 = clmul(ci_low, h_low);
|
||||
z2 = clmul(ci_high, h_high);
|
||||
z1a = clmul(veor_u8(ci_high, ci_low), veor_u8(h_high, h_low));
|
||||
z1a = veorq_u8(z0, z1a);
|
||||
z1a = veorq_u8(z2, z1a);
|
||||
z_high = vcombine_u8(veor_u8(vget_low_u8(z2), vget_high_u8(z1a)),
|
||||
vget_high_u8(z2));
|
||||
z_low = vcombine_u8(vget_low_u8(z0),
|
||||
veor_u8(vget_high_u8(z0), vget_low_u8(z1a)));
|
||||
|
||||
/* Shift one (multiply by x) as gcm spec is stupid. */
|
||||
z_low_l = vshlq_n_u64(vreinterpretq_u64_u8(z_low), 1);
|
||||
z_low_r = vshrq_n_u64(vreinterpretq_u64_u8(z_low), 63);
|
||||
z_high_l = vshlq_n_u64(vreinterpretq_u64_u8(z_high), 1);
|
||||
z_high_r = vshrq_n_u64(vreinterpretq_u64_u8(z_high), 63);
|
||||
z_low = vreinterpretq_u8_u64(
|
||||
vcombine_u64(vget_low_u64(z_low_l),
|
||||
vorr_u64(vget_high_u64(z_low_l),
|
||||
vget_low_u64(z_low_r))));
|
||||
z_high = vreinterpretq_u8_u64(
|
||||
vcombine_u64(vorr_u64(vget_low_u64(z_high_l),
|
||||
vget_high_u64(z_low_r)),
|
||||
vorr_u64(vget_high_u64(z_high_l),
|
||||
vget_low_u64(z_high_r))));
|
||||
|
||||
/* Reduce */
|
||||
t1 = vshlq_n_s64(vreinterpretq_s64_u8(z_low), 57);
|
||||
t2 = vshlq_n_s64(vreinterpretq_s64_u8(z_low), 62);
|
||||
t3 = vshlq_n_s64(vreinterpretq_s64_u8(z_low), 63);
|
||||
t = vreinterpretq_u8_s64(veorq_s64(t1, veorq_s64(t2, t3)));
|
||||
|
||||
z_low = vcombine_u8(vget_low_u8(z_low),
|
||||
veor_u8(vget_high_u8(z_low), vget_low_u8(t)));
|
||||
z_high = vcombine_u8(veor_u8(vget_low_u8(z_high), vget_high_u8(t)),
|
||||
vget_high_u8(z_high));
|
||||
|
||||
t = vreinterpretq_u8_u64(vshrq_n_u64(vreinterpretq_u64_u8(z_low), 1));
|
||||
z_high = veorq_u8(z_high, z_low);
|
||||
z_low = veorq_u8(z_low, t);
|
||||
t = vreinterpretq_u8_u64(vshrq_n_u64(vreinterpretq_u64_u8(t), 6));
|
||||
z_low = vreinterpretq_u8_u64(
|
||||
vshrq_n_u64(vreinterpretq_u64_u8(z_low), 1));
|
||||
z_low = veorq_u8(z_low, z_high);
|
||||
ci = veorq_u8(z_low, t);
|
||||
}
|
||||
|
||||
vst1_u8((uint8_t *)&ghash->x_high, vget_high_u8(ci));
|
||||
vst1_u8((uint8_t *)&ghash->x_low, vget_low_u8(ci));
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
gcm_HashInit_hw(gcmHashContext *ghash)
|
||||
{
|
||||
ghash->ghash_mul = gcm_HashMult_hw;
|
||||
ghash->x_low = 0;
|
||||
ghash->x_high = 0;
|
||||
ghash->hw = PR_TRUE;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
gcm_HashZeroX_hw(gcmHashContext *ghash)
|
||||
{
|
||||
ghash->x_low = 0;
|
||||
ghash->x_high = 0;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
#endif /* IS_LITTLE_ENDIAN */
|
||||
|
|
@ -9,6 +9,7 @@
|
|||
#endif
|
||||
#include "blapii.h"
|
||||
#include "blapit.h"
|
||||
#include "blapi.h"
|
||||
#include "gcm.h"
|
||||
#include "ctr.h"
|
||||
#include "secerr.h"
|
||||
|
|
@ -21,6 +22,10 @@
|
|||
#if defined(__aarch64__) && defined(IS_LITTLE_ENDIAN) && \
|
||||
(defined(__clang__) || defined(__GNUC__) && __GNUC__ > 6)
|
||||
#define USE_ARM_GCM
|
||||
#elif defined(__arm__) && defined(IS_LITTLE_ENDIAN) && \
|
||||
!defined(NSS_DISABLE_ARM32_NEON)
|
||||
/* We don't test on big endian platform, so disable this on big endian. */
|
||||
#define USE_ARM_GCM
|
||||
#endif
|
||||
|
||||
/* Forward declarations */
|
||||
|
|
@ -93,7 +98,11 @@ gcmHash_InitContext(gcmHashContext *ghash, const unsigned char *H, PRBool sw)
|
|||
ghash->h_low = get64(H + 8);
|
||||
ghash->h_high = get64(H);
|
||||
#ifdef USE_ARM_GCM
|
||||
#if defined(__aarch64__)
|
||||
if (arm_pmull_support() && !sw) {
|
||||
#else
|
||||
if (arm_neon_support() && !sw) {
|
||||
#endif
|
||||
#elif defined(USE_PPC_CRYPTO)
|
||||
if (ppc_crypto_support() && !sw) {
|
||||
#else
|
||||
|
|
@ -482,9 +491,12 @@ gcmHash_Reset(gcmHashContext *ghash, const unsigned char *AAD,
|
|||
SECStatus rv;
|
||||
|
||||
// Limit AADLen in accordance with SP800-38D
|
||||
if (sizeof(AADLen) >= 8 && AADLen > (1ULL << 61) - 1) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
if (sizeof(AADLen) >= 8) {
|
||||
unsigned long long AADLen_ull = AADLen;
|
||||
if (AADLen_ull > (1ULL << 61) - 1) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
}
|
||||
|
||||
ghash->cLen = 0;
|
||||
|
|
@ -517,10 +529,18 @@ gcmHash_Reset(gcmHashContext *ghash, const unsigned char *AAD,
|
|||
struct GCMContextStr {
|
||||
gcmHashContext *ghash_context;
|
||||
CTRContext ctr_context;
|
||||
freeblCipherFunc cipher;
|
||||
void *cipher_context;
|
||||
unsigned long tagBits;
|
||||
unsigned char tagKey[MAX_BLOCK_SIZE];
|
||||
PRBool ctr_context_init;
|
||||
gcmIVContext gcm_iv;
|
||||
};
|
||||
|
||||
SECStatus gcm_InitCounter(GCMContext *gcm, const unsigned char *iv,
|
||||
unsigned int ivLen, unsigned int tagBits,
|
||||
const unsigned char *aad, unsigned int aadLen);
|
||||
|
||||
GCMContext *
|
||||
GCM_CreateContext(void *context, freeblCipherFunc cipher,
|
||||
const unsigned char *params)
|
||||
|
|
@ -529,9 +549,7 @@ GCM_CreateContext(void *context, freeblCipherFunc cipher,
|
|||
gcmHashContext *ghash = NULL;
|
||||
unsigned char H[MAX_BLOCK_SIZE];
|
||||
unsigned int tmp;
|
||||
PRBool freeCtr = PR_FALSE;
|
||||
const CK_GCM_PARAMS *gcmParams = (const CK_GCM_PARAMS *)params;
|
||||
CK_AES_CTR_PARAMS ctrParams;
|
||||
const CK_NSS_GCM_PARAMS *gcmParams = (const CK_NSS_GCM_PARAMS *)params;
|
||||
SECStatus rv;
|
||||
#ifdef DISABLE_HW_GCM
|
||||
const PRBool sw = PR_TRUE;
|
||||
|
|
@ -539,23 +557,12 @@ GCM_CreateContext(void *context, freeblCipherFunc cipher,
|
|||
const PRBool sw = PR_FALSE;
|
||||
#endif
|
||||
|
||||
if (gcmParams->ulIvLen == 0) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (gcmParams->ulTagBits != 128 && gcmParams->ulTagBits != 120 &&
|
||||
gcmParams->ulTagBits != 112 && gcmParams->ulTagBits != 104 &&
|
||||
gcmParams->ulTagBits != 96 && gcmParams->ulTagBits != 64 &&
|
||||
gcmParams->ulTagBits != 32) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gcm = PORT_ZNew(GCMContext);
|
||||
if (gcm == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
gcm->cipher = cipher;
|
||||
gcm->cipher_context = context;
|
||||
ghash = PORT_ZNewAligned(gcmHashContext, 16, mem);
|
||||
|
||||
/* first plug in the ghash context */
|
||||
|
|
@ -570,14 +577,79 @@ GCM_CreateContext(void *context, freeblCipherFunc cipher,
|
|||
goto loser;
|
||||
}
|
||||
|
||||
gcm_InitIVContext(&gcm->gcm_iv);
|
||||
gcm->ctr_context_init = PR_FALSE;
|
||||
|
||||
/* if gcmPara/ms is NULL, then we are creating an PKCS #11 MESSAGE
|
||||
* style context, in which we initialize the key once, then do separate
|
||||
* iv/aad's for each message. In that case we only initialize the key
|
||||
* and ghash. We initialize the counter in each separate message */
|
||||
if (gcmParams == NULL) {
|
||||
/* OK we are finished with init, if we are doing MESSAGE interface,
|
||||
* return from here */
|
||||
return gcm;
|
||||
}
|
||||
|
||||
rv = gcm_InitCounter(gcm, gcmParams->pIv, gcmParams->ulIvLen,
|
||||
gcmParams->ulTagBits, gcmParams->pAAD,
|
||||
gcmParams->ulAADLen);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
PORT_Memset(H, 0, AES_BLOCK_SIZE);
|
||||
gcm->ctr_context_init = PR_TRUE;
|
||||
return gcm;
|
||||
|
||||
loser:
|
||||
PORT_Memset(H, 0, AES_BLOCK_SIZE);
|
||||
if (ghash && ghash->mem) {
|
||||
void *mem = ghash->mem;
|
||||
PORT_Memset(ghash, 0, sizeof(gcmHashContext));
|
||||
PORT_Free(mem);
|
||||
}
|
||||
if (gcm) {
|
||||
PORT_ZFree(gcm, sizeof(GCMContext));
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
gcm_InitCounter(GCMContext *gcm, const unsigned char *iv, unsigned int ivLen,
|
||||
unsigned int tagBits, const unsigned char *aad,
|
||||
unsigned int aadLen)
|
||||
{
|
||||
gcmHashContext *ghash = gcm->ghash_context;
|
||||
unsigned int tmp;
|
||||
PRBool freeCtr = PR_FALSE;
|
||||
CK_AES_CTR_PARAMS ctrParams;
|
||||
SECStatus rv;
|
||||
|
||||
/* Verify our parameters here */
|
||||
if (ivLen == 0) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (tagBits != 128 && tagBits != 120 &&
|
||||
tagBits != 112 && tagBits != 104 &&
|
||||
tagBits != 96 && tagBits != 64 &&
|
||||
tagBits != 32) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* fill in the Counter context */
|
||||
ctrParams.ulCounterBits = 32;
|
||||
PORT_Memset(ctrParams.cb, 0, sizeof(ctrParams.cb));
|
||||
if (gcmParams->ulIvLen == 12) {
|
||||
PORT_Memcpy(ctrParams.cb, gcmParams->pIv, gcmParams->ulIvLen);
|
||||
if (ivLen == 12) {
|
||||
PORT_Memcpy(ctrParams.cb, iv, ivLen);
|
||||
ctrParams.cb[AES_BLOCK_SIZE - 1] = 1;
|
||||
} else {
|
||||
rv = gcmHash_Update(ghash, gcmParams->pIv, gcmParams->ulIvLen);
|
||||
rv = gcmHash_Reset(ghash, NULL, 0);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
rv = gcmHash_Update(ghash, iv, ivLen);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
|
@ -586,7 +658,7 @@ GCM_CreateContext(void *context, freeblCipherFunc cipher,
|
|||
goto loser;
|
||||
}
|
||||
}
|
||||
rv = CTR_InitContext(&gcm->ctr_context, context, cipher,
|
||||
rv = CTR_InitContext(&gcm->ctr_context, gcm->cipher_context, gcm->cipher,
|
||||
(unsigned char *)&ctrParams);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
|
|
@ -594,9 +666,10 @@ GCM_CreateContext(void *context, freeblCipherFunc cipher,
|
|||
freeCtr = PR_TRUE;
|
||||
|
||||
/* fill in the gcm structure */
|
||||
gcm->tagBits = gcmParams->ulTagBits; /* save for final step */
|
||||
gcm->tagBits = tagBits; /* save for final step */
|
||||
/* calculate the final tag key. NOTE: gcm->tagKey is zero to start with.
|
||||
* if this assumption changes, we would need to explicitly clear it here */
|
||||
PORT_Memset(gcm->tagKey, 0, sizeof(gcm->tagKey));
|
||||
rv = CTR_Update(&gcm->ctr_context, gcm->tagKey, &tmp, AES_BLOCK_SIZE,
|
||||
gcm->tagKey, AES_BLOCK_SIZE, AES_BLOCK_SIZE);
|
||||
if (rv != SECSuccess) {
|
||||
|
|
@ -604,34 +677,34 @@ GCM_CreateContext(void *context, freeblCipherFunc cipher,
|
|||
}
|
||||
|
||||
/* finally mix in the AAD data */
|
||||
rv = gcmHash_Reset(ghash, gcmParams->pAAD, gcmParams->ulAADLen);
|
||||
rv = gcmHash_Reset(ghash, aad, aadLen);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return gcm;
|
||||
PORT_Memset(&ctrParams, 0, sizeof ctrParams);
|
||||
return SECSuccess;
|
||||
|
||||
loser:
|
||||
PORT_Memset(&ctrParams, 0, sizeof ctrParams);
|
||||
if (freeCtr) {
|
||||
CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
|
||||
}
|
||||
if (ghash && ghash->mem) {
|
||||
PORT_Free(ghash->mem);
|
||||
}
|
||||
if (gcm) {
|
||||
PORT_Free(gcm);
|
||||
}
|
||||
return NULL;
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
void
|
||||
GCM_DestroyContext(GCMContext *gcm, PRBool freeit)
|
||||
{
|
||||
/* these two are statically allocated and will be freed when we free
|
||||
void *mem = gcm->ghash_context->mem;
|
||||
/* ctr_context is statically allocated and will be freed when we free
|
||||
* gcm. call their destroy functions to free up any locally
|
||||
* allocated data (like mp_int's) */
|
||||
CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
|
||||
PORT_Free(gcm->ghash_context->mem);
|
||||
if (gcm->ctr_context_init) {
|
||||
CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
|
||||
}
|
||||
PORT_Memset(gcm->ghash_context, 0, sizeof(gcmHashContext));
|
||||
PORT_Free(mem);
|
||||
PORT_Memset(&gcm->tagBits, 0, sizeof(gcm->tagBits));
|
||||
PORT_Memset(gcm->tagKey, 0, sizeof(gcm->tagKey));
|
||||
if (freeit) {
|
||||
|
|
@ -699,6 +772,11 @@ GCM_EncryptUpdate(GCMContext *gcm, unsigned char *outbuf,
|
|||
return SECFailure;
|
||||
}
|
||||
|
||||
if (!gcm->ctr_context_init) {
|
||||
PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE;
|
||||
if (UINT_MAX - inlen < tagBytes) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
|
|
@ -757,6 +835,11 @@ GCM_DecryptUpdate(GCMContext *gcm, unsigned char *outbuf,
|
|||
return SECFailure;
|
||||
}
|
||||
|
||||
if (!gcm->ctr_context_init) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE;
|
||||
|
||||
/* get the authentication block */
|
||||
|
|
@ -791,3 +874,298 @@ GCM_DecryptUpdate(GCMContext *gcm, unsigned char *outbuf,
|
|||
return CTR_Update(&gcm->ctr_context, outbuf, outlen, maxout,
|
||||
inbuf, inlen, AES_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
void
|
||||
gcm_InitIVContext(gcmIVContext *gcmIv)
|
||||
{
|
||||
gcmIv->counter = 0;
|
||||
gcmIv->max_count = 0;
|
||||
gcmIv->ivGen = CKG_GENERATE;
|
||||
gcmIv->ivLen = 0;
|
||||
gcmIv->fixedBits = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* generate the IV on the fly and return it to the application.
|
||||
* This function keeps a counter, which may be used in the IV
|
||||
* generation, or may be used in simply to make sure we don't
|
||||
* generate to many IV's from this same key.
|
||||
* PKCS #11 defines 4 generating values:
|
||||
* 1) CKG_NO_GENERATE: just use the passed in IV as it.
|
||||
* 2) CKG_GENERATE: the application doesn't care what generation
|
||||
* scheme is use (we default to counter in this code).
|
||||
* 3) CKG_GENERATE_COUNTER: The IV is the value of a counter.
|
||||
* 4) CKG_GENERATE_RANDOM: The IV is randomly generated.
|
||||
* We add a fifth rule:
|
||||
* 5) CKG_GENERATE_COUNTER_XOR: The Counter value is xor'ed with
|
||||
* the IV.
|
||||
* The value fixedBits specifies the number of bits that will be passed
|
||||
* on from the original IV. The counter or the random data is is loaded
|
||||
* in the remainder of the IV not covered by fixedBits, overwriting any
|
||||
* data there. In the xor case the counter is xor'ed with the data in the
|
||||
* IV. In all cases only bits outside of fixedBits is modified.
|
||||
* The number of IV's we can generate is restricted by the size of the
|
||||
* variable part of the IV and the generation algorithm used. Because of
|
||||
* this, we require subsequent calls on this context to use the same
|
||||
* generator, IV len, and fixed bits as the first call.
|
||||
*/
|
||||
SECStatus
|
||||
gcm_GenerateIV(gcmIVContext *gcmIv, unsigned char *iv, unsigned int ivLen,
|
||||
unsigned int fixedBits, CK_GENERATOR_FUNCTION ivGen)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int flexBits;
|
||||
unsigned int ivOffset;
|
||||
unsigned int ivNewCount;
|
||||
unsigned char ivMask;
|
||||
unsigned char ivSave;
|
||||
SECStatus rv;
|
||||
|
||||
if (gcmIv->counter != 0) {
|
||||
/* If we've already generated a message, make sure all subsequent
|
||||
* messages are using the same generator */
|
||||
if ((gcmIv->ivGen != ivGen) || (gcmIv->fixedBits != fixedBits) ||
|
||||
(gcmIv->ivLen != ivLen)) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
} else {
|
||||
/* remember these values */
|
||||
gcmIv->ivGen = ivGen;
|
||||
gcmIv->fixedBits = fixedBits;
|
||||
gcmIv->ivLen = ivLen;
|
||||
/* now calculate how may bits of IV we have to supply */
|
||||
flexBits = ivLen * PR_BITS_PER_BYTE; /* bytes->bits */
|
||||
/* first make sure we aren't going to overflow */
|
||||
if (flexBits < fixedBits) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
flexBits -= fixedBits;
|
||||
/* if we are generating a random number reduce the acceptable bits to
|
||||
* avoid birthday attacks */
|
||||
if (ivGen == CKG_GENERATE_RANDOM) {
|
||||
if (flexBits <= GCMIV_RANDOM_BIRTHDAY_BITS) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
/* see freebl/blapit.h for how we calculate
|
||||
* GCMIV_RANDOM_BIRTHDAY_BITS */
|
||||
flexBits -= GCMIV_RANDOM_BIRTHDAY_BITS;
|
||||
flexBits = flexBits >> 1;
|
||||
}
|
||||
if (flexBits == 0) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
/* Turn those bits into the number of IV's we can safely return */
|
||||
if (flexBits >= sizeof(gcmIv->max_count) * PR_BITS_PER_BYTE) {
|
||||
gcmIv->max_count = PR_UINT64(0xffffffffffffffff);
|
||||
} else {
|
||||
gcmIv->max_count = PR_UINT64(1) << flexBits;
|
||||
}
|
||||
}
|
||||
|
||||
/* no generate, accept the IV from the source */
|
||||
if (ivGen == CKG_NO_GENERATE) {
|
||||
gcmIv->counter = 1;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
/* make sure we haven't exceeded the number of IVs we can return
|
||||
* for this key, generator, and IV size */
|
||||
if (gcmIv->counter >= gcmIv->max_count) {
|
||||
/* use a unique error from just bad user input */
|
||||
PORT_SetError(SEC_ERROR_EXTRA_INPUT);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* build to mask to handle the first byte of the IV */
|
||||
ivOffset = fixedBits / PR_BITS_PER_BYTE;
|
||||
ivMask = 0xff >> ((8 - (fixedBits & 7)) & 7);
|
||||
ivNewCount = ivLen - ivOffset;
|
||||
|
||||
/* finally generate the IV */
|
||||
switch (ivGen) {
|
||||
case CKG_GENERATE: /* default to counter */
|
||||
case CKG_GENERATE_COUNTER:
|
||||
iv[ivOffset] = (iv[ivOffset] & ~ivMask) |
|
||||
(PORT_GET_BYTE_BE(gcmIv->counter, 0, ivNewCount) & ivMask);
|
||||
for (i = 1; i < ivNewCount; i++) {
|
||||
iv[ivOffset + i] = PORT_GET_BYTE_BE(gcmIv->counter, i, ivNewCount);
|
||||
}
|
||||
break;
|
||||
/* for TLS 1.3 */
|
||||
case CKG_GENERATE_COUNTER_XOR:
|
||||
iv[ivOffset] ^=
|
||||
(PORT_GET_BYTE_BE(gcmIv->counter, 0, ivNewCount) & ivMask);
|
||||
for (i = 1; i < ivNewCount; i++) {
|
||||
iv[ivOffset + i] ^= PORT_GET_BYTE_BE(gcmIv->counter, i, ivNewCount);
|
||||
}
|
||||
break;
|
||||
case CKG_GENERATE_RANDOM:
|
||||
ivSave = iv[ivOffset] & ~ivMask;
|
||||
rv = RNG_GenerateGlobalRandomBytes(iv + ivOffset, ivNewCount);
|
||||
iv[ivOffset] = ivSave | (iv[ivOffset] & ivMask);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
}
|
||||
break;
|
||||
}
|
||||
gcmIv->counter++;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
GCM_EncryptAEAD(GCMContext *gcm, unsigned char *outbuf,
|
||||
unsigned int *outlen, unsigned int maxout,
|
||||
const unsigned char *inbuf, unsigned int inlen,
|
||||
void *params, unsigned int paramLen,
|
||||
const unsigned char *aad, unsigned int aadLen,
|
||||
unsigned int blocksize)
|
||||
{
|
||||
SECStatus rv;
|
||||
unsigned int tagBytes;
|
||||
unsigned int len;
|
||||
const CK_GCM_MESSAGE_PARAMS *gcmParams =
|
||||
(const CK_GCM_MESSAGE_PARAMS *)params;
|
||||
|
||||
PORT_Assert(blocksize == AES_BLOCK_SIZE);
|
||||
if (blocksize != AES_BLOCK_SIZE) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* paramLen comes all the way from the application layer, make sure
|
||||
* it's correct */
|
||||
if (paramLen != sizeof(CK_GCM_MESSAGE_PARAMS)) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
/* if we were initialized with the C_EncryptInit, we shouldn't be in this
|
||||
* function */
|
||||
if (gcm->ctr_context_init) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (maxout < inlen) {
|
||||
*outlen = inlen;
|
||||
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
rv = gcm_GenerateIV(&gcm->gcm_iv, gcmParams->pIv, gcmParams->ulIvLen,
|
||||
gcmParams->ulIvFixedBits, gcmParams->ivGenerator);
|
||||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
rv = gcm_InitCounter(gcm, gcmParams->pIv, gcmParams->ulIvLen,
|
||||
gcmParams->ulTagBits, aad, aadLen);
|
||||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE;
|
||||
|
||||
rv = CTR_Update(&gcm->ctr_context, outbuf, outlen, maxout,
|
||||
inbuf, inlen, AES_BLOCK_SIZE);
|
||||
CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
|
||||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
}
|
||||
rv = gcmHash_Update(gcm->ghash_context, outbuf, *outlen);
|
||||
if (rv != SECSuccess) {
|
||||
PORT_Memset(outbuf, 0, *outlen); /* clear the output buffer */
|
||||
*outlen = 0;
|
||||
return SECFailure;
|
||||
}
|
||||
rv = gcm_GetTag(gcm, gcmParams->pTag, &len, tagBytes);
|
||||
if (rv != SECSuccess) {
|
||||
PORT_Memset(outbuf, 0, *outlen); /* clear the output buffer */
|
||||
*outlen = 0;
|
||||
return SECFailure;
|
||||
};
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
GCM_DecryptAEAD(GCMContext *gcm, unsigned char *outbuf,
|
||||
unsigned int *outlen, unsigned int maxout,
|
||||
const unsigned char *inbuf, unsigned int inlen,
|
||||
void *params, unsigned int paramLen,
|
||||
const unsigned char *aad, unsigned int aadLen,
|
||||
unsigned int blocksize)
|
||||
{
|
||||
SECStatus rv;
|
||||
unsigned int tagBytes;
|
||||
unsigned char tag[MAX_BLOCK_SIZE];
|
||||
const unsigned char *intag;
|
||||
unsigned int len;
|
||||
const CK_GCM_MESSAGE_PARAMS *gcmParams =
|
||||
(const CK_GCM_MESSAGE_PARAMS *)params;
|
||||
|
||||
PORT_Assert(blocksize == AES_BLOCK_SIZE);
|
||||
if (blocksize != AES_BLOCK_SIZE) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* paramLen comes all the way from the application layer, make sure
|
||||
* it's correct */
|
||||
if (paramLen != sizeof(CK_GCM_MESSAGE_PARAMS)) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
/* if we were initialized with the C_DecryptInit, we shouldn't be in this
|
||||
* function */
|
||||
if (gcm->ctr_context_init) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (maxout < inlen) {
|
||||
*outlen = inlen;
|
||||
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
rv = gcm_InitCounter(gcm, gcmParams->pIv, gcmParams->ulIvLen,
|
||||
gcmParams->ulTagBits, aad, aadLen);
|
||||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE;
|
||||
intag = gcmParams->pTag;
|
||||
PORT_Assert(tagBytes != 0);
|
||||
|
||||
/* verify the block */
|
||||
rv = gcmHash_Update(gcm->ghash_context, inbuf, inlen);
|
||||
if (rv != SECSuccess) {
|
||||
CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
|
||||
return SECFailure;
|
||||
}
|
||||
rv = gcm_GetTag(gcm, tag, &len, AES_BLOCK_SIZE);
|
||||
if (rv != SECSuccess) {
|
||||
CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
|
||||
return SECFailure;
|
||||
}
|
||||
/* Don't decrypt if we can't authenticate the encrypted data!
|
||||
* This assumes that if tagBits is may not be a multiple of 8, intag will
|
||||
* preserve the masked off missing bits. */
|
||||
if (NSS_SecureMemcmp(tag, intag, tagBytes) != 0) {
|
||||
/* force a CKR_ENCRYPTED_DATA_INVALID error at in softoken */
|
||||
CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
|
||||
PORT_SetError(SEC_ERROR_BAD_DATA);
|
||||
PORT_Memset(tag, 0, sizeof(tag));
|
||||
return SECFailure;
|
||||
}
|
||||
PORT_Memset(tag, 0, sizeof(tag));
|
||||
/* finish the decryption */
|
||||
rv = CTR_Update(&gcm->ctr_context, outbuf, outlen, maxout,
|
||||
inbuf, inlen, AES_BLOCK_SIZE);
|
||||
CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
|
||||
return rv;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#define GCM_H 1
|
||||
|
||||
#include "blapii.h"
|
||||
#include "pkcs11t.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef NSS_X86_OR_X64
|
||||
|
|
@ -30,26 +31,8 @@
|
|||
#include <arm_neon.h>
|
||||
#endif
|
||||
|
||||
#ifdef __powerpc64__
|
||||
#include "altivec-types.h"
|
||||
|
||||
/* The ghash freebl test tries to use this in C++, and gcc defines conflict. */
|
||||
#ifdef __cplusplus
|
||||
#undef pixel
|
||||
#undef vector
|
||||
#undef bool
|
||||
#endif
|
||||
|
||||
/*
|
||||
* PPC CRYPTO requires at least gcc 5 or clang. The LE check is purely
|
||||
* because it's only been tested on LE. If you're interested in BE,
|
||||
* please send a patch.
|
||||
*/
|
||||
#if (defined(__clang__) || (defined(__GNUC__) && __GNUC__ >= 5)) && \
|
||||
defined(IS_LITTLE_ENDIAN)
|
||||
#define USE_PPC_CRYPTO
|
||||
#endif
|
||||
|
||||
#if defined(__powerpc64__)
|
||||
#include "ppc-crypto.h"
|
||||
#endif
|
||||
|
||||
SEC_BEGIN_PROTOS
|
||||
|
|
@ -78,6 +61,18 @@ SECStatus GCM_DecryptUpdate(GCMContext *gcm, unsigned char *outbuf,
|
|||
unsigned int *outlen, unsigned int maxout,
|
||||
const unsigned char *inbuf, unsigned int inlen,
|
||||
unsigned int blocksize);
|
||||
SECStatus GCM_EncryptAEAD(GCMContext *gcm, unsigned char *outbuf,
|
||||
unsigned int *outlen, unsigned int maxout,
|
||||
const unsigned char *inbuf, unsigned int inlen,
|
||||
void *params, unsigned int paramLen,
|
||||
const unsigned char *aad, unsigned int aadLen,
|
||||
unsigned int blocksize);
|
||||
SECStatus GCM_DecryptAEAD(GCMContext *gcm, unsigned char *outbuf,
|
||||
unsigned int *outlen, unsigned int maxout,
|
||||
const unsigned char *inbuf, unsigned int inlen,
|
||||
void *params, unsigned int paramLen,
|
||||
const unsigned char *aad, unsigned int aadLen,
|
||||
unsigned int blocksize);
|
||||
|
||||
/* These functions are here only so we can test them */
|
||||
#define GCM_HASH_LEN_LEN 8 /* gcm hash defines lengths to be 64 bits */
|
||||
|
|
@ -102,6 +97,15 @@ pre_align struct gcmHashContextStr {
|
|||
gcmHashContext *mem;
|
||||
} post_align;
|
||||
|
||||
typedef struct gcmIVContextStr gcmIVContext;
|
||||
struct gcmIVContextStr {
|
||||
PRUint64 counter;
|
||||
PRUint64 max_count;
|
||||
CK_GENERATOR_FUNCTION ivGen;
|
||||
unsigned int fixedBits;
|
||||
unsigned int ivLen;
|
||||
};
|
||||
|
||||
SECStatus gcmHash_Update(gcmHashContext *ghash, const unsigned char *buf,
|
||||
unsigned int len);
|
||||
SECStatus gcmHash_InitContext(gcmHashContext *ghash, const unsigned char *H,
|
||||
|
|
@ -111,6 +115,11 @@ SECStatus gcmHash_Reset(gcmHashContext *ghash, const unsigned char *AAD,
|
|||
SECStatus gcmHash_Final(gcmHashContext *ghash, unsigned char *outbuf,
|
||||
unsigned int *outlen, unsigned int maxout);
|
||||
|
||||
void gcm_InitIVContext(gcmIVContext *gcmiv);
|
||||
SECStatus gcm_GenerateIV(gcmIVContext *gcmIv, unsigned char *iv,
|
||||
unsigned int ivLen, unsigned int fixedBits,
|
||||
CK_GENERATOR_FUNCTION ivGen);
|
||||
|
||||
SEC_END_PROTOS
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -16,34 +16,19 @@
|
|||
* field. (SHA-384/512 have 128-bit length.) */
|
||||
#define MAX_HASH_BIT_COUNT_BYTES 16
|
||||
|
||||
/* Some utility functions are needed:
|
||||
*
|
||||
* These macros return the given value with the MSB copied to all the other
|
||||
* bits. They use the fact that an arithmetic shift shifts-in the sign bit.
|
||||
* However, this is not ensured by the C standard so you may need to replace
|
||||
* them with something else on odd CPUs.
|
||||
*
|
||||
* Note: the argument to these macros must be an unsigned int.
|
||||
* */
|
||||
#define DUPLICATE_MSB_TO_ALL(x) ((unsigned int)((int)(x) >> (sizeof(int) * 8 - 1)))
|
||||
#define DUPLICATE_MSB_TO_ALL_8(x) ((unsigned char)(DUPLICATE_MSB_TO_ALL(x)))
|
||||
|
||||
/* constantTimeGE returns 0xff if a>=b and 0x00 otherwise, where a, b <
|
||||
* MAX_UINT/2. */
|
||||
static unsigned char
|
||||
constantTimeGE(unsigned int a, unsigned int b)
|
||||
{
|
||||
a -= b;
|
||||
return DUPLICATE_MSB_TO_ALL(~a);
|
||||
return PORT_CT_GE(a, b);
|
||||
}
|
||||
|
||||
/* constantTimeEQ8 returns 0xff if a==b and 0x00 otherwise. */
|
||||
static unsigned char
|
||||
constantTimeEQ8(unsigned char a, unsigned char b)
|
||||
constantTimeEQ(unsigned char a, unsigned char b)
|
||||
{
|
||||
unsigned int c = a ^ b;
|
||||
c--;
|
||||
return DUPLICATE_MSB_TO_ALL_8(c);
|
||||
return PORT_CT_EQ(a, b);
|
||||
}
|
||||
|
||||
/* MAC performs a constant time SSLv3/TLS MAC of |dataLen| bytes of |data|,
|
||||
|
|
@ -223,8 +208,8 @@ MAC(unsigned char *mdOut,
|
|||
* constant time, to |macOut|. */
|
||||
for (i = numStartingBlocks; i <= numStartingBlocks + varianceBlocks; i++) {
|
||||
unsigned char block[HASH_BLOCK_LENGTH_MAX];
|
||||
unsigned char isBlockA = constantTimeEQ8(i, indexA);
|
||||
unsigned char isBlockB = constantTimeEQ8(i, indexB);
|
||||
unsigned char isBlockA = constantTimeEQ(i, indexA);
|
||||
unsigned char isBlockB = constantTimeEQ(i, indexB);
|
||||
for (j = 0; j < mdBlockSize; j++) {
|
||||
unsigned char isPastC = isBlockA & constantTimeGE(j, c);
|
||||
unsigned char isPastCPlus1 = isBlockA & constantTimeGE(j, c + 1);
|
||||
|
|
@ -289,6 +274,11 @@ MAC(unsigned char *mdOut,
|
|||
hashObj->end(mdState, mdOut, mdOutLen, mdOutMax);
|
||||
hashObj->destroy(mdState, PR_TRUE);
|
||||
|
||||
PORT_Memset(lengthBytes, 0, sizeof lengthBytes);
|
||||
PORT_Memset(hmacPad, 0, sizeof hmacPad);
|
||||
PORT_Memset(firstBlock, 0, sizeof firstBlock);
|
||||
PORT_Memset(macOut, 0, sizeof macOut);
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,8 +36,16 @@ struct intel_AES_GCMContextStr {
|
|||
unsigned long tagBits;
|
||||
unsigned long Alen;
|
||||
unsigned long Mlen;
|
||||
freeblCipherFunc cipher;
|
||||
PRBool ctr_context_init;
|
||||
gcmIVContext gcm_iv;
|
||||
};
|
||||
|
||||
SECStatus intel_aes_gcmInitCounter(intel_AES_GCMContext *gcm,
|
||||
const unsigned char *iv,
|
||||
unsigned long ivLen, unsigned long tagBits,
|
||||
const unsigned char *aad, unsigned long aadLen);
|
||||
|
||||
intel_AES_GCMContext *
|
||||
intel_AES_GCM_CreateContext(void *context,
|
||||
freeblCipherFunc cipher,
|
||||
|
|
@ -45,38 +53,9 @@ intel_AES_GCM_CreateContext(void *context,
|
|||
{
|
||||
intel_AES_GCMContext *gcm = NULL;
|
||||
AESContext *aes = (AESContext *)context;
|
||||
const CK_GCM_PARAMS *gcmParams = (const CK_GCM_PARAMS *)params;
|
||||
unsigned char buff[AES_BLOCK_SIZE]; /* aux buffer */
|
||||
|
||||
unsigned long IV_whole_len = gcmParams->ulIvLen & (~0xful);
|
||||
unsigned int IV_remainder_len = gcmParams->ulIvLen & 0xful;
|
||||
unsigned long AAD_whole_len = gcmParams->ulAADLen & (~0xful);
|
||||
unsigned int AAD_remainder_len = gcmParams->ulAADLen & 0xful;
|
||||
|
||||
__m128i BSWAP_MASK = _mm_setr_epi8(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
|
||||
__m128i ONE = _mm_set_epi32(0, 0, 0, 1);
|
||||
unsigned int j;
|
||||
const CK_NSS_GCM_PARAMS *gcmParams = (const CK_NSS_GCM_PARAMS *)params;
|
||||
SECStatus rv;
|
||||
|
||||
if (gcmParams->ulIvLen == 0) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (gcmParams->ulTagBits != 128 && gcmParams->ulTagBits != 120 &&
|
||||
gcmParams->ulTagBits != 112 && gcmParams->ulTagBits != 104 &&
|
||||
gcmParams->ulTagBits != 96 && gcmParams->ulTagBits != 64 &&
|
||||
gcmParams->ulTagBits != 32) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Limit AADLen in accordance with SP800-38D
|
||||
if (sizeof(AAD_whole_len) >= 8 && AAD_whole_len > (1ULL << 61) - 1) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gcm = PORT_ZNew(intel_AES_GCMContext);
|
||||
if (gcm == NULL) {
|
||||
return NULL;
|
||||
|
|
@ -84,40 +63,102 @@ intel_AES_GCM_CreateContext(void *context,
|
|||
|
||||
/* initialize context fields */
|
||||
gcm->aes_context = aes;
|
||||
gcm->tagBits = gcmParams->ulTagBits;
|
||||
gcm->cipher = cipher;
|
||||
gcm->Alen = 0;
|
||||
gcm->Mlen = 0;
|
||||
gcm->ctr_context_init = PR_FALSE;
|
||||
|
||||
/* first prepare H and its derivatives for ghash */
|
||||
intel_aes_gcmINIT(gcm->Htbl, (unsigned char *)aes->k.expandedKey, aes->Nr);
|
||||
|
||||
gcm_InitIVContext(&gcm->gcm_iv);
|
||||
|
||||
/* if gcmParams is NULL, then we are creating an PKCS #11 MESSAGE
|
||||
* style context, in which we initialize the key once, then do separate
|
||||
* iv/aad's for each message. If we are doing that kind of operation,
|
||||
* we've finished with init here. We'll init the Counter in each AEAD
|
||||
* call */
|
||||
if (gcmParams == NULL) {
|
||||
return gcm;
|
||||
}
|
||||
|
||||
rv = intel_aes_gcmInitCounter(gcm, gcmParams->pIv,
|
||||
gcmParams->ulIvLen, gcmParams->ulTagBits,
|
||||
gcmParams->pAAD, gcmParams->ulAADLen);
|
||||
if (rv != SECSuccess) {
|
||||
PORT_Free(gcm);
|
||||
return NULL;
|
||||
}
|
||||
gcm->ctr_context_init = PR_TRUE;
|
||||
|
||||
return gcm;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
intel_aes_gcmInitCounter(intel_AES_GCMContext *gcm,
|
||||
const unsigned char *iv, unsigned long ivLen,
|
||||
unsigned long tagBits,
|
||||
const unsigned char *aad, unsigned long aadLen)
|
||||
{
|
||||
unsigned char buff[AES_BLOCK_SIZE]; /* aux buffer */
|
||||
unsigned long IV_whole_len = ivLen & (~0xful);
|
||||
unsigned int IV_remainder_len = ivLen & 0xful;
|
||||
unsigned long AAD_whole_len = aadLen & (~0xful);
|
||||
unsigned int AAD_remainder_len = aadLen & 0xful;
|
||||
unsigned int j;
|
||||
__m128i BSWAP_MASK = _mm_setr_epi8(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
|
||||
__m128i ONE = _mm_set_epi32(0, 0, 0, 1);
|
||||
SECStatus rv;
|
||||
|
||||
if (ivLen == 0) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (tagBits != 128 && tagBits != 120 && tagBits != 112 &&
|
||||
tagBits != 104 && tagBits != 96 && tagBits != 64 &&
|
||||
tagBits != 32) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
gcm->tagBits = tagBits;
|
||||
|
||||
/* reset the aad and message length counters */
|
||||
gcm->Alen = 0;
|
||||
gcm->Mlen = 0;
|
||||
|
||||
// Limit AADLen in accordance with SP800-38D
|
||||
if (sizeof(AAD_whole_len) >= 8 && AAD_whole_len > (1ULL << 61) - 1) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
/* Initial TAG value is zero */
|
||||
_mm_storeu_si128((__m128i *)gcm->T, _mm_setzero_si128());
|
||||
_mm_storeu_si128((__m128i *)gcm->X0, _mm_setzero_si128());
|
||||
|
||||
/* Init the counter */
|
||||
if (gcmParams->ulIvLen == 12) {
|
||||
if (ivLen == 12) {
|
||||
_mm_storeu_si128((__m128i *)gcm->CTR,
|
||||
_mm_setr_epi32(((unsigned int *)gcmParams->pIv)[0],
|
||||
((unsigned int *)gcmParams->pIv)[1],
|
||||
((unsigned int *)gcmParams->pIv)[2],
|
||||
_mm_setr_epi32(((unsigned int *)iv)[0],
|
||||
((unsigned int *)iv)[1],
|
||||
((unsigned int *)iv)[2],
|
||||
0x01000000));
|
||||
} else {
|
||||
/* If IV size is not 96 bits, then the initial counter value is GHASH
|
||||
* of the IV */
|
||||
intel_aes_gcmAAD(gcm->Htbl, gcmParams->pIv, IV_whole_len, gcm->T);
|
||||
intel_aes_gcmAAD(gcm->Htbl, (unsigned char *)iv, IV_whole_len, gcm->T);
|
||||
|
||||
/* Partial block */
|
||||
if (IV_remainder_len) {
|
||||
PORT_Memset(buff, 0, AES_BLOCK_SIZE);
|
||||
PORT_Memcpy(buff, gcmParams->pIv + IV_whole_len, IV_remainder_len);
|
||||
PORT_Memcpy(buff, iv + IV_whole_len, IV_remainder_len);
|
||||
intel_aes_gcmAAD(gcm->Htbl, buff, AES_BLOCK_SIZE, gcm->T);
|
||||
}
|
||||
|
||||
intel_aes_gcmTAG(
|
||||
gcm->Htbl,
|
||||
gcm->T,
|
||||
gcmParams->ulIvLen,
|
||||
ivLen,
|
||||
0,
|
||||
gcm->X0,
|
||||
gcm->CTR);
|
||||
|
|
@ -128,10 +169,10 @@ intel_AES_GCM_CreateContext(void *context,
|
|||
|
||||
/* Encrypt the initial counter, will be used to encrypt the GHASH value,
|
||||
* in the end */
|
||||
rv = (*cipher)(context, gcm->X0, &j, AES_BLOCK_SIZE, gcm->CTR,
|
||||
AES_BLOCK_SIZE, AES_BLOCK_SIZE);
|
||||
rv = (*gcm->cipher)(gcm->aes_context, gcm->X0, &j, AES_BLOCK_SIZE, gcm->CTR,
|
||||
AES_BLOCK_SIZE, AES_BLOCK_SIZE);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* Promote the counter by 1 */
|
||||
|
|
@ -141,18 +182,14 @@ intel_AES_GCM_CreateContext(void *context,
|
|||
* creation from the AAD, because that would allow to reuse the H, which
|
||||
* only changes when the AES key changes, and not every package, like the
|
||||
* IV and AAD */
|
||||
intel_aes_gcmAAD(gcm->Htbl, gcmParams->pAAD, AAD_whole_len, gcm->T);
|
||||
intel_aes_gcmAAD(gcm->Htbl, (unsigned char *)aad, AAD_whole_len, gcm->T);
|
||||
if (AAD_remainder_len) {
|
||||
PORT_Memset(buff, 0, AES_BLOCK_SIZE);
|
||||
PORT_Memcpy(buff, gcmParams->pAAD + AAD_whole_len, AAD_remainder_len);
|
||||
PORT_Memcpy(buff, aad + AAD_whole_len, AAD_remainder_len);
|
||||
intel_aes_gcmAAD(gcm->Htbl, buff, AES_BLOCK_SIZE, gcm->T);
|
||||
}
|
||||
gcm->Alen += gcmParams->ulAADLen;
|
||||
return gcm;
|
||||
|
||||
loser:
|
||||
PORT_Free(gcm);
|
||||
return NULL;
|
||||
gcm->Alen += aadLen;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -177,9 +214,16 @@ intel_AES_GCM_EncryptUpdate(intel_AES_GCMContext *gcm,
|
|||
|
||||
// GCM has a 16 octet block, with a 32-bit block counter
|
||||
// Limit in accordance with SP800-38D
|
||||
if (sizeof(inlen) > 4 &&
|
||||
inlen >= ((1ULL << 32) - 2) * AES_BLOCK_SIZE) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
if (sizeof(inlen) > 4) {
|
||||
unsigned long long inlen_ull = inlen;
|
||||
if (inlen_ull >= ((1ULL << 32) - 2) * AES_BLOCK_SIZE) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
}
|
||||
|
||||
if (!gcm->ctr_context_init) {
|
||||
PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
|
|
@ -229,6 +273,11 @@ intel_AES_GCM_DecryptUpdate(intel_AES_GCMContext *gcm,
|
|||
unsigned char T[AES_BLOCK_SIZE];
|
||||
const unsigned char *intag;
|
||||
|
||||
if (!gcm->ctr_context_init) {
|
||||
PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE;
|
||||
|
||||
/* get the authentication block */
|
||||
|
|
@ -242,10 +291,12 @@ intel_AES_GCM_DecryptUpdate(intel_AES_GCMContext *gcm,
|
|||
|
||||
// GCM has a 16 octet block, with a 32-bit block counter
|
||||
// Limit in accordance with SP800-38D
|
||||
if (sizeof(inlen) > 4 &&
|
||||
inlen >= ((1ULL << 32) - 2) * AES_BLOCK_SIZE) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
if (sizeof(inlen) > 4) {
|
||||
unsigned long long inlen_ull = inlen;
|
||||
if (inlen_ull >= ((1ULL << 32) - 2) * AES_BLOCK_SIZE) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
}
|
||||
|
||||
if (maxout < inlen) {
|
||||
|
|
@ -281,4 +332,144 @@ intel_AES_GCM_DecryptUpdate(intel_AES_GCMContext *gcm,
|
|||
return SECSuccess;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
intel_AES_GCM_EncryptAEAD(intel_AES_GCMContext *gcm,
|
||||
unsigned char *outbuf,
|
||||
unsigned int *outlen, unsigned int maxout,
|
||||
const unsigned char *inbuf, unsigned int inlen,
|
||||
void *params, unsigned int paramLen,
|
||||
const unsigned char *aad, unsigned int aadLen,
|
||||
unsigned int blocksize)
|
||||
{
|
||||
unsigned int tagBytes;
|
||||
unsigned char T[AES_BLOCK_SIZE];
|
||||
const CK_GCM_MESSAGE_PARAMS *gcmParams =
|
||||
(const CK_GCM_MESSAGE_PARAMS *)params;
|
||||
SECStatus rv;
|
||||
|
||||
// GCM has a 16 octet block, with a 32-bit block counter
|
||||
// Limit in accordance with SP800-38D
|
||||
if (sizeof(inlen) > 4) {
|
||||
unsigned long long inlen_ull = inlen;
|
||||
if (inlen_ull >= ((1ULL << 32) - 2) * AES_BLOCK_SIZE) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
}
|
||||
/* paramLen comes all the way from the application layer, make sure
|
||||
* it's correct */
|
||||
if (paramLen != sizeof(CK_GCM_MESSAGE_PARAMS)) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* if we were initialized with the C_EncryptInit, we shouldn't be in this
|
||||
* function */
|
||||
if (gcm->ctr_context_init) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (maxout < inlen) {
|
||||
*outlen = inlen;
|
||||
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
rv = gcm_GenerateIV(&gcm->gcm_iv, gcmParams->pIv, gcmParams->ulIvLen,
|
||||
gcmParams->ulIvFixedBits, gcmParams->ivGenerator);
|
||||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
rv = intel_aes_gcmInitCounter(gcm, gcmParams->pIv, gcmParams->ulIvLen,
|
||||
gcmParams->ulTagBits, aad, aadLen);
|
||||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE;
|
||||
|
||||
intel_aes_gcmENC(inbuf, outbuf, gcm, inlen);
|
||||
|
||||
gcm->Mlen += inlen;
|
||||
|
||||
intel_aes_gcmTAG(gcm->Htbl, gcm->T, gcm->Mlen, gcm->Alen, gcm->X0, T);
|
||||
|
||||
*outlen = inlen;
|
||||
PORT_Memcpy(gcmParams->pTag, T, tagBytes);
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
intel_AES_GCM_DecryptAEAD(intel_AES_GCMContext *gcm,
|
||||
unsigned char *outbuf,
|
||||
unsigned int *outlen, unsigned int maxout,
|
||||
const unsigned char *inbuf, unsigned int inlen,
|
||||
void *params, unsigned int paramLen,
|
||||
const unsigned char *aad, unsigned int aadLen,
|
||||
unsigned int blocksize)
|
||||
{
|
||||
unsigned int tagBytes;
|
||||
unsigned char T[AES_BLOCK_SIZE];
|
||||
const unsigned char *intag;
|
||||
const CK_GCM_MESSAGE_PARAMS *gcmParams =
|
||||
(const CK_GCM_MESSAGE_PARAMS *)params;
|
||||
SECStatus rv;
|
||||
|
||||
/* paramLen comes all the way from the application layer, make sure
|
||||
* it's correct */
|
||||
if (paramLen != sizeof(CK_GCM_MESSAGE_PARAMS)) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
/* if we were initialized with the C_DecryptInit, we shouldn't be in this
|
||||
* function */
|
||||
if (gcm->ctr_context_init) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
// GCM has a 16 octet block, with a 32-bit block counter
|
||||
// Limit in accordance with SP800-38D
|
||||
if (sizeof(inlen) > 4) {
|
||||
unsigned long long inlen_ull = inlen;
|
||||
if (inlen_ull >= ((1ULL << 32) - 2) * AES_BLOCK_SIZE) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
}
|
||||
|
||||
if (maxout < inlen) {
|
||||
*outlen = inlen;
|
||||
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
rv = intel_aes_gcmInitCounter(gcm, gcmParams->pIv, gcmParams->ulIvLen,
|
||||
gcmParams->ulTagBits, aad, aadLen);
|
||||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE;
|
||||
intag = gcmParams->pTag;
|
||||
PORT_Assert(tagBytes != 0);
|
||||
|
||||
intel_aes_gcmDEC(inbuf, outbuf, gcm, inlen);
|
||||
|
||||
gcm->Mlen += inlen;
|
||||
intel_aes_gcmTAG(gcm->Htbl, gcm->T, gcm->Mlen, gcm->Alen, gcm->X0, T);
|
||||
|
||||
if (NSS_SecureMemcmp(T, intag, tagBytes) != 0) {
|
||||
memset(outbuf, 0, inlen);
|
||||
*outlen = 0;
|
||||
/* force a CKR_ENCRYPTED_DATA_INVALID error at in softoken */
|
||||
PORT_SetError(SEC_ERROR_BAD_DATA);
|
||||
return SECFailure;
|
||||
}
|
||||
*outlen = inlen;
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -40,6 +40,20 @@ SECStatus intel_AES_GCM_DecryptUpdate(intel_AES_GCMContext *gcm, unsigned char *
|
|||
unsigned int *outlen, unsigned int maxout,
|
||||
const unsigned char *inbuf, unsigned int inlen,
|
||||
unsigned int blocksize);
|
||||
SECStatus intel_AES_GCM_EncryptAEAD(intel_AES_GCMContext *gcm,
|
||||
unsigned char *outbuf,
|
||||
unsigned int *outlen, unsigned int maxout,
|
||||
const unsigned char *inbuf, unsigned int inlen,
|
||||
void *params, unsigned int paramLen,
|
||||
const unsigned char *aad, unsigned int aadLen,
|
||||
unsigned int blocksize);
|
||||
SECStatus intel_AES_GCM_DecryptAEAD(intel_AES_GCMContext *gcm,
|
||||
unsigned char *outbuf,
|
||||
unsigned int *outlen, unsigned int maxout,
|
||||
const unsigned char *inbuf, unsigned int inlen,
|
||||
void *params, unsigned int paramLen,
|
||||
const unsigned char *aad, unsigned int aadLen,
|
||||
unsigned int blocksize);
|
||||
|
||||
/* Prototypes of functions in the assembler file for fast AES-GCM, using
|
||||
Intel AES-NI and CLMUL-NI, as described in [1]
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifdef FREEBL_NO_DEPEND
|
||||
#include "stubs.h"
|
||||
extern int FREEBL_InitStubs(void);
|
||||
#endif
|
||||
|
||||
|
|
@ -14,323 +15,370 @@ extern int FREEBL_InitStubs(void);
|
|||
#include "alghmac.h"
|
||||
#include "hmacct.h"
|
||||
#include "blapii.h"
|
||||
#include "secerr.h"
|
||||
|
||||
static const struct FREEBLVectorStr vector =
|
||||
{
|
||||
SECStatus
|
||||
FREEBL_Deprecated(void)
|
||||
{
|
||||
|
||||
sizeof vector,
|
||||
FREEBL_VERSION,
|
||||
PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
RSA_NewKey,
|
||||
RSA_PublicKeyOp,
|
||||
RSA_PrivateKeyOp,
|
||||
DSA_NewKey,
|
||||
DSA_SignDigest,
|
||||
DSA_VerifyDigest,
|
||||
DSA_NewKeyFromSeed,
|
||||
DSA_SignDigestWithSeed,
|
||||
DH_GenParam,
|
||||
DH_NewKey,
|
||||
DH_Derive,
|
||||
KEA_Derive,
|
||||
KEA_Verify,
|
||||
RC4_CreateContext,
|
||||
RC4_DestroyContext,
|
||||
RC4_Encrypt,
|
||||
RC4_Decrypt,
|
||||
RC2_CreateContext,
|
||||
RC2_DestroyContext,
|
||||
RC2_Encrypt,
|
||||
RC2_Decrypt,
|
||||
RC5_CreateContext,
|
||||
RC5_DestroyContext,
|
||||
RC5_Encrypt,
|
||||
RC5_Decrypt,
|
||||
DES_CreateContext,
|
||||
DES_DestroyContext,
|
||||
DES_Encrypt,
|
||||
DES_Decrypt,
|
||||
AES_CreateContext,
|
||||
AES_DestroyContext,
|
||||
AES_Encrypt,
|
||||
AES_Decrypt,
|
||||
MD5_Hash,
|
||||
MD5_HashBuf,
|
||||
MD5_NewContext,
|
||||
MD5_DestroyContext,
|
||||
MD5_Begin,
|
||||
MD5_Update,
|
||||
MD5_End,
|
||||
MD5_FlattenSize,
|
||||
MD5_Flatten,
|
||||
MD5_Resurrect,
|
||||
MD5_TraceState,
|
||||
MD2_Hash,
|
||||
MD2_NewContext,
|
||||
MD2_DestroyContext,
|
||||
MD2_Begin,
|
||||
MD2_Update,
|
||||
MD2_End,
|
||||
MD2_FlattenSize,
|
||||
MD2_Flatten,
|
||||
MD2_Resurrect,
|
||||
SHA1_Hash,
|
||||
SHA1_HashBuf,
|
||||
SHA1_NewContext,
|
||||
SHA1_DestroyContext,
|
||||
SHA1_Begin,
|
||||
SHA1_Update,
|
||||
SHA1_End,
|
||||
SHA1_TraceState,
|
||||
SHA1_FlattenSize,
|
||||
SHA1_Flatten,
|
||||
SHA1_Resurrect,
|
||||
RNG_RNGInit,
|
||||
RNG_RandomUpdate,
|
||||
RNG_GenerateGlobalRandomBytes,
|
||||
RNG_RNGShutdown,
|
||||
PQG_ParamGen,
|
||||
PQG_ParamGenSeedLen,
|
||||
PQG_VerifyParams,
|
||||
static const struct FREEBLVectorStr vector = {
|
||||
|
||||
/* End of Version 3.001. */
|
||||
sizeof vector,
|
||||
FREEBL_VERSION,
|
||||
|
||||
RSA_PrivateKeyOpDoubleChecked,
|
||||
RSA_PrivateKeyCheck,
|
||||
BL_Cleanup,
|
||||
RSA_NewKey,
|
||||
RSA_PublicKeyOp,
|
||||
RSA_PrivateKeyOp,
|
||||
DSA_NewKey,
|
||||
DSA_SignDigest,
|
||||
DSA_VerifyDigest,
|
||||
DSA_NewKeyFromSeed,
|
||||
DSA_SignDigestWithSeed,
|
||||
DH_GenParam,
|
||||
DH_NewKey,
|
||||
DH_Derive,
|
||||
KEA_Derive,
|
||||
KEA_Verify,
|
||||
RC4_CreateContext,
|
||||
RC4_DestroyContext,
|
||||
RC4_Encrypt,
|
||||
RC4_Decrypt,
|
||||
#ifndef NSS_DISABLE_DEPRECATED_RC2
|
||||
RC2_CreateContext,
|
||||
RC2_DestroyContext,
|
||||
RC2_Encrypt,
|
||||
RC2_Decrypt,
|
||||
#else
|
||||
(F_RC2_CreateContext)FREEBL_Deprecated,
|
||||
(F_RC2_DestroyContext)FREEBL_Deprecated,
|
||||
(F_RC2_Encrypt)FREEBL_Deprecated,
|
||||
(F_RC2_Decrypt)FREEBL_Deprecated,
|
||||
#endif
|
||||
RC5_CreateContext,
|
||||
RC5_DestroyContext,
|
||||
RC5_Encrypt,
|
||||
RC5_Decrypt,
|
||||
DES_CreateContext,
|
||||
DES_DestroyContext,
|
||||
DES_Encrypt,
|
||||
DES_Decrypt,
|
||||
AES_CreateContext,
|
||||
AES_DestroyContext,
|
||||
AES_Encrypt,
|
||||
AES_Decrypt,
|
||||
MD5_Hash,
|
||||
MD5_HashBuf,
|
||||
MD5_NewContext,
|
||||
MD5_DestroyContext,
|
||||
MD5_Begin,
|
||||
MD5_Update,
|
||||
MD5_End,
|
||||
MD5_FlattenSize,
|
||||
MD5_Flatten,
|
||||
MD5_Resurrect,
|
||||
MD5_TraceState,
|
||||
MD2_Hash,
|
||||
MD2_NewContext,
|
||||
MD2_DestroyContext,
|
||||
MD2_Begin,
|
||||
MD2_Update,
|
||||
MD2_End,
|
||||
MD2_FlattenSize,
|
||||
MD2_Flatten,
|
||||
MD2_Resurrect,
|
||||
SHA1_Hash,
|
||||
SHA1_HashBuf,
|
||||
SHA1_NewContext,
|
||||
SHA1_DestroyContext,
|
||||
SHA1_Begin,
|
||||
SHA1_Update,
|
||||
SHA1_End,
|
||||
SHA1_TraceState,
|
||||
SHA1_FlattenSize,
|
||||
SHA1_Flatten,
|
||||
SHA1_Resurrect,
|
||||
RNG_RNGInit,
|
||||
RNG_RandomUpdate,
|
||||
RNG_GenerateGlobalRandomBytes,
|
||||
RNG_RNGShutdown,
|
||||
PQG_ParamGen,
|
||||
PQG_ParamGenSeedLen,
|
||||
PQG_VerifyParams,
|
||||
|
||||
/* End of Version 3.002. */
|
||||
/* End of Version 3.001. */
|
||||
|
||||
SHA256_NewContext,
|
||||
SHA256_DestroyContext,
|
||||
SHA256_Begin,
|
||||
SHA256_Update,
|
||||
SHA256_End,
|
||||
SHA256_HashBuf,
|
||||
SHA256_Hash,
|
||||
SHA256_TraceState,
|
||||
SHA256_FlattenSize,
|
||||
SHA256_Flatten,
|
||||
SHA256_Resurrect,
|
||||
RSA_PrivateKeyOpDoubleChecked,
|
||||
RSA_PrivateKeyCheck,
|
||||
BL_Cleanup,
|
||||
|
||||
SHA512_NewContext,
|
||||
SHA512_DestroyContext,
|
||||
SHA512_Begin,
|
||||
SHA512_Update,
|
||||
SHA512_End,
|
||||
SHA512_HashBuf,
|
||||
SHA512_Hash,
|
||||
SHA512_TraceState,
|
||||
SHA512_FlattenSize,
|
||||
SHA512_Flatten,
|
||||
SHA512_Resurrect,
|
||||
/* End of Version 3.002. */
|
||||
|
||||
SHA384_NewContext,
|
||||
SHA384_DestroyContext,
|
||||
SHA384_Begin,
|
||||
SHA384_Update,
|
||||
SHA384_End,
|
||||
SHA384_HashBuf,
|
||||
SHA384_Hash,
|
||||
SHA384_TraceState,
|
||||
SHA384_FlattenSize,
|
||||
SHA384_Flatten,
|
||||
SHA384_Resurrect,
|
||||
SHA256_NewContext,
|
||||
SHA256_DestroyContext,
|
||||
SHA256_Begin,
|
||||
SHA256_Update,
|
||||
SHA256_End,
|
||||
SHA256_HashBuf,
|
||||
SHA256_Hash,
|
||||
SHA256_TraceState,
|
||||
SHA256_FlattenSize,
|
||||
SHA256_Flatten,
|
||||
SHA256_Resurrect,
|
||||
|
||||
/* End of Version 3.003. */
|
||||
SHA512_NewContext,
|
||||
SHA512_DestroyContext,
|
||||
SHA512_Begin,
|
||||
SHA512_Update,
|
||||
SHA512_End,
|
||||
SHA512_HashBuf,
|
||||
SHA512_Hash,
|
||||
SHA512_TraceState,
|
||||
SHA512_FlattenSize,
|
||||
SHA512_Flatten,
|
||||
SHA512_Resurrect,
|
||||
|
||||
AESKeyWrap_CreateContext,
|
||||
AESKeyWrap_DestroyContext,
|
||||
AESKeyWrap_Encrypt,
|
||||
AESKeyWrap_Decrypt,
|
||||
SHA384_NewContext,
|
||||
SHA384_DestroyContext,
|
||||
SHA384_Begin,
|
||||
SHA384_Update,
|
||||
SHA384_End,
|
||||
SHA384_HashBuf,
|
||||
SHA384_Hash,
|
||||
SHA384_TraceState,
|
||||
SHA384_FlattenSize,
|
||||
SHA384_Flatten,
|
||||
SHA384_Resurrect,
|
||||
|
||||
/* End of Version 3.004. */
|
||||
/* End of Version 3.003. */
|
||||
|
||||
BLAPI_SHVerify,
|
||||
BLAPI_VerifySelf,
|
||||
AESKeyWrap_CreateContext,
|
||||
AESKeyWrap_DestroyContext,
|
||||
AESKeyWrap_Encrypt,
|
||||
AESKeyWrap_Decrypt,
|
||||
|
||||
/* End of Version 3.005. */
|
||||
/* End of Version 3.004. */
|
||||
|
||||
EC_NewKey,
|
||||
EC_NewKeyFromSeed,
|
||||
EC_ValidatePublicKey,
|
||||
ECDH_Derive,
|
||||
ECDSA_SignDigest,
|
||||
ECDSA_VerifyDigest,
|
||||
ECDSA_SignDigestWithSeed,
|
||||
BLAPI_SHVerify,
|
||||
BLAPI_VerifySelf,
|
||||
|
||||
/* End of Version 3.006. */
|
||||
/* End of Version 3.007. */
|
||||
/* End of Version 3.005. */
|
||||
|
||||
AES_InitContext,
|
||||
AESKeyWrap_InitContext,
|
||||
DES_InitContext,
|
||||
RC2_InitContext,
|
||||
RC4_InitContext,
|
||||
EC_NewKey,
|
||||
EC_NewKeyFromSeed,
|
||||
EC_ValidatePublicKey,
|
||||
ECDH_Derive,
|
||||
ECDSA_SignDigest,
|
||||
ECDSA_VerifyDigest,
|
||||
ECDSA_SignDigestWithSeed,
|
||||
|
||||
AES_AllocateContext,
|
||||
AESKeyWrap_AllocateContext,
|
||||
DES_AllocateContext,
|
||||
RC2_AllocateContext,
|
||||
RC4_AllocateContext,
|
||||
/* End of Version 3.006. */
|
||||
/* End of Version 3.007. */
|
||||
|
||||
MD2_Clone,
|
||||
MD5_Clone,
|
||||
SHA1_Clone,
|
||||
SHA256_Clone,
|
||||
SHA384_Clone,
|
||||
SHA512_Clone,
|
||||
AES_InitContext,
|
||||
AESKeyWrap_InitContext,
|
||||
DES_InitContext,
|
||||
#ifndef NSS_DISABLE_DEPRECATED_RC2
|
||||
RC2_InitContext,
|
||||
#else
|
||||
(F_RC2_InitContext)FREEBL_Deprecated,
|
||||
#endif
|
||||
RC4_InitContext,
|
||||
|
||||
TLS_PRF,
|
||||
HASH_GetRawHashObject,
|
||||
AES_AllocateContext,
|
||||
AESKeyWrap_AllocateContext,
|
||||
DES_AllocateContext,
|
||||
#ifndef NSS_DISABLE_DEPRECATED_RC2
|
||||
RC2_AllocateContext,
|
||||
#else
|
||||
(F_RC2_AllocateContext)FREEBL_Deprecated,
|
||||
#endif
|
||||
RC4_AllocateContext,
|
||||
|
||||
HMAC_Create,
|
||||
HMAC_Init,
|
||||
HMAC_Begin,
|
||||
HMAC_Update,
|
||||
HMAC_Clone,
|
||||
HMAC_Finish,
|
||||
HMAC_Destroy,
|
||||
MD2_Clone,
|
||||
MD5_Clone,
|
||||
SHA1_Clone,
|
||||
SHA256_Clone,
|
||||
SHA384_Clone,
|
||||
SHA512_Clone,
|
||||
|
||||
RNG_SystemInfoForRNG,
|
||||
TLS_PRF,
|
||||
HASH_GetRawHashObject,
|
||||
|
||||
/* End of Version 3.008. */
|
||||
HMAC_Create,
|
||||
HMAC_Init,
|
||||
HMAC_Begin,
|
||||
HMAC_Update,
|
||||
HMAC_Clone,
|
||||
HMAC_Finish,
|
||||
HMAC_Destroy,
|
||||
|
||||
FIPS186Change_GenerateX,
|
||||
FIPS186Change_ReduceModQForDSA,
|
||||
RNG_SystemInfoForRNG,
|
||||
|
||||
/* End of Version 3.009. */
|
||||
Camellia_InitContext,
|
||||
Camellia_AllocateContext,
|
||||
Camellia_CreateContext,
|
||||
Camellia_DestroyContext,
|
||||
Camellia_Encrypt,
|
||||
Camellia_Decrypt,
|
||||
/* End of Version 3.008. */
|
||||
|
||||
PQG_DestroyParams,
|
||||
PQG_DestroyVerify,
|
||||
FIPS186Change_GenerateX,
|
||||
FIPS186Change_ReduceModQForDSA,
|
||||
|
||||
/* End of Version 3.010. */
|
||||
/* End of Version 3.009. */
|
||||
Camellia_InitContext,
|
||||
Camellia_AllocateContext,
|
||||
Camellia_CreateContext,
|
||||
Camellia_DestroyContext,
|
||||
Camellia_Encrypt,
|
||||
Camellia_Decrypt,
|
||||
|
||||
SEED_InitContext,
|
||||
SEED_AllocateContext,
|
||||
SEED_CreateContext,
|
||||
SEED_DestroyContext,
|
||||
SEED_Encrypt,
|
||||
SEED_Decrypt,
|
||||
PQG_DestroyParams,
|
||||
PQG_DestroyVerify,
|
||||
|
||||
BL_Init,
|
||||
BL_SetForkState,
|
||||
/* End of Version 3.010. */
|
||||
|
||||
PRNGTEST_Instantiate,
|
||||
PRNGTEST_Reseed,
|
||||
PRNGTEST_Generate,
|
||||
#ifndef NSS_DISABLE_DEPRECATED_SEED
|
||||
SEED_InitContext,
|
||||
SEED_AllocateContext,
|
||||
SEED_CreateContext,
|
||||
SEED_DestroyContext,
|
||||
SEED_Encrypt,
|
||||
SEED_Decrypt,
|
||||
#else
|
||||
(F_SEED_InitContext)FREEBL_Deprecated,
|
||||
(F_SEED_AllocateContext)FREEBL_Deprecated,
|
||||
(F_SEED_CreateContext)FREEBL_Deprecated,
|
||||
(F_SEED_DestroyContext)FREEBL_Deprecated,
|
||||
(F_SEED_Encrypt)FREEBL_Deprecated,
|
||||
(F_SEED_Decrypt)FREEBL_Deprecated,
|
||||
#endif /* NSS_DISABLE_DEPRECATED_SEED */
|
||||
|
||||
PRNGTEST_Uninstantiate,
|
||||
BL_Init,
|
||||
BL_SetForkState,
|
||||
|
||||
/* End of Version 3.011. */
|
||||
PRNGTEST_Instantiate,
|
||||
PRNGTEST_Reseed,
|
||||
PRNGTEST_Generate,
|
||||
|
||||
RSA_PopulatePrivateKey,
|
||||
PRNGTEST_Uninstantiate,
|
||||
|
||||
DSA_NewRandom,
|
||||
/* End of Version 3.011. */
|
||||
|
||||
JPAKE_Sign,
|
||||
JPAKE_Verify,
|
||||
JPAKE_Round2,
|
||||
JPAKE_Final,
|
||||
RSA_PopulatePrivateKey,
|
||||
|
||||
/* End of Version 3.012 */
|
||||
DSA_NewRandom,
|
||||
|
||||
TLS_P_hash,
|
||||
SHA224_NewContext,
|
||||
SHA224_DestroyContext,
|
||||
SHA224_Begin,
|
||||
SHA224_Update,
|
||||
SHA224_End,
|
||||
SHA224_HashBuf,
|
||||
SHA224_Hash,
|
||||
SHA224_TraceState,
|
||||
SHA224_FlattenSize,
|
||||
SHA224_Flatten,
|
||||
SHA224_Resurrect,
|
||||
SHA224_Clone,
|
||||
BLAPI_SHVerifyFile,
|
||||
JPAKE_Sign,
|
||||
JPAKE_Verify,
|
||||
JPAKE_Round2,
|
||||
JPAKE_Final,
|
||||
|
||||
/* End of Version 3.013 */
|
||||
/* End of Version 3.012 */
|
||||
|
||||
PQG_ParamGenV2,
|
||||
PRNGTEST_RunHealthTests,
|
||||
TLS_P_hash,
|
||||
SHA224_NewContext,
|
||||
SHA224_DestroyContext,
|
||||
SHA224_Begin,
|
||||
SHA224_Update,
|
||||
SHA224_End,
|
||||
SHA224_HashBuf,
|
||||
SHA224_Hash,
|
||||
SHA224_TraceState,
|
||||
SHA224_FlattenSize,
|
||||
SHA224_Flatten,
|
||||
SHA224_Resurrect,
|
||||
SHA224_Clone,
|
||||
BLAPI_SHVerifyFile,
|
||||
|
||||
/* End of Version 3.014 */
|
||||
/* End of Version 3.013 */
|
||||
|
||||
HMAC_ConstantTime,
|
||||
SSLv3_MAC_ConstantTime,
|
||||
PQG_ParamGenV2,
|
||||
PRNGTEST_RunHealthTests,
|
||||
|
||||
/* End of Version 3.015 */
|
||||
/* End of Version 3.014 */
|
||||
|
||||
RSA_SignRaw,
|
||||
RSA_CheckSignRaw,
|
||||
RSA_CheckSignRecoverRaw,
|
||||
RSA_EncryptRaw,
|
||||
RSA_DecryptRaw,
|
||||
RSA_EncryptOAEP,
|
||||
RSA_DecryptOAEP,
|
||||
RSA_EncryptBlock,
|
||||
RSA_DecryptBlock,
|
||||
RSA_SignPSS,
|
||||
RSA_CheckSignPSS,
|
||||
RSA_Sign,
|
||||
RSA_CheckSign,
|
||||
RSA_CheckSignRecover,
|
||||
HMAC_ConstantTime,
|
||||
SSLv3_MAC_ConstantTime,
|
||||
|
||||
/* End of Version 3.016 */
|
||||
/* End of Version 3.015 */
|
||||
|
||||
EC_FillParams,
|
||||
EC_DecodeParams,
|
||||
EC_CopyParams,
|
||||
RSA_SignRaw,
|
||||
RSA_CheckSignRaw,
|
||||
RSA_CheckSignRecoverRaw,
|
||||
RSA_EncryptRaw,
|
||||
RSA_DecryptRaw,
|
||||
RSA_EncryptOAEP,
|
||||
RSA_DecryptOAEP,
|
||||
RSA_EncryptBlock,
|
||||
RSA_DecryptBlock,
|
||||
RSA_SignPSS,
|
||||
RSA_CheckSignPSS,
|
||||
RSA_Sign,
|
||||
RSA_CheckSign,
|
||||
RSA_CheckSignRecover,
|
||||
|
||||
/* End of Version 3.017 */
|
||||
/* End of Version 3.016 */
|
||||
|
||||
ChaCha20Poly1305_InitContext,
|
||||
ChaCha20Poly1305_CreateContext,
|
||||
ChaCha20Poly1305_DestroyContext,
|
||||
ChaCha20Poly1305_Seal,
|
||||
ChaCha20Poly1305_Open,
|
||||
EC_FillParams,
|
||||
EC_DecodeParams,
|
||||
EC_CopyParams,
|
||||
|
||||
/* End of Version 3.018 */
|
||||
/* End of Version 3.017 */
|
||||
|
||||
EC_GetPointSize,
|
||||
ChaCha20Poly1305_InitContext,
|
||||
ChaCha20Poly1305_CreateContext,
|
||||
ChaCha20Poly1305_DestroyContext,
|
||||
ChaCha20Poly1305_Seal,
|
||||
ChaCha20Poly1305_Open,
|
||||
|
||||
/* End of Version 3.019 */
|
||||
/* End of Version 3.018 */
|
||||
|
||||
BLAKE2B_Hash,
|
||||
BLAKE2B_HashBuf,
|
||||
BLAKE2B_MAC_HashBuf,
|
||||
BLAKE2B_NewContext,
|
||||
BLAKE2B_DestroyContext,
|
||||
BLAKE2B_Begin,
|
||||
BLAKE2B_MAC_Begin,
|
||||
BLAKE2B_Update,
|
||||
BLAKE2B_End,
|
||||
BLAKE2B_FlattenSize,
|
||||
BLAKE2B_Flatten,
|
||||
BLAKE2B_Resurrect,
|
||||
EC_GetPointSize,
|
||||
|
||||
/* End of Version 3.020 */
|
||||
/* End of Version 3.019 */
|
||||
|
||||
ChaCha20_Xor,
|
||||
BLAKE2B_Hash,
|
||||
BLAKE2B_HashBuf,
|
||||
BLAKE2B_MAC_HashBuf,
|
||||
BLAKE2B_NewContext,
|
||||
BLAKE2B_DestroyContext,
|
||||
BLAKE2B_Begin,
|
||||
BLAKE2B_MAC_Begin,
|
||||
BLAKE2B_Update,
|
||||
BLAKE2B_End,
|
||||
BLAKE2B_FlattenSize,
|
||||
BLAKE2B_Flatten,
|
||||
BLAKE2B_Resurrect,
|
||||
|
||||
/* End of version 3.021 */
|
||||
/* End of Version 3.020 */
|
||||
|
||||
CMAC_Init,
|
||||
CMAC_Create,
|
||||
CMAC_Begin,
|
||||
CMAC_Update,
|
||||
CMAC_Finish,
|
||||
CMAC_Destroy
|
||||
ChaCha20_Xor,
|
||||
|
||||
/* End of version 3.022 */
|
||||
};
|
||||
/* End of version 3.021 */
|
||||
|
||||
CMAC_Init,
|
||||
CMAC_Create,
|
||||
CMAC_Begin,
|
||||
CMAC_Update,
|
||||
CMAC_Finish,
|
||||
CMAC_Destroy,
|
||||
|
||||
/* End of version 3.022 */
|
||||
ChaCha20Poly1305_Encrypt,
|
||||
ChaCha20Poly1305_Decrypt,
|
||||
AES_AEAD,
|
||||
AESKeyWrap_EncryptKWP,
|
||||
AESKeyWrap_DecryptKWP,
|
||||
|
||||
/* End of version 3.023 */
|
||||
KEA_PrimeCheck,
|
||||
|
||||
/* End of version 3.024 */
|
||||
ChaCha20_InitContext,
|
||||
ChaCha20_CreateContext,
|
||||
ChaCha20_DestroyContext
|
||||
|
||||
/* End of version 3.025 */
|
||||
};
|
||||
|
||||
const FREEBLVector*
|
||||
FREEBL_GetVector(void)
|
||||
|
|
@ -360,21 +408,20 @@ FREEBL_GetVector(void)
|
|||
}
|
||||
|
||||
#ifdef FREEBL_LOWHASH
|
||||
static const struct NSSLOWVectorStr nssvector =
|
||||
{
|
||||
sizeof nssvector,
|
||||
NSSLOW_VERSION,
|
||||
FREEBL_GetVector,
|
||||
NSSLOW_Init,
|
||||
NSSLOW_Shutdown,
|
||||
NSSLOW_Reset,
|
||||
NSSLOWHASH_NewContext,
|
||||
NSSLOWHASH_Begin,
|
||||
NSSLOWHASH_Update,
|
||||
NSSLOWHASH_End,
|
||||
NSSLOWHASH_Destroy,
|
||||
NSSLOWHASH_Length
|
||||
};
|
||||
static const struct NSSLOWVectorStr nssvector = {
|
||||
sizeof nssvector,
|
||||
NSSLOW_VERSION,
|
||||
FREEBL_GetVector,
|
||||
NSSLOW_Init,
|
||||
NSSLOW_Shutdown,
|
||||
NSSLOW_Reset,
|
||||
NSSLOWHASH_NewContext,
|
||||
NSSLOWHASH_Begin,
|
||||
NSSLOWHASH_Update,
|
||||
NSSLOWHASH_End,
|
||||
NSSLOWHASH_Destroy,
|
||||
NSSLOWHASH_Length
|
||||
};
|
||||
|
||||
const NSSLOWVector*
|
||||
NSSLOW_GetVector(void)
|
||||
|
|
|
|||
|
|
@ -236,6 +236,14 @@ KEA_Verify(SECItem *Y, SECItem *prime, SECItem *subPrime)
|
|||
return (vector->p_KEA_Verify)(Y, prime, subPrime);
|
||||
}
|
||||
|
||||
PRBool
|
||||
KEA_PrimeCheck(SECItem *prime)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return PR_FALSE;
|
||||
return (vector->p_KEA_PrimeCheck)(prime);
|
||||
}
|
||||
|
||||
RC4Context *
|
||||
RC4_CreateContext(const unsigned char *key, int len)
|
||||
{
|
||||
|
|
@ -280,7 +288,11 @@ RC2_CreateContext(const unsigned char *key, unsigned int len,
|
|||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return NULL;
|
||||
#ifndef NSS_DISABLE_DEPRECATED_RC2
|
||||
return (vector->p_RC2_CreateContext)(key, len, iv, mode, effectiveKeyLen);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -288,7 +300,11 @@ RC2_DestroyContext(RC2Context *cx, PRBool freeit)
|
|||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return;
|
||||
#ifndef NSS_DISABLE_DEPRECATED_RC2
|
||||
(vector->p_RC2_DestroyContext)(cx, freeit);
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
SECStatus
|
||||
|
|
@ -298,8 +314,12 @@ RC2_Encrypt(RC2Context *cx, unsigned char *output, unsigned int *outputLen,
|
|||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return SECFailure;
|
||||
#ifndef NSS_DISABLE_DEPRECATED_RC2
|
||||
return (vector->p_RC2_Encrypt)(cx, output, outputLen, maxOutputLen, input,
|
||||
inputLen);
|
||||
#else
|
||||
return SECFailure;
|
||||
#endif
|
||||
}
|
||||
|
||||
SECStatus
|
||||
|
|
@ -309,8 +329,12 @@ RC2_Decrypt(RC2Context *cx, unsigned char *output, unsigned int *outputLen,
|
|||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return SECFailure;
|
||||
#ifndef NSS_DISABLE_DEPRECATED_RC2
|
||||
return (vector->p_RC2_Decrypt)(cx, output, outputLen, maxOutputLen, input,
|
||||
inputLen);
|
||||
#else
|
||||
return SECFailure;
|
||||
#endif
|
||||
}
|
||||
|
||||
RC5Context *
|
||||
|
|
@ -396,7 +420,11 @@ SEED_CreateContext(const unsigned char *key, const unsigned char *iv,
|
|||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return NULL;
|
||||
#ifndef NSS_DISABLE_DEPRECATED_SEED
|
||||
return (vector->p_SEED_CreateContext)(key, iv, mode, encrypt);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -404,7 +432,11 @@ SEED_DestroyContext(SEEDContext *cx, PRBool freeit)
|
|||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return;
|
||||
#ifndef NSS_DISABLE_DEPRECATED_SEED
|
||||
(vector->p_SEED_DestroyContext)(cx, freeit);
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
SECStatus
|
||||
|
|
@ -414,8 +446,12 @@ SEED_Encrypt(SEEDContext *cx, unsigned char *output, unsigned int *outputLen,
|
|||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return SECFailure;
|
||||
#ifndef NSS_DISABLE_DEPRECATED_SEED
|
||||
return (vector->p_SEED_Encrypt)(cx, output, outputLen, maxOutputLen, input,
|
||||
inputLen);
|
||||
#else
|
||||
return SECFailure;
|
||||
#endif
|
||||
}
|
||||
|
||||
SECStatus
|
||||
|
|
@ -425,8 +461,12 @@ SEED_Decrypt(SEEDContext *cx, unsigned char *output, unsigned int *outputLen,
|
|||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return SECFailure;
|
||||
#ifndef NSS_DISABLE_DEPRECATED_SEED
|
||||
return (vector->p_SEED_Decrypt)(cx, output, outputLen, maxOutputLen, input,
|
||||
inputLen);
|
||||
#else
|
||||
return SECFailure;
|
||||
#endif
|
||||
}
|
||||
|
||||
AESContext *
|
||||
|
|
@ -470,6 +510,19 @@ AES_Decrypt(AESContext *cx, unsigned char *output,
|
|||
input, inputLen);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
AES_AEAD(AESContext *cx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen,
|
||||
void *params, unsigned int paramsLen,
|
||||
const unsigned char *aad, unsigned int aadLen)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return SECFailure;
|
||||
return (vector->p_AES_AEAD)(cx, output, outputLen, maxOutputLen, input,
|
||||
inputLen, params, paramsLen, aad, aadLen);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
MD5_Hash(unsigned char *dest, const char *src)
|
||||
{
|
||||
|
|
@ -1125,6 +1178,7 @@ AESKeyWrap_Encrypt(AESKeyWrapContext *cx, unsigned char *output,
|
|||
return vector->p_AESKeyWrap_Encrypt(cx, output, outputLen, maxOutputLen,
|
||||
input, inputLen);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
AESKeyWrap_Decrypt(AESKeyWrapContext *cx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
|
|
@ -1136,6 +1190,28 @@ AESKeyWrap_Decrypt(AESKeyWrapContext *cx, unsigned char *output,
|
|||
input, inputLen);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
AESKeyWrap_EncryptKWP(AESKeyWrapContext *cx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return SECFailure;
|
||||
return vector->p_AESKeyWrap_EncryptKWP(cx, output, outputLen, maxOutputLen,
|
||||
input, inputLen);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
AESKeyWrap_DecryptKWP(AESKeyWrapContext *cx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return SECFailure;
|
||||
return vector->p_AESKeyWrap_DecryptKWP(cx, output, outputLen, maxOutputLen,
|
||||
input, inputLen);
|
||||
}
|
||||
|
||||
PRBool
|
||||
BLAPI_SHVerify(const char *name, PRFuncPtr addr)
|
||||
{
|
||||
|
|
@ -1255,7 +1331,11 @@ RC2_AllocateContext(void)
|
|||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return NULL;
|
||||
#ifndef NSS_DISABLE_DEPRECATED_RC2
|
||||
return (vector->p_RC2_AllocateContext)();
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
RC4Context *
|
||||
|
|
@ -1305,7 +1385,11 @@ SEED_InitContext(SEEDContext *cx, const unsigned char *key,
|
|||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return SECFailure;
|
||||
#ifndef NSS_DISABLE_DEPRECATED_SEED
|
||||
return (vector->p_SEED_InitContext)(cx, key, keylen, iv, mode, encrypt, xtra);
|
||||
#else
|
||||
return SECFailure;
|
||||
#endif
|
||||
}
|
||||
|
||||
SECStatus
|
||||
|
|
@ -1315,8 +1399,12 @@ RC2_InitContext(RC2Context *cx, const unsigned char *key,
|
|||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return SECFailure;
|
||||
#ifndef NSS_DISABLE_DEPRECATED_RC2
|
||||
return (vector->p_RC2_InitContext)(cx, key, keylen, iv, mode,
|
||||
effectiveKeyLen, xtra);
|
||||
#else
|
||||
return SECFailure;
|
||||
#endif
|
||||
}
|
||||
|
||||
SECStatus
|
||||
|
|
@ -2070,6 +2158,36 @@ ChaCha20_Xor(unsigned char *output, const unsigned char *block, unsigned int len
|
|||
return (vector->p_ChaCha20_Xor)(output, block, len, k, nonce, ctr);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
ChaCha20_InitContext(ChaCha20Context *ctx, const unsigned char *key,
|
||||
unsigned int keyLen,
|
||||
const unsigned char *nonce,
|
||||
unsigned int nonceLen,
|
||||
PRUint32 ctr)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return SECFailure;
|
||||
return (vector->p_ChaCha20_InitContext)(ctx, key, keyLen, nonce, nonceLen, ctr);
|
||||
}
|
||||
|
||||
ChaCha20Context *
|
||||
ChaCha20_CreateContext(const unsigned char *key, unsigned int keyLen,
|
||||
const unsigned char *nonce, unsigned int nonceLen,
|
||||
PRUint32 ctr)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return NULL;
|
||||
return (vector->p_ChaCha20_CreateContext)(key, keyLen, nonce, nonceLen, ctr);
|
||||
}
|
||||
|
||||
void
|
||||
ChaCha20_DestroyContext(ChaCha20Context *ctx, PRBool freeit)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return;
|
||||
(vector->p_ChaCha20_DestroyContext)(ctx, freeit);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
ChaCha20Poly1305_InitContext(ChaCha20Poly1305Context *ctx,
|
||||
const unsigned char *key, unsigned int keyLen,
|
||||
|
|
@ -2127,6 +2245,38 @@ ChaCha20Poly1305_Open(const ChaCha20Poly1305Context *ctx,
|
|||
nonce, nonceLen, ad, adLen);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
ChaCha20Poly1305_Encrypt(const ChaCha20Poly1305Context *ctx,
|
||||
unsigned char *output, unsigned int *outputLen,
|
||||
unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen,
|
||||
const unsigned char *nonce, unsigned int nonceLen,
|
||||
const unsigned char *ad, unsigned int adLen,
|
||||
unsigned char *tagOut)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return SECFailure;
|
||||
return (vector->p_ChaCha20Poly1305_Encrypt)(
|
||||
ctx, output, outputLen, maxOutputLen, input, inputLen,
|
||||
nonce, nonceLen, ad, adLen, tagOut);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
ChaCha20Poly1305_Decrypt(const ChaCha20Poly1305Context *ctx,
|
||||
unsigned char *output, unsigned int *outputLen,
|
||||
unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen,
|
||||
const unsigned char *nonce, unsigned int nonceLen,
|
||||
const unsigned char *ad, unsigned int adLen,
|
||||
unsigned char *tagIn)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return SECFailure;
|
||||
return (vector->p_ChaCha20Poly1305_Decrypt)(
|
||||
ctx, output, outputLen, maxOutputLen, input, inputLen,
|
||||
nonce, nonceLen, ad, adLen, tagIn);
|
||||
}
|
||||
|
||||
int
|
||||
EC_GetPointSize(const ECParams *params)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
#include "blapi.h"
|
||||
|
||||
#define FREEBL_VERSION 0x0316
|
||||
#define FREEBL_VERSION 0x0325
|
||||
|
||||
struct FREEBLVectorStr {
|
||||
|
||||
|
|
@ -778,6 +778,59 @@ struct FREEBLVectorStr {
|
|||
void (*p_CMAC_Destroy)(CMACContext *ctx, PRBool free_it);
|
||||
|
||||
/* Version 3.022 came to here */
|
||||
SECStatus (*p_ChaCha20Poly1305_Encrypt)(
|
||||
const ChaCha20Poly1305Context *ctx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen,
|
||||
const unsigned char *nonce, unsigned int nonceLen,
|
||||
const unsigned char *ad, unsigned int adLen, unsigned char *tagOut);
|
||||
|
||||
SECStatus (*p_ChaCha20Poly1305_Decrypt)(
|
||||
const ChaCha20Poly1305Context *ctx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen,
|
||||
const unsigned char *nonce, unsigned int nonceLen,
|
||||
const unsigned char *ad, unsigned int adLen, unsigned char *tagIn);
|
||||
SECStatus (*p_AES_AEAD)(AESContext *cx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen,
|
||||
void *params, unsigned int paramsLen,
|
||||
const unsigned char *aad, unsigned int aadLen);
|
||||
SECStatus (*p_AESKeyWrap_EncryptKWP)(AESKeyWrapContext *cx,
|
||||
unsigned char *output,
|
||||
unsigned int *outputLen,
|
||||
unsigned int maxOutputLen,
|
||||
const unsigned char *input,
|
||||
unsigned int inputLen);
|
||||
|
||||
SECStatus (*p_AESKeyWrap_DecryptKWP)(AESKeyWrapContext *cx,
|
||||
unsigned char *output,
|
||||
unsigned int *outputLen,
|
||||
unsigned int maxOutputLen,
|
||||
const unsigned char *input,
|
||||
unsigned int inputLen);
|
||||
|
||||
/* Version 3.023 came to here */
|
||||
|
||||
PRBool (*p_KEA_PrimeCheck)(SECItem *prime);
|
||||
/* Version 3.024 came to here */
|
||||
|
||||
SECStatus (*p_ChaCha20_InitContext)(ChaCha20Context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keyLen,
|
||||
const unsigned char *nonce,
|
||||
unsigned int nonceLen,
|
||||
PRUint32 ctr);
|
||||
|
||||
ChaCha20Context *(*p_ChaCha20_CreateContext)(const unsigned char *key,
|
||||
unsigned int keyLen,
|
||||
const unsigned char *nonce,
|
||||
unsigned int nonceLen,
|
||||
PRUint32 ctr);
|
||||
|
||||
void (*p_ChaCha20_DestroyContext)(ChaCha20Context *ctx, PRBool freeit);
|
||||
|
||||
/* Version 3.025 came to here */
|
||||
|
||||
/* Add new function pointers at the end of this struct and bump
|
||||
* FREEBL_VERSION at the beginning of this file. */
|
||||
|
|
@ -829,3 +882,55 @@ extern FREEBLGetVectorFn FREEBL_GetVector;
|
|||
SEC_END_PROTOS
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef NSS_DISABLE_DEPRECATED_SEED
|
||||
typedef SECStatus (*F_SEED_InitContext)(SEEDContext *cx,
|
||||
const unsigned char *key,
|
||||
unsigned int keylen,
|
||||
const unsigned char *iv,
|
||||
int mode,
|
||||
unsigned int encrypt,
|
||||
unsigned int);
|
||||
|
||||
typedef SEEDContext *(*F_SEED_AllocateContext)(void);
|
||||
|
||||
typedef SEEDContext *(*F_SEED_CreateContext)(const unsigned char *key,
|
||||
const unsigned char *iv,
|
||||
int mode, PRBool encrypt);
|
||||
|
||||
typedef void (*F_SEED_DestroyContext)(SEEDContext *cx, PRBool freeit);
|
||||
|
||||
typedef SECStatus (*F_SEED_Encrypt)(SEEDContext *cx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen);
|
||||
|
||||
typedef SECStatus (*F_SEED_Decrypt)(SEEDContext *cx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen);
|
||||
#endif
|
||||
|
||||
#ifdef NSS_DISABLE_DEPRECATED_RC2
|
||||
typedef RC2Context *(*F_RC2_CreateContext)(const unsigned char *key,
|
||||
unsigned int len, const unsigned char *iv,
|
||||
int mode, unsigned effectiveKeyLen);
|
||||
|
||||
typedef void (*F_RC2_DestroyContext)(RC2Context *cx, PRBool freeit);
|
||||
|
||||
typedef SECStatus (*F_RC2_Encrypt)(RC2Context *cx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen);
|
||||
|
||||
typedef SECStatus (*F_RC2_Decrypt)(RC2Context *cx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen);
|
||||
|
||||
typedef SECStatus (*F_RC2_InitContext)(RC2Context *cx,
|
||||
const unsigned char *key,
|
||||
unsigned int keylen,
|
||||
const unsigned char *iv,
|
||||
int mode,
|
||||
unsigned int effectiveKeyLen,
|
||||
unsigned int);
|
||||
|
||||
typedef RC2Context *(*F_RC2_AllocateContext)(void);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -123,10 +123,9 @@ CSRCS = \
|
|||
cmac.c \
|
||||
alghmac.c \
|
||||
rawhash.c \
|
||||
alg2268.c \
|
||||
arcfour.c \
|
||||
arcfive.c \
|
||||
crypto_primitives.c \
|
||||
crypto_primitives.c \
|
||||
blake2b.c \
|
||||
desblapi.c \
|
||||
des.c \
|
||||
|
|
@ -150,8 +149,8 @@ CSRCS = \
|
|||
rsapkcs.c \
|
||||
shvfy.c \
|
||||
tlsprfalg.c \
|
||||
seed.c \
|
||||
jpake.c \
|
||||
secmpi.c \
|
||||
$(MPI_SRCS) \
|
||||
$(MPCPU_SRCS) \
|
||||
$(ECL_SRCS) \
|
||||
|
|
@ -161,6 +160,14 @@ CSRCS = \
|
|||
$(EXTRA_SRCS) \
|
||||
$(NULL)
|
||||
|
||||
ifndef NSS_DISABLE_DEPRECATED_SEED
|
||||
CSRCS += deprecated/seed.c
|
||||
endif
|
||||
|
||||
ifndef NSS_DISABLE_DEPRECATED_RC2
|
||||
CSRCS += deprecated/alg2268.c
|
||||
endif
|
||||
|
||||
ALL_CSRCS := $(CSRCS)
|
||||
|
||||
ALL_HDRS = \
|
||||
|
|
|
|||
0
security/nss/lib/freebl/mpi/doc/build
Normal file → Executable file
0
security/nss/lib/freebl/mpi/doc/build
Normal file → Executable file
|
|
@ -198,7 +198,7 @@ L18:
|
|||
mov dword ptr [8+rbx], edi
|
||||
je L9
|
||||
lea r10d, dword ptr [-2+rdx]
|
||||
cmp dword ptr [r11+r10*8], 0
|
||||
cmp qword ptr [r11+r10*8], 0
|
||||
je L18
|
||||
L9:
|
||||
mov edx, dword ptr [8+rbx]
|
||||
|
|
@ -689,7 +689,7 @@ L43:
|
|||
mov dword ptr [8+rbx], edi
|
||||
je L35
|
||||
lea eax, dword ptr [-2+rdx]
|
||||
cmp dword ptr [r11+rax*8], 0
|
||||
cmp qword ptr [r11+rax*8], 0
|
||||
je L43
|
||||
L35:
|
||||
mov r11d, dword ptr [8+rbx]
|
||||
|
|
@ -2268,7 +2268,7 @@ L84:
|
|||
mov dword ptr [8+rbx], edi
|
||||
je L76
|
||||
lea eax, dword ptr [-2+rdx]
|
||||
cmp dword ptr [r11+rax*8], 0
|
||||
cmp qword ptr [r11+rax*8], 0
|
||||
je L84
|
||||
L76:
|
||||
mov edx, dword ptr [8+rbx]
|
||||
|
|
@ -7830,7 +7830,7 @@ L157:
|
|||
mov dword ptr [8+r13], ebx
|
||||
je L149
|
||||
lea r12d, dword ptr [-2+rdx]
|
||||
cmp dword ptr [r9+r12*8], 0
|
||||
cmp qword ptr [r9+r12*8], 0
|
||||
je L157
|
||||
L149:
|
||||
mov r9d, dword ptr [8+r13]
|
||||
|
|
@ -7990,7 +7990,7 @@ s_mp_sqr_comba_4 PROC
|
|||
lea ecx, dword ptr [-1+rdx]
|
||||
mov rsi, qword ptr [16+r11]
|
||||
mov r10d, ecx
|
||||
cmp dword ptr [rsi+r10*8], 0
|
||||
cmp qword ptr [rsi+r10*8], 0
|
||||
jne L166
|
||||
mov edx, ecx
|
||||
ALIGN 16
|
||||
|
|
@ -8000,7 +8000,7 @@ L167:
|
|||
je L171
|
||||
dec edx
|
||||
mov eax, edx
|
||||
cmp dword ptr [rsi+rax*8], 0
|
||||
cmp qword ptr [rsi+rax*8], 0
|
||||
je L167
|
||||
mov dword ptr [8+r11], ecx
|
||||
mov edx, ecx
|
||||
|
|
@ -8415,7 +8415,7 @@ s_mp_sqr_comba_8 PROC
|
|||
lea ecx, dword ptr [-1+rdx]
|
||||
mov rsi, qword ptr [16+rbp]
|
||||
mov r14d, ecx
|
||||
cmp dword ptr [rsi+r14*8], 0
|
||||
cmp qword ptr [rsi+r14*8], 0
|
||||
jne L190
|
||||
mov edx, ecx
|
||||
ALIGN 16
|
||||
|
|
@ -8425,7 +8425,7 @@ L191:
|
|||
je L195
|
||||
dec edx
|
||||
mov r9d, edx
|
||||
cmp dword ptr [rsi+r9*8], 0
|
||||
cmp qword ptr [rsi+r9*8], 0
|
||||
je L191
|
||||
mov dword ptr [8+rbp], ecx
|
||||
mov edx, ecx
|
||||
|
|
@ -9511,7 +9511,7 @@ s_mp_sqr_comba_16 PROC ; A "FRAME" function
|
|||
lea ecx, dword ptr [-1+rdx]
|
||||
mov rsi, qword ptr [16+r14]
|
||||
mov r9d, ecx
|
||||
cmp dword ptr [rsi+r9*8], 0
|
||||
cmp qword ptr [rsi+r9*8], 0
|
||||
jne L230
|
||||
mov edx, ecx
|
||||
ALIGN 16
|
||||
|
|
@ -9521,7 +9521,7 @@ L231:
|
|||
je L235
|
||||
dec edx
|
||||
mov eax, edx
|
||||
cmp dword ptr [rsi+rax*8], 0
|
||||
cmp qword ptr [rsi+rax*8], 0
|
||||
je L231
|
||||
mov dword ptr [8+r14], ecx
|
||||
mov edx, ecx
|
||||
|
|
@ -13023,7 +13023,7 @@ s_mp_sqr_comba_32 PROC ; A "FRAME" function
|
|||
lea ecx, dword ptr [-1+rdx]
|
||||
mov rsi, qword ptr [16+r14]
|
||||
mov r10d, ecx
|
||||
cmp dword ptr [rsi+r10*8], 0
|
||||
cmp qword ptr [rsi+r10*8], 0
|
||||
jne L302
|
||||
mov edx, ecx
|
||||
ALIGN 16
|
||||
|
|
@ -13033,7 +13033,7 @@ L303:
|
|||
je L307
|
||||
dec edx
|
||||
mov eax, edx
|
||||
cmp dword ptr [rsi+rax*8], 0
|
||||
cmp qword ptr [rsi+rax*8], 0
|
||||
je L303
|
||||
mov dword ptr [8+r14], ecx
|
||||
mov edx, ecx
|
||||
|
|
|
|||
|
|
@ -7,11 +7,10 @@
|
|||
#include "mplogic.h"
|
||||
#include "mpi-priv.h"
|
||||
|
||||
const mp_digit mp_gf2m_sqr_tb[16] =
|
||||
{
|
||||
0, 1, 4, 5, 16, 17, 20, 21,
|
||||
64, 65, 68, 69, 80, 81, 84, 85
|
||||
};
|
||||
const mp_digit mp_gf2m_sqr_tb[16] = {
|
||||
0, 1, 4, 5, 16, 17, 20, 21,
|
||||
64, 65, 68, 69, 80, 81, 84, 85
|
||||
};
|
||||
|
||||
/* Multiply two binary polynomials mp_digits a, b.
|
||||
* Result is a polynomial with degree < 2 * MP_DIGIT_BITS - 1.
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@ freebl_cpuid(unsigned long op, unsigned long *eax,
|
|||
unsigned long *ebx, unsigned long *ecx,
|
||||
unsigned long *edx)
|
||||
{
|
||||
__asm__("cpuid\n\t"
|
||||
__asm__("xor %%ecx, %%ecx\n\t"
|
||||
"cpuid\n\t"
|
||||
: "=a"(*eax),
|
||||
"=b"(*ebx),
|
||||
"=c"(*ecx),
|
||||
|
|
@ -726,10 +727,10 @@ s_mpi_getProcessorLineSize()
|
|||
static inline void
|
||||
dcbzl(char *array)
|
||||
{
|
||||
register char *a asm("r2") = array;
|
||||
__asm__ __volatile__("dcbzl %0,0"
|
||||
: "=r"(a)
|
||||
: "0"(a));
|
||||
__asm__("dcbzl %0, %1"
|
||||
: /*no result*/
|
||||
: "b%"(array), "r"(0)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
#define PPC_DO_ALIGN(x, y) ((char *)((((long long)(x)) + ((y)-1)) & ~((y)-1)))
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ mp_err s_mp_invmod_2d(const mp_int *a, mp_size k, mp_int *c);
|
|||
mp_err s_mp_invmod_even_m(const mp_int *a, const mp_int *m, mp_int *c);
|
||||
|
||||
#ifdef NSS_USE_COMBA
|
||||
|
||||
PR_STATIC_ASSERT(sizeof(mp_digit) == 8);
|
||||
#define IS_POWER_OF_2(a) ((a) && !((a) & ((a)-1)))
|
||||
|
||||
void s_mp_mul_comba_4(const mp_int *A, const mp_int *B, mp_int *C);
|
||||
|
|
@ -204,6 +204,9 @@ void MPI_ASM_DECL s_mpv_mul_d_add(const mp_digit *a, mp_size a_len,
|
|||
void MPI_ASM_DECL s_mpv_mul_d_add_prop(const mp_digit *a,
|
||||
mp_size a_len, mp_digit b,
|
||||
mp_digit *c);
|
||||
void MPI_ASM_DECL s_mpv_mul_d_add_propCT(const mp_digit *a,
|
||||
mp_size a_len, mp_digit b,
|
||||
mp_digit *c, mp_size c_len);
|
||||
void MPI_ASM_DECL s_mpv_sqr_add_prop(const mp_digit *a,
|
||||
mp_size a_len,
|
||||
mp_digit *sqrs);
|
||||
|
|
|
|||
|
|
@ -9,9 +9,8 @@
|
|||
|
||||
#include "mpi-priv.h"
|
||||
#include "mplogic.h"
|
||||
#if defined(OSF1)
|
||||
#include <c_asm.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#if defined(__arm__) && \
|
||||
((defined(__thumb__) && !defined(__thumb2__)) || defined(__ARM_ARCH_3__))
|
||||
|
|
@ -805,15 +804,18 @@ CLEANUP:
|
|||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ mp_mul(a, b, c) */
|
||||
/* {{{ s_mp_mulg(a, b, c) */
|
||||
|
||||
/*
|
||||
mp_mul(a, b, c)
|
||||
s_mp_mulg(a, b, c)
|
||||
|
||||
Compute c = a * b. All parameters may be identical.
|
||||
Compute c = a * b. All parameters may be identical. if constantTime is set,
|
||||
then the operations are done in constant time. The original is mostly
|
||||
constant time as long as s_mpv_mul_d_add() is constant time. This is true
|
||||
of the x86 assembler, as well as the current c code.
|
||||
*/
|
||||
mp_err
|
||||
mp_mul(const mp_int *a, const mp_int *b, mp_int *c)
|
||||
s_mp_mulg(const mp_int *a, const mp_int *b, mp_int *c, int constantTime)
|
||||
{
|
||||
mp_digit *pb;
|
||||
mp_int tmp;
|
||||
|
|
@ -849,7 +851,14 @@ mp_mul(const mp_int *a, const mp_int *b, mp_int *c)
|
|||
goto CLEANUP;
|
||||
|
||||
#ifdef NSS_USE_COMBA
|
||||
if ((MP_USED(a) == MP_USED(b)) && IS_POWER_OF_2(MP_USED(b))) {
|
||||
/* comba isn't constant time because it clamps! If we cared
|
||||
* (we needed a constant time version of multiply that was 'faster'
|
||||
* we could easily pass constantTime down to the comba code and
|
||||
* get it to skip the clamp... but here are assembler versions
|
||||
* which add comba to platforms that can't compile the normal
|
||||
* comba's imbedded assembler which would also need to change, so
|
||||
* for now we just skip comba when we are running constant time. */
|
||||
if (!constantTime && (MP_USED(a) == MP_USED(b)) && IS_POWER_OF_2(MP_USED(b))) {
|
||||
if (MP_USED(a) == 4) {
|
||||
s_mp_mul_comba_4(a, b, c);
|
||||
goto CLEANUP;
|
||||
|
|
@ -879,13 +888,15 @@ mp_mul(const mp_int *a, const mp_int *b, mp_int *c)
|
|||
mp_digit b_i = *pb++;
|
||||
|
||||
/* Inner product: Digits of a */
|
||||
if (b_i)
|
||||
if (constantTime || b_i)
|
||||
s_mpv_mul_d_add(MP_DIGITS(a), useda, b_i, MP_DIGITS(c) + ib);
|
||||
else
|
||||
MP_DIGIT(c, ib + useda) = b_i;
|
||||
}
|
||||
|
||||
s_mp_clamp(c);
|
||||
if (!constantTime) {
|
||||
s_mp_clamp(c);
|
||||
}
|
||||
|
||||
if (SIGN(a) == SIGN(b) || s_mp_cmp_d(c, 0) == MP_EQ)
|
||||
SIGN(c) = ZPOS;
|
||||
|
|
@ -895,10 +906,54 @@ mp_mul(const mp_int *a, const mp_int *b, mp_int *c)
|
|||
CLEANUP:
|
||||
mp_clear(&tmp);
|
||||
return res;
|
||||
} /* end smp_mulg() */
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ mp_mul(a, b, c) */
|
||||
|
||||
/*
|
||||
mp_mul(a, b, c)
|
||||
|
||||
Compute c = a * b. All parameters may be identical.
|
||||
*/
|
||||
|
||||
mp_err
|
||||
mp_mul(const mp_int *a, const mp_int *b, mp_int *c)
|
||||
{
|
||||
return s_mp_mulg(a, b, c, 0);
|
||||
} /* end mp_mul() */
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ mp_mulCT(a, b, c) */
|
||||
|
||||
/*
|
||||
mp_mulCT(a, b, c)
|
||||
|
||||
Compute c = a * b. In constant time. Parameters may not be identical.
|
||||
NOTE: a and b may be modified.
|
||||
*/
|
||||
|
||||
mp_err
|
||||
mp_mulCT(mp_int *a, mp_int *b, mp_int *c, mp_size setSize)
|
||||
{
|
||||
mp_err res;
|
||||
|
||||
/* make the multiply values fixed length so multiply
|
||||
* doesn't leak the length. at this point all the
|
||||
* values are blinded, but once we finish we want the
|
||||
* output size to be hidden (so no clamping the out put) */
|
||||
MP_CHECKOK(s_mp_pad(a, setSize));
|
||||
MP_CHECKOK(s_mp_pad(b, setSize));
|
||||
MP_CHECKOK(s_mp_pad(c, 2 * setSize));
|
||||
MP_CHECKOK(s_mp_mulg(a, b, c, 1));
|
||||
CLEANUP:
|
||||
return res;
|
||||
} /* end mp_mulCT() */
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ mp_sqr(a, sqr) */
|
||||
|
||||
#if MP_SQUARE
|
||||
|
|
@ -1271,6 +1326,138 @@ mp_mod(const mp_int *a, const mp_int *m, mp_int *c)
|
|||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ s_mp_subCT_d(a, b, borrow, c) */
|
||||
|
||||
/*
|
||||
s_mp_subCT_d(a, b, borrow, c)
|
||||
|
||||
Compute c = (a -b) - subtract in constant time. returns borrow
|
||||
*/
|
||||
mp_digit
|
||||
s_mp_subCT_d(mp_digit a, mp_digit b, mp_digit borrow, mp_digit *ret)
|
||||
{
|
||||
*ret = a - b - borrow;
|
||||
return MP_CT_LTU(a, *ret) | (MP_CT_EQ(a, *ret) & borrow);
|
||||
} /* s_mp_subCT_d() */
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ mp_subCT(a, b, ret, borrow) */
|
||||
|
||||
/* return ret= a - b and borrow in borrow. done in constant time.
|
||||
* b could be modified.
|
||||
*/
|
||||
mp_err
|
||||
mp_subCT(const mp_int *a, mp_int *b, mp_int *ret, mp_digit *borrow)
|
||||
{
|
||||
mp_size used_a = MP_USED(a);
|
||||
mp_size i;
|
||||
mp_err res;
|
||||
|
||||
MP_CHECKOK(s_mp_pad(b, used_a));
|
||||
MP_CHECKOK(s_mp_pad(ret, used_a));
|
||||
*borrow = 0;
|
||||
for (i = 0; i < used_a; i++) {
|
||||
*borrow = s_mp_subCT_d(MP_DIGIT(a, i), MP_DIGIT(b, i), *borrow,
|
||||
&MP_DIGIT(ret, i));
|
||||
}
|
||||
|
||||
res = MP_OKAY;
|
||||
CLEANUP:
|
||||
return res;
|
||||
} /* end mp_subCT() */
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ mp_selectCT(cond, a, b, ret) */
|
||||
|
||||
/*
|
||||
* return ret= cond ? a : b; cond should be either 0 or 1
|
||||
*/
|
||||
mp_err
|
||||
mp_selectCT(mp_digit cond, const mp_int *a, const mp_int *b, mp_int *ret)
|
||||
{
|
||||
mp_size used_a = MP_USED(a);
|
||||
mp_err res;
|
||||
mp_size i;
|
||||
|
||||
cond *= MP_DIGIT_MAX;
|
||||
|
||||
/* we currently require these to be equal on input,
|
||||
* we could use pad to extend one of them, but that might
|
||||
* leak data as it wouldn't be constant time */
|
||||
if (used_a != MP_USED(b)) {
|
||||
return MP_BADARG;
|
||||
}
|
||||
|
||||
MP_CHECKOK(s_mp_pad(ret, used_a));
|
||||
for (i = 0; i < used_a; i++) {
|
||||
MP_DIGIT(ret, i) = MP_CT_SEL_DIGIT(cond, MP_DIGIT(a, i), MP_DIGIT(b, i));
|
||||
}
|
||||
res = MP_OKAY;
|
||||
CLEANUP:
|
||||
return res;
|
||||
} /* end mp_selectCT() */
|
||||
|
||||
/* {{{ mp_reduceCT(a, m, c) */
|
||||
|
||||
/*
|
||||
mp_reduceCT(a, m, c)
|
||||
|
||||
Compute c = aR^-1 (mod m) in constant time.
|
||||
input should be in montgomery form. If input is the
|
||||
result of a montgomery multiply then out put will be
|
||||
in mongomery form.
|
||||
Result will be reduced to MP_USED(m), but not be
|
||||
clamped.
|
||||
*/
|
||||
|
||||
mp_err
|
||||
mp_reduceCT(const mp_int *a, const mp_int *m, mp_digit n0i, mp_int *c)
|
||||
{
|
||||
mp_size used_m = MP_USED(m);
|
||||
mp_size used_c = used_m * 2 + 1;
|
||||
mp_digit *m_digits, *c_digits;
|
||||
mp_size i;
|
||||
mp_digit borrow, carry;
|
||||
mp_err res;
|
||||
mp_int sub;
|
||||
|
||||
MP_DIGITS(&sub) = 0;
|
||||
MP_CHECKOK(mp_init_size(&sub, used_m));
|
||||
|
||||
if (a != c) {
|
||||
MP_CHECKOK(mp_copy(a, c));
|
||||
}
|
||||
MP_CHECKOK(s_mp_pad(c, used_c));
|
||||
m_digits = MP_DIGITS(m);
|
||||
c_digits = MP_DIGITS(c);
|
||||
for (i = 0; i < used_m; i++) {
|
||||
mp_digit m_i = MP_DIGIT(c, i) * n0i;
|
||||
s_mpv_mul_d_add_propCT(m_digits, used_m, m_i, c_digits++, used_c--);
|
||||
}
|
||||
s_mp_rshd(c, used_m);
|
||||
/* MP_USED(c) should be used_m+1 with the high word being any carry
|
||||
* from the previous multiply, save that carry and drop the high
|
||||
* word for the substraction below */
|
||||
carry = MP_DIGIT(c, used_m);
|
||||
MP_DIGIT(c, used_m) = 0;
|
||||
MP_USED(c) = used_m;
|
||||
/* mp_subCT wants c and m to be the same size, we've already
|
||||
* guarrenteed that in the previous statement, so mp_subCT won't actually
|
||||
* modify m, so it's safe to recast */
|
||||
MP_CHECKOK(mp_subCT(c, (mp_int *)m, &sub, &borrow));
|
||||
|
||||
/* we return c-m if c >= m no borrow or there was a borrow and a carry */
|
||||
MP_CHECKOK(mp_selectCT(borrow ^ carry, c, &sub, c));
|
||||
res = MP_OKAY;
|
||||
CLEANUP:
|
||||
mp_clear(&sub);
|
||||
return res;
|
||||
} /* end mp_reduceCT() */
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ mp_mod_d(a, d, c) */
|
||||
|
||||
/*
|
||||
|
|
@ -1387,6 +1574,37 @@ mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)
|
|||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ mp_mulmontmodCT(a, b, m, c) */
|
||||
|
||||
/*
|
||||
mp_mulmontmodCT(a, b, m, c)
|
||||
|
||||
Compute c = (a * b) mod m in constant time wrt a and b. either a or b
|
||||
should be in montgomery form and the output is native. If both a and b
|
||||
are in montgomery form, then the output will also be in montgomery form
|
||||
and can be recovered with an mp_reduceCT call.
|
||||
NOTE: a and b may be modified.
|
||||
*/
|
||||
|
||||
mp_err
|
||||
mp_mulmontmodCT(mp_int *a, mp_int *b, const mp_int *m, mp_digit n0i,
|
||||
mp_int *c)
|
||||
{
|
||||
mp_err res;
|
||||
|
||||
ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
|
||||
|
||||
if ((res = mp_mulCT(a, b, c, MP_USED(m))) != MP_OKAY)
|
||||
return res;
|
||||
|
||||
if ((res = mp_reduceCT(c, m, n0i, c)) != MP_OKAY)
|
||||
return res;
|
||||
|
||||
return MP_OKAY;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ mp_sqrmod(a, m, c) */
|
||||
|
||||
#if MP_SQUARE
|
||||
|
|
@ -2523,12 +2741,6 @@ mp_read_raw(mp_int *mp, char *str, int len)
|
|||
|
||||
mp_zero(mp);
|
||||
|
||||
/* Get sign from first byte */
|
||||
if (ustr[0])
|
||||
SIGN(mp) = NEG;
|
||||
else
|
||||
SIGN(mp) = ZPOS;
|
||||
|
||||
/* Read the rest of the digits */
|
||||
for (ix = 1; ix < len; ix++) {
|
||||
if ((res = mp_mul_d(mp, 256, mp)) != MP_OKAY)
|
||||
|
|
@ -2537,6 +2749,12 @@ mp_read_raw(mp_int *mp, char *str, int len)
|
|||
return res;
|
||||
}
|
||||
|
||||
/* Get sign from first byte */
|
||||
if (ustr[0])
|
||||
SIGN(mp) = NEG;
|
||||
else
|
||||
SIGN(mp) = ZPOS;
|
||||
|
||||
return MP_OKAY;
|
||||
|
||||
} /* end mp_read_raw() */
|
||||
|
|
@ -2693,7 +2911,7 @@ mp_radix_size(mp_int *mp, int radix)
|
|||
|
||||
bits = USED(mp) * DIGIT_BIT - 1;
|
||||
|
||||
return s_mp_outlen(bits, radix);
|
||||
return SIGN(mp) + s_mp_outlen(bits, radix);
|
||||
|
||||
} /* end mp_radix_size() */
|
||||
|
||||
|
|
@ -3248,7 +3466,8 @@ CLEANUP:
|
|||
/* {{{ s_mp_add_d(mp, d) */
|
||||
|
||||
/* Add d to |mp| in place */
|
||||
mp_err s_mp_add_d(mp_int *mp, mp_digit d) /* unsigned digit addition */
|
||||
mp_err
|
||||
s_mp_add_d(mp_int *mp, mp_digit d) /* unsigned digit addition */
|
||||
{
|
||||
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
|
||||
mp_word w, k = 0;
|
||||
|
|
@ -3305,7 +3524,8 @@ CLEANUP:
|
|||
/* {{{ s_mp_sub_d(mp, d) */
|
||||
|
||||
/* Subtract d from |mp| in place, assumes |mp| > d */
|
||||
mp_err s_mp_sub_d(mp_int *mp, mp_digit d) /* unsigned digit subtract */
|
||||
mp_err
|
||||
s_mp_sub_d(mp_int *mp, mp_digit d) /* unsigned digit subtract */
|
||||
{
|
||||
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
|
||||
mp_word w, b = 0;
|
||||
|
|
@ -3512,7 +3732,8 @@ CLEANUP:
|
|||
/* {{{ s_mp_add(a, b) */
|
||||
|
||||
/* Compute a = |a| + |b| */
|
||||
mp_err s_mp_add(mp_int *a, const mp_int *b) /* magnitude addition */
|
||||
mp_err
|
||||
s_mp_add(mp_int *a, const mp_int *b) /* magnitude addition */
|
||||
{
|
||||
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
|
||||
mp_word w = 0;
|
||||
|
|
@ -3775,7 +3996,8 @@ s_mp_add_offset(mp_int *a, mp_int *b, mp_size offset)
|
|||
/* {{{ s_mp_sub(a, b) */
|
||||
|
||||
/* Compute a = |a| - |b|, assumes |a| >= |b| */
|
||||
mp_err s_mp_sub(mp_int *a, const mp_int *b) /* magnitude subtract */
|
||||
mp_err
|
||||
s_mp_sub(mp_int *a, const mp_int *b) /* magnitude subtract */
|
||||
{
|
||||
mp_digit *pa, *pb, *limit;
|
||||
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
|
||||
|
|
@ -3930,12 +4152,6 @@ s_mp_mul(mp_int *a, const mp_int *b)
|
|||
Plo = (mp_digit)product; \
|
||||
Phi = (mp_digit)(product >> MP_DIGIT_BIT); \
|
||||
}
|
||||
#elif defined(OSF1)
|
||||
#define MP_MUL_DxD(a, b, Phi, Plo) \
|
||||
{ \
|
||||
Plo = asm("mulq %a0, %a1, %v0", a, b); \
|
||||
Phi = asm("umulh %a0, %a1, %v0", a, b); \
|
||||
}
|
||||
#else
|
||||
#define MP_MUL_DxD(a, b, Phi, Plo) \
|
||||
{ \
|
||||
|
|
@ -3946,15 +4162,63 @@ s_mp_mul(mp_int *a, const mp_int *b)
|
|||
a1b0 = (a >> MP_HALF_DIGIT_BIT) * (b & MP_HALF_DIGIT_MAX); \
|
||||
a1b0 += a0b1; \
|
||||
Phi += a1b0 >> MP_HALF_DIGIT_BIT; \
|
||||
if (a1b0 < a0b1) \
|
||||
Phi += MP_HALF_RADIX; \
|
||||
Phi += (MP_CT_LTU(a1b0, a0b1)) << MP_HALF_DIGIT_BIT; \
|
||||
a1b0 <<= MP_HALF_DIGIT_BIT; \
|
||||
Plo += a1b0; \
|
||||
if (Plo < a1b0) \
|
||||
++Phi; \
|
||||
Phi += MP_CT_LTU(Plo, a1b0); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Constant time version of s_mpv_mul_d_add_prop.
|
||||
* Presently, this is only used by the Constant time Montgomery arithmetic code. */
|
||||
/* c += a * b */
|
||||
void
|
||||
s_mpv_mul_d_add_propCT(const mp_digit *a, mp_size a_len, mp_digit b,
|
||||
mp_digit *c, mp_size c_len)
|
||||
{
|
||||
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)
|
||||
mp_digit d = 0;
|
||||
|
||||
c_len -= a_len;
|
||||
/* Inner product: Digits of a */
|
||||
while (a_len--) {
|
||||
mp_word w = ((mp_word)b * *a++) + *c + d;
|
||||
*c++ = ACCUM(w);
|
||||
d = CARRYOUT(w);
|
||||
}
|
||||
|
||||
/* propagate the carry to the end, even if carry is zero */
|
||||
while (c_len--) {
|
||||
mp_word w = (mp_word)*c + d;
|
||||
*c++ = ACCUM(w);
|
||||
d = CARRYOUT(w);
|
||||
}
|
||||
#else
|
||||
mp_digit carry = 0;
|
||||
c_len -= a_len;
|
||||
while (a_len--) {
|
||||
mp_digit a_i = *a++;
|
||||
mp_digit a0b0, a1b1;
|
||||
MP_MUL_DxD(a_i, b, a1b1, a0b0);
|
||||
|
||||
a0b0 += carry;
|
||||
a1b1 += MP_CT_LTU(a0b0, carry);
|
||||
a0b0 += a_i = *c;
|
||||
a1b1 += MP_CT_LTU(a0b0, a_i);
|
||||
|
||||
*c++ = a0b0;
|
||||
carry = a1b1;
|
||||
}
|
||||
/* propagate the carry to the end, even if carry is zero */
|
||||
while (c_len--) {
|
||||
mp_digit c_i = *c;
|
||||
carry += c_i;
|
||||
*c++ = carry;
|
||||
carry = MP_CT_LTU(carry, c_i);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(MP_ASSEMBLY_MULTIPLY)
|
||||
/* c = a * b */
|
||||
void
|
||||
|
|
@ -3979,8 +4243,7 @@ s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
|
|||
MP_MUL_DxD(a_i, b, a1b1, a0b0);
|
||||
|
||||
a0b0 += carry;
|
||||
if (a0b0 < carry)
|
||||
++a1b1;
|
||||
a1b1 += MP_CT_LTU(a0b0, carry);
|
||||
*c++ = a0b0;
|
||||
carry = a1b1;
|
||||
}
|
||||
|
|
@ -4012,11 +4275,9 @@ s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b,
|
|||
MP_MUL_DxD(a_i, b, a1b1, a0b0);
|
||||
|
||||
a0b0 += carry;
|
||||
if (a0b0 < carry)
|
||||
++a1b1;
|
||||
a1b1 += MP_CT_LTU(a0b0, carry);
|
||||
a0b0 += a_i = *c;
|
||||
if (a0b0 < a_i)
|
||||
++a1b1;
|
||||
a1b1 += MP_CT_LTU(a0b0, a_i);
|
||||
*c++ = a0b0;
|
||||
carry = a1b1;
|
||||
}
|
||||
|
|
@ -4081,12 +4342,6 @@ s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
|
|||
Plo = (mp_digit)square; \
|
||||
Phi = (mp_digit)(square >> MP_DIGIT_BIT); \
|
||||
}
|
||||
#elif defined(OSF1)
|
||||
#define MP_SQR_D(a, Phi, Plo) \
|
||||
{ \
|
||||
Plo = asm("mulq %a0, %a0, %v0", a); \
|
||||
Phi = asm("umulh %a0, %a0, %v0", a); \
|
||||
}
|
||||
#else
|
||||
#define MP_SQR_D(a, Phi, Plo) \
|
||||
{ \
|
||||
|
|
@ -4253,9 +4508,10 @@ s_mp_sqr(mp_int *a)
|
|||
Compute a = a / b and b = a mod b. Assumes b > a.
|
||||
*/
|
||||
|
||||
mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */
|
||||
mp_int *div, /* i: divisor */
|
||||
mp_int *quot) /* i: 0; o: quotient */
|
||||
mp_err
|
||||
s_mp_div(mp_int *rem, /* i: dividend, o: remainder */
|
||||
mp_int *div, /* i: divisor */
|
||||
mp_int *quot) /* i: 0; o: quotient */
|
||||
{
|
||||
mp_int part, t;
|
||||
mp_digit q_msd;
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ typedef int mp_err;
|
|||
/* MP_ULONG_LONG_MAX was defined to be ULLONG_MAX */
|
||||
#elif defined(ULONG_LONG_MAX) /* HPUX */
|
||||
#define MP_ULONG_LONG_MAX ULONG_LONG_MAX
|
||||
#elif defined(ULONGLONG_MAX) /* IRIX, AIX */
|
||||
#elif defined(ULONGLONG_MAX) /* AIX */
|
||||
#define MP_ULONG_LONG_MAX ULONGLONG_MAX
|
||||
#endif
|
||||
|
||||
|
|
@ -150,6 +150,38 @@ typedef int mp_sword;
|
|||
/* This defines the maximum I/O base (minimum is 2) */
|
||||
#define MP_MAX_RADIX 64
|
||||
|
||||
/* Constant Time Macros on mp_digits */
|
||||
#define MP_CT_HIGH_TO_LOW(x) ((mp_digit)((mp_digit)(x) >> (MP_DIGIT_BIT - 1)))
|
||||
#define MP_CT_TRUE ((mp_digit)1)
|
||||
#define MP_CT_FALSE ((mp_digit)0)
|
||||
|
||||
/* basic zero and non zero tests */
|
||||
#define MP_CT_NOT_ZERO(x) (MP_CT_HIGH_TO_LOW(((x) | (((mp_digit)0) - (x)))))
|
||||
#define MP_CT_ZERO(x) (MP_CT_TRUE ^ MP_CT_HIGH_TO_LOW(((x) | (((mp_digit)0) - (x)))))
|
||||
|
||||
/* basic constant-time helper macro for equalities and inequalities.
|
||||
* The inequalities will produce incorrect results if
|
||||
* abs(a-b) >= MP_DIGIT_SIZE/2. This can be avoided if unsigned values stay
|
||||
* within the range 0-MP_DIGIT_MAX/2. */
|
||||
#define MP_CT_EQ(a, b) MP_CT_ZERO(((a) ^ (b)))
|
||||
#define MP_CT_NE(a, b) MP_CT_NOT_ZERO(((a) ^ (b)))
|
||||
#define MP_CT_GT(a, b) MP_CT_HIGH_TO_LOW((b) - (a))
|
||||
#define MP_CT_LT(a, b) MP_CT_HIGH_TO_LOW((a) - (b))
|
||||
#define MP_CT_GE(a, b) (MP_CT_TRUE ^ MP_CT_LT(a, b))
|
||||
#define MP_CT_LE(a, b) (MP_CT_TRUE ^ MP_CT_GT(a, b))
|
||||
|
||||
/* use constant time result to select a boolean value
|
||||
* or an mp digit depending on the args */
|
||||
#define MP_CT_SEL(m, l, r) ((r) ^ ((m) & ((r) ^ (l))))
|
||||
#define MP_CT_SELB(m, l, r) MP_CT_SEL(m, l, r) /* mask, l and r are booleans */
|
||||
#define MP_CT_SEL_DIGIT(m, l, r) MP_CT_SEL(m, l, r) /*mask, l, and r are mp_digit */
|
||||
|
||||
/* full inequalities that work with full mp_digit values */
|
||||
#define MP_CT_OVERFLOW(a, b, c, d) \
|
||||
MP_CT_SELB(MP_CT_HIGH_TO_LOW((a) ^ (b)), \
|
||||
(MP_CT_HIGH_TO_LOW(d)), c)
|
||||
#define MP_CT_LTU(a, b) MP_CT_OVERFLOW(a, b, MP_CT_LT(a, b), b)
|
||||
|
||||
typedef struct {
|
||||
mp_sign sign; /* sign of this quantity */
|
||||
mp_size alloc; /* how many digits allocated */
|
||||
|
|
@ -190,7 +222,9 @@ mp_err mp_neg(const mp_int *a, mp_int *b);
|
|||
/* Full arithmetic */
|
||||
mp_err mp_add(const mp_int *a, const mp_int *b, mp_int *c);
|
||||
mp_err mp_sub(const mp_int *a, const mp_int *b, mp_int *c);
|
||||
mp_err mp_subCT(const mp_int *a, mp_int *b, mp_int *c, mp_digit *borrow);
|
||||
mp_err mp_mul(const mp_int *a, const mp_int *b, mp_int *c);
|
||||
mp_err mp_mulCT(mp_int *a, mp_int *b, mp_int *c, mp_size setSize);
|
||||
#if MP_SQUARE
|
||||
mp_err mp_sqr(const mp_int *a, mp_int *b);
|
||||
#else
|
||||
|
|
@ -217,6 +251,12 @@ mp_err mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c);
|
|||
mp_err mp_exptmod_d(const mp_int *a, mp_digit d, const mp_int *m, mp_int *c);
|
||||
#endif /* MP_MODARITH */
|
||||
|
||||
/* montgomery math */
|
||||
mp_err mp_to_mont(const mp_int *x, const mp_int *N, mp_int *xMont);
|
||||
mp_digit mp_calculate_mont_n0i(const mp_int *N);
|
||||
mp_err mp_reduceCT(const mp_int *a, const mp_int *m, mp_digit n0i, mp_int *ct);
|
||||
mp_err mp_mulmontmodCT(mp_int *a, mp_int *b, const mp_int *m, mp_digit n0i, mp_int *c);
|
||||
|
||||
/* Comparisons */
|
||||
int mp_cmp_z(const mp_int *a);
|
||||
int mp_cmp_d(const mp_int *a, mp_digit d);
|
||||
|
|
@ -224,6 +264,7 @@ int mp_cmp(const mp_int *a, const mp_int *b);
|
|||
int mp_cmp_mag(const mp_int *a, const mp_int *b);
|
||||
int mp_isodd(const mp_int *a);
|
||||
int mp_iseven(const mp_int *a);
|
||||
mp_err mp_selectCT(mp_digit cond, const mp_int *a, const mp_int *b, mp_int *ret);
|
||||
|
||||
/* Number theoretic */
|
||||
mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c);
|
||||
|
|
|
|||
|
|
@ -18,7 +18,15 @@
|
|||
# s_mpv_mul_set_vec64(uint64_t *r, uint64_t *a, int len, uint64_t digit)
|
||||
#
|
||||
|
||||
.text; .align 16; .globl s_mpv_mul_set_vec64; .type s_mpv_mul_set_vec64, @function; s_mpv_mul_set_vec64:
|
||||
.text; .align 16; .globl s_mpv_mul_set_vec64;
|
||||
|
||||
#ifdef DARWIN
|
||||
#define s_mpv_mul_set_vec64 _s_mpv_mul_set_vec64
|
||||
.private_extern s_mpv_mul_set_vec64
|
||||
s_mpv_mul_set_vec64:
|
||||
#else
|
||||
.type s_mpv_mul_set_vec64, @function; s_mpv_mul_set_vec64:
|
||||
#endif
|
||||
|
||||
xorq %rax, %rax # if (len == 0) return (0)
|
||||
testq %rdx, %rdx
|
||||
|
|
@ -169,7 +177,9 @@
|
|||
movq %r9, %rax
|
||||
ret
|
||||
|
||||
#ifndef DARWIN
|
||||
.size s_mpv_mul_set_vec64, .-s_mpv_mul_set_vec64
|
||||
#endif
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
#
|
||||
|
|
@ -186,7 +196,15 @@
|
|||
# s_mpv_mul_add_vec64(uint64_t *r, uint64_t *a, int len, uint64_t digit)
|
||||
#
|
||||
|
||||
.text; .align 16; .globl s_mpv_mul_add_vec64; .type s_mpv_mul_add_vec64, @function; s_mpv_mul_add_vec64:
|
||||
.text; .align 16; .globl s_mpv_mul_add_vec64;
|
||||
|
||||
#ifdef DARWIN
|
||||
#define s_mpv_mul_add_vec64 _s_mpv_mul_add_vec64
|
||||
.private_extern s_mpv_mul_add_vec64
|
||||
s_mpv_mul_add_vec64:
|
||||
#else
|
||||
.type s_mpv_mul_add_vec64, @function; s_mpv_mul_add_vec64:
|
||||
#endif
|
||||
|
||||
xorq %rax, %rax # if (len == 0) return (0)
|
||||
testq %rdx, %rdx
|
||||
|
|
@ -381,9 +399,11 @@
|
|||
.L27:
|
||||
movq %r9, %rax
|
||||
ret
|
||||
|
||||
|
||||
#ifndef DARWIN
|
||||
.size s_mpv_mul_add_vec64, .-s_mpv_mul_add_vec64
|
||||
|
||||
# Magic indicating no need for an executable stack
|
||||
.section .note.GNU-stack, "", @progbits
|
||||
.previous
|
||||
#endif
|
||||
|
|
@ -222,10 +222,9 @@ mpl_lsh(const mp_int *a, mp_int *b, mp_digit d)
|
|||
/* {{{ mpl_num_set(a, num) */
|
||||
|
||||
mp_err
|
||||
mpl_num_set(mp_int *a, int *num)
|
||||
mpl_num_set(mp_int *a, unsigned int *num)
|
||||
{
|
||||
unsigned int ix;
|
||||
int db, nset = 0;
|
||||
unsigned int ix, db, nset = 0;
|
||||
mp_digit cur;
|
||||
unsigned char reg;
|
||||
|
||||
|
|
@ -253,10 +252,9 @@ mpl_num_set(mp_int *a, int *num)
|
|||
/* {{{ mpl_num_clear(a, num) */
|
||||
|
||||
mp_err
|
||||
mpl_num_clear(mp_int *a, int *num)
|
||||
mpl_num_clear(mp_int *a, unsigned int *num)
|
||||
{
|
||||
unsigned int ix;
|
||||
int db, nset = 0;
|
||||
unsigned int ix, db, nset = 0;
|
||||
mp_digit cur;
|
||||
unsigned char reg;
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#define _H_MPLOGIC_
|
||||
|
||||
#include "mpi.h"
|
||||
SEC_BEGIN_PROTOS
|
||||
|
||||
/*
|
||||
The logical operations treat an mp_int as if it were a bit vector,
|
||||
|
|
@ -38,9 +39,9 @@ mp_err mpl_lsh(const mp_int *a, mp_int *b, mp_digit d); /* left shift */
|
|||
|
||||
/* Bit count and parity */
|
||||
|
||||
mp_err mpl_num_set(mp_int *a, int *num); /* count set bits */
|
||||
mp_err mpl_num_clear(mp_int *a, int *num); /* count clear bits */
|
||||
mp_err mpl_parity(mp_int *a); /* determine parity */
|
||||
mp_err mpl_num_set(mp_int *a, unsigned int *num); /* count set bits */
|
||||
mp_err mpl_num_clear(mp_int *a, unsigned int *num); /* count clear bits */
|
||||
mp_err mpl_parity(mp_int *a); /* determine parity */
|
||||
|
||||
/* Get & Set the value of a bit */
|
||||
|
||||
|
|
@ -49,4 +50,6 @@ mp_err mpl_get_bit(const mp_int *a, mp_size bitNum);
|
|||
mp_err mpl_get_bits(const mp_int *a, mp_size lsbNum, mp_size numBits);
|
||||
mp_size mpl_significant_bits(const mp_int *a);
|
||||
|
||||
SEC_END_PROTOS
|
||||
|
||||
#endif /* end _H_MPLOGIC_ */
|
||||
|
|
|
|||
|
|
@ -129,20 +129,27 @@ CLEANUP:
|
|||
}
|
||||
#endif
|
||||
|
||||
STATIC
|
||||
mp_err
|
||||
s_mp_to_mont(const mp_int *x, mp_mont_modulus *mmm, mp_int *xMont)
|
||||
mp_to_mont(const mp_int *x, const mp_int *N, mp_int *xMont)
|
||||
{
|
||||
mp_err res;
|
||||
|
||||
/* xMont = x * R mod N where N is modulus */
|
||||
MP_CHECKOK(mp_copy(x, xMont));
|
||||
MP_CHECKOK(s_mp_lshd(xMont, MP_USED(&mmm->N))); /* xMont = x << b */
|
||||
MP_CHECKOK(mp_div(xMont, &mmm->N, 0, xMont)); /* mod N */
|
||||
if (x != xMont) {
|
||||
MP_CHECKOK(mp_copy(x, xMont));
|
||||
}
|
||||
MP_CHECKOK(s_mp_lshd(xMont, MP_USED(N))); /* xMont = x << b */
|
||||
MP_CHECKOK(mp_div(xMont, N, 0, xMont)); /* mod N */
|
||||
CLEANUP:
|
||||
return res;
|
||||
}
|
||||
|
||||
mp_digit
|
||||
mp_calculate_mont_n0i(const mp_int *N)
|
||||
{
|
||||
return 0 - s_mp_invmod_radix(MP_DIGIT(N, 0));
|
||||
}
|
||||
|
||||
#ifdef MP_USING_MONT_MULF
|
||||
|
||||
/* the floating point multiply is already cache safe,
|
||||
|
|
@ -198,7 +205,7 @@ mp_exptmod_f(const mp_int *montBase,
|
|||
MP_CHECKOK(mp_init_size(&accum1, 3 * nLen + 2));
|
||||
|
||||
mp_set(&accum1, 1);
|
||||
MP_CHECKOK(s_mp_to_mont(&accum1, mmm, &accum1));
|
||||
MP_CHECKOK(mp_to_mont(&accum1, &(mmm->N), &accum1));
|
||||
MP_CHECKOK(s_mp_pad(&accum1, nLen));
|
||||
|
||||
oddPowSize = 2 * nLen + 1;
|
||||
|
|
@ -478,7 +485,7 @@ mp_exptmod_i(const mp_int *montBase,
|
|||
|
||||
/* set accumulator to montgomery residue of 1 */
|
||||
mp_set(&accum1, 1);
|
||||
MP_CHECKOK(s_mp_to_mont(&accum1, mmm, &accum1));
|
||||
MP_CHECKOK(mp_to_mont(&accum1, &(mmm->N), &accum1));
|
||||
pa1 = &accum1;
|
||||
pa2 = &accum2;
|
||||
|
||||
|
|
@ -723,10 +730,11 @@ mp_set_safe_modexp(int value)
|
|||
* mp_ints that use less than nDigits digits are logically padded with zeros
|
||||
* while being stored in the weaved array.
|
||||
*/
|
||||
mp_err mpi_to_weave(const mp_int *bignums,
|
||||
mp_digit *weaved,
|
||||
mp_size nDigits, /* in each mp_int of input */
|
||||
mp_size nBignums) /* in the entire source array */
|
||||
mp_err
|
||||
mpi_to_weave(const mp_int *bignums,
|
||||
mp_digit *weaved,
|
||||
mp_size nDigits, /* in each mp_int of input */
|
||||
mp_size nBignums) /* in the entire source array */
|
||||
{
|
||||
mp_size i;
|
||||
mp_digit *endDest = weaved + (nDigits * nBignums);
|
||||
|
|
@ -765,11 +773,12 @@ mp_err mpi_to_weave(const mp_int *bignums,
|
|||
* Every read accesses every element of the weaved array, in order to
|
||||
* avoid timing attacks based on patterns of memory accesses.
|
||||
*/
|
||||
mp_err weave_to_mpi(mp_int *a, /* out, result */
|
||||
const mp_digit *weaved, /* in, byte matrix */
|
||||
mp_size index, /* which column to read */
|
||||
mp_size nDigits, /* number of mp_digits in each bignum */
|
||||
mp_size nBignums) /* width of the matrix */
|
||||
mp_err
|
||||
weave_to_mpi(mp_int *a, /* out, result */
|
||||
const mp_digit *weaved, /* in, byte matrix */
|
||||
mp_size index, /* which column to read */
|
||||
mp_size nDigits, /* number of mp_digits in each bignum */
|
||||
mp_size nBignums) /* width of the matrix */
|
||||
{
|
||||
/* these are indices, but need to be the same size as mp_digit
|
||||
* because of the CONST_TIME operations */
|
||||
|
|
@ -865,7 +874,7 @@ mp_exptmod_safe_i(const mp_int *montBase,
|
|||
MP_CHECKOK(mp_init_size(&accum[2], 3 * nLen + 2));
|
||||
MP_CHECKOK(mp_init_size(&accum[3], 3 * nLen + 2));
|
||||
mp_set(&accum[0], 1);
|
||||
MP_CHECKOK(s_mp_to_mont(&accum[0], mmm, &accum[0]));
|
||||
MP_CHECKOK(mp_to_mont(&accum[0], &(mmm->N), &accum[0]));
|
||||
MP_CHECKOK(mp_copy(montBase, &accum[1]));
|
||||
SQR(montBase, &accum[2]);
|
||||
MUL_NOWEAVE(montBase, &accum[2], &accum[3]);
|
||||
|
|
@ -884,7 +893,7 @@ mp_exptmod_safe_i(const mp_int *montBase,
|
|||
} else {
|
||||
if (first_window == 0) {
|
||||
mp_set(&accum1, 1);
|
||||
MP_CHECKOK(s_mp_to_mont(&accum1, mmm, &accum1));
|
||||
MP_CHECKOK(mp_to_mont(&accum1, &(mmm->N), &accum1));
|
||||
} else {
|
||||
/* assert first_window == 1? */
|
||||
MP_CHECKOK(mp_copy(montBase, &accum1));
|
||||
|
|
@ -1006,7 +1015,11 @@ CLEANUP:
|
|||
mp_clear(&accum[2]);
|
||||
mp_clear(&accum[3]);
|
||||
mp_clear(&tmp);
|
||||
/* PORT_Memset(powers,0,num_powers*nLen*sizeof(mp_digit)); */
|
||||
/* zero required by FIPS here, can't use PORT_ZFree
|
||||
* because mpi doesn't link with util */
|
||||
if (powers) {
|
||||
PORT_Memset(powers, 0, num_powers * sizeof(mp_digit));
|
||||
}
|
||||
free(powersArray);
|
||||
return res;
|
||||
}
|
||||
|
|
@ -1051,9 +1064,9 @@ mp_exptmod(const mp_int *inBase, const mp_int *exponent,
|
|||
/* compute n0', given n0, n0' = -(n0 ** -1) mod MP_RADIX
|
||||
** where n0 = least significant mp_digit of N, the modulus.
|
||||
*/
|
||||
mmm.n0prime = 0 - s_mp_invmod_radix(MP_DIGIT(modulus, 0));
|
||||
mmm.n0prime = mp_calculate_mont_n0i(modulus);
|
||||
|
||||
MP_CHECKOK(s_mp_to_mont(base, &mmm, &montBase));
|
||||
MP_CHECKOK(mp_to_mont(base, modulus, &montBase));
|
||||
|
||||
bits_in_exponent = mpl_significant_bits(exponent);
|
||||
#ifdef MP_USING_CACHE_SAFE_MOD_EXP
|
||||
|
|
|
|||
|
|
@ -126,6 +126,8 @@ mpp_random(mp_int *a)
|
|||
|
||||
/* }}} */
|
||||
|
||||
static mpp_random_fn mpp_random_insecure = &mpp_random;
|
||||
|
||||
/* {{{ mpp_random_size(a, prec) */
|
||||
|
||||
mp_err
|
||||
|
|
@ -138,7 +140,7 @@ mpp_random_size(mp_int *a, mp_size prec)
|
|||
if ((res = s_mp_pad(a, prec)) != MP_OKAY)
|
||||
return res;
|
||||
|
||||
return mpp_random(a);
|
||||
return (*mpp_random_insecure)(a);
|
||||
|
||||
} /* end mpp_random_size() */
|
||||
|
||||
|
|
@ -271,6 +273,12 @@ mpp_fermat_list(mp_int *a, const mp_digit *primes, mp_size nPrimes)
|
|||
|
||||
mp_err
|
||||
mpp_pprime(mp_int *a, int nt)
|
||||
{
|
||||
return mpp_pprime_ext_random(a, nt, mpp_random_insecure);
|
||||
}
|
||||
|
||||
mp_err
|
||||
mpp_pprime_ext_random(mp_int *a, int nt, mpp_random_fn random)
|
||||
{
|
||||
mp_err res;
|
||||
mp_int x, amo, m, z; /* "amo" = "a minus one" */
|
||||
|
|
@ -306,7 +314,7 @@ mpp_pprime(mp_int *a, int nt)
|
|||
|
||||
/* Choose a random value for 1 < x < a */
|
||||
MP_CHECKOK(s_mp_pad(&x, USED(a)));
|
||||
mpp_random(&x);
|
||||
MP_CHECKOK((*random)(&x));
|
||||
MP_CHECKOK(mp_mod(&x, a, &x));
|
||||
if (mp_cmp_d(&x, 1) <= 0) {
|
||||
iter--; /* don't count this iteration */
|
||||
|
|
@ -403,6 +411,12 @@ mpp_sieve(mp_int *trial, const mp_digit *primes, mp_size nPrimes,
|
|||
|
||||
mp_err
|
||||
mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong)
|
||||
{
|
||||
return mpp_make_prime_ext_random(start, nBits, strong, mpp_random_insecure);
|
||||
}
|
||||
|
||||
mp_err
|
||||
mpp_make_prime_ext_random(mp_int *start, mp_size nBits, mp_size strong, mpp_random_fn random)
|
||||
{
|
||||
mp_digit np;
|
||||
mp_err res;
|
||||
|
|
@ -490,7 +504,7 @@ mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong)
|
|||
|
||||
FPUTC('+', stderr);
|
||||
/* If that passed, run some Miller-Rabin tests */
|
||||
res = mpp_pprime(&trial, num_tests);
|
||||
res = mpp_pprime_ext_random(&trial, num_tests, random);
|
||||
if (res != MP_OKAY) {
|
||||
if (res == MP_NO)
|
||||
continue; /* was composite */
|
||||
|
|
@ -528,7 +542,7 @@ mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong)
|
|||
}
|
||||
|
||||
/* And test with Miller-Rabin, as with its parent ... */
|
||||
res = mpp_pprime(&q, num_tests);
|
||||
res = mpp_pprime_ext_random(&q, num_tests, random);
|
||||
if (res != MP_YES) {
|
||||
mp_clear(&q);
|
||||
if (res == MP_NO)
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@ mp_err mpp_divis_d(mp_int *a, mp_digit d);
|
|||
mp_err mpp_random(mp_int *a);
|
||||
mp_err mpp_random_size(mp_int *a, mp_size prec);
|
||||
|
||||
/* Type for a pointer to a user-provided mpp_random implementation */
|
||||
typedef mp_err (*mpp_random_fn)(mp_int *);
|
||||
|
||||
/* Pseudo-primality testing */
|
||||
mp_err mpp_divis_vector(mp_int *a, const mp_digit *vec, int size, int *which);
|
||||
mp_err mpp_divis_primes(mp_int *a, mp_digit *np);
|
||||
|
|
@ -36,6 +39,10 @@ mp_err mpp_sieve(mp_int *trial, const mp_digit *primes, mp_size nPrimes,
|
|||
unsigned char *sieve, mp_size nSieve);
|
||||
mp_err mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong);
|
||||
|
||||
/* Pseudo-primality tests using a user-provided mpp_random implementation */
|
||||
mp_err mpp_pprime_ext_random(mp_int *a, int nt, mpp_random_fn random);
|
||||
mp_err mpp_make_prime_ext_random(mp_int *start, mp_size nBits, mp_size strong, mpp_random_fn random);
|
||||
|
||||
SEC_END_PROTOS
|
||||
|
||||
#endif /* end _H_MP_PRIME_ */
|
||||
|
|
|
|||
|
|
@ -836,6 +836,6 @@ const mp_digit prime_tab[] = {
|
|||
0xFE95, 0xFE9B, 0xFE9F, 0xFEB3, 0xFEBD, 0xFED7, 0xFEE9, 0xFEF3,
|
||||
0xFEF5, 0xFF07, 0xFF0D, 0xFF1D, 0xFF2B, 0xFF2F, 0xFF49, 0xFF4D,
|
||||
0xFF5B, 0xFF65, 0xFF71, 0xFF7F, 0xFF85, 0xFF8B, 0xFF8F, 0xFF9D,
|
||||
0xFFA7, 0xFFA9, 0xFFC7, 0xFFD9, 0xFFEF, 0xFFF1,
|
||||
0xFFA7, 0xFFA9, 0xFFC7, 0xFFD9, 0xFFEF, 0xFFF1
|
||||
#endif
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include "stubs.h"
|
||||
#endif
|
||||
#include "prtypes.h"
|
||||
#include "prenv.h"
|
||||
#include "secerr.h"
|
||||
#include "blapi.h"
|
||||
#include "hasht.h"
|
||||
|
|
@ -30,6 +31,12 @@ nsslow_GetFIPSEnabled(void)
|
|||
FILE *f;
|
||||
char d;
|
||||
size_t size;
|
||||
const char *env;
|
||||
|
||||
env = PR_GetEnvSecure("NSS_FIPS");
|
||||
if (env && (*env == 'y' || *env == 'f' || *env == '1' || *env == 't')) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
f = fopen("/proc/sys/crypto/fips_enabled", "r");
|
||||
if (!f)
|
||||
|
|
@ -60,7 +67,7 @@ NSSLOW_Init(void)
|
|||
/* make sure the FIPS product is installed if we are trying to
|
||||
* go into FIPS mode */
|
||||
if (nsslow_GetFIPSEnabled()) {
|
||||
if (BL_FIPSEntryOK(PR_TRUE) != SECSuccess) {
|
||||
if (BL_FIPSEntryOK(PR_TRUE, PR_FALSE) != SECSuccess) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
post_failed = PR_TRUE;
|
||||
return NULL;
|
||||
|
|
|
|||
31
security/nss/lib/freebl/ppc-crypto.h
Normal file
31
security/nss/lib/freebl/ppc-crypto.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef PPC_CRYPTO_H
|
||||
#define PPC_CRYPTO_H 1
|
||||
|
||||
#if defined(__powerpc64__) && defined(__ALTIVEC__) && \
|
||||
!defined(NSS_DISABLE_ALTIVEC)
|
||||
#include "altivec-types.h"
|
||||
|
||||
/* The ghash freebl test tries to use this in C++, and gcc defines conflict. */
|
||||
#ifdef __cplusplus
|
||||
#undef pixel
|
||||
#undef vector
|
||||
#undef bool
|
||||
#endif
|
||||
|
||||
/*
|
||||
* PPC CRYPTO requires at least gcc 8 or clang. The LE check is purely
|
||||
* because it's only been tested on LE. If you're interested in BE,
|
||||
* please send a patch.
|
||||
*/
|
||||
#if (defined(__clang__) || (defined(__GNUC__) && __GNUC__ >= 8)) && \
|
||||
defined(IS_LITTLE_ENDIAN) && defined(__VSX__)
|
||||
#define USE_PPC_CRYPTO
|
||||
#endif
|
||||
|
||||
#endif /* defined(__powerpc64__) && !defined(NSS_DISABLE_ALTIVEC) && defined(__ALTIVEC__) */
|
||||
|
||||
#endif
|
||||
458
security/nss/lib/freebl/ppc-gcm-wrap.c
Normal file
458
security/nss/lib/freebl/ppc-gcm-wrap.c
Normal file
|
|
@ -0,0 +1,458 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/* Copyright(c) 2013, Intel Corp. */
|
||||
|
||||
/* Wrapper functions for PowerPC optimized implementation of AES-GCM */
|
||||
|
||||
#ifdef FREEBL_NO_DEPEND
|
||||
#include "stubs.h"
|
||||
#endif
|
||||
|
||||
#include "blapii.h"
|
||||
#include "blapit.h"
|
||||
#include "gcm.h"
|
||||
#include "ctr.h"
|
||||
#include "secerr.h"
|
||||
#include "prtypes.h"
|
||||
#include "pkcs11t.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ppc-gcm.h"
|
||||
#include "rijndael.h"
|
||||
|
||||
struct ppc_AES_GCMContextStr {
|
||||
unsigned char Htbl[8 * AES_BLOCK_SIZE];
|
||||
unsigned char X0[AES_BLOCK_SIZE];
|
||||
unsigned char T[AES_BLOCK_SIZE];
|
||||
unsigned char CTR[AES_BLOCK_SIZE];
|
||||
AESContext *aes_context;
|
||||
unsigned long tagBits;
|
||||
unsigned long Alen;
|
||||
unsigned long Mlen;
|
||||
freeblCipherFunc cipher;
|
||||
PRBool ctr_context_init;
|
||||
gcmIVContext gcm_iv;
|
||||
};
|
||||
|
||||
SECStatus ppc_aes_gcmInitCounter(ppc_AES_GCMContext *gcm,
|
||||
const unsigned char *iv,
|
||||
unsigned long ivLen, unsigned long tagBits,
|
||||
const unsigned char *aad, unsigned long aadLen);
|
||||
|
||||
ppc_AES_GCMContext *
|
||||
ppc_AES_GCM_CreateContext(void *context,
|
||||
freeblCipherFunc cipher,
|
||||
const unsigned char *params)
|
||||
{
|
||||
ppc_AES_GCMContext *gcm = NULL;
|
||||
AESContext *aes = (AESContext *)context;
|
||||
const CK_NSS_GCM_PARAMS *gcmParams = (const CK_NSS_GCM_PARAMS *)params;
|
||||
SECStatus rv;
|
||||
|
||||
gcm = PORT_ZNew(ppc_AES_GCMContext);
|
||||
if (gcm == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* initialize context fields */
|
||||
gcm->aes_context = aes;
|
||||
gcm->cipher = cipher;
|
||||
gcm->Alen = 0;
|
||||
gcm->Mlen = 0;
|
||||
gcm->ctr_context_init = PR_FALSE;
|
||||
|
||||
/* first prepare H and its derivatives for ghash */
|
||||
ppc_aes_gcmINIT(gcm->Htbl, aes->k.expandedKey, aes->Nr);
|
||||
|
||||
gcm_InitIVContext(&gcm->gcm_iv);
|
||||
|
||||
/* if gcmParams is NULL, then we are creating an PKCS #11 MESSAGE
|
||||
* style context, in which we initialize the key once, then do separate
|
||||
* iv/aad's for each message. If we are doing that kind of operation,
|
||||
* we've finished with init here. We'll init the Counter in each AEAD
|
||||
* call */
|
||||
if (gcmParams == NULL) {
|
||||
return gcm;
|
||||
}
|
||||
|
||||
rv = ppc_aes_gcmInitCounter(gcm, gcmParams->pIv,
|
||||
gcmParams->ulIvLen, gcmParams->ulTagBits,
|
||||
gcmParams->pAAD, gcmParams->ulAADLen);
|
||||
if (rv != SECSuccess) {
|
||||
PORT_Free(gcm);
|
||||
return NULL;
|
||||
}
|
||||
gcm->ctr_context_init = PR_TRUE;
|
||||
|
||||
return gcm;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
ppc_aes_gcmInitCounter(ppc_AES_GCMContext *gcm,
|
||||
const unsigned char *iv, unsigned long ivLen,
|
||||
unsigned long tagBits,
|
||||
const unsigned char *aad, unsigned long aadLen)
|
||||
{
|
||||
unsigned int j;
|
||||
SECStatus rv;
|
||||
|
||||
if (ivLen == 0) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (tagBits != 128 && tagBits != 120 && tagBits != 112 &&
|
||||
tagBits != 104 && tagBits != 96 && tagBits != 64 &&
|
||||
tagBits != 32) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
gcm->tagBits = tagBits;
|
||||
|
||||
/* reset the aad and message length counters */
|
||||
gcm->Alen = 0;
|
||||
gcm->Mlen = 0;
|
||||
|
||||
/* Initial TAG value is zero */
|
||||
PORT_Memset(gcm->T, 0, AES_BLOCK_SIZE);
|
||||
PORT_Memset(gcm->X0, 0, AES_BLOCK_SIZE);
|
||||
|
||||
/* Init the counter */
|
||||
if (ivLen == 12) {
|
||||
PORT_Memcpy(gcm->CTR, iv, AES_BLOCK_SIZE - 4);
|
||||
gcm->CTR[12] = 0;
|
||||
gcm->CTR[13] = 0;
|
||||
gcm->CTR[14] = 0;
|
||||
gcm->CTR[15] = 1;
|
||||
} else {
|
||||
/* If IV size is not 96 bits, then the initial counter value is GHASH
|
||||
* of the IV */
|
||||
ppc_aes_gcmHASH(gcm->Htbl, iv, ivLen, gcm->T);
|
||||
|
||||
ppc_aes_gcmTAG(
|
||||
gcm->Htbl,
|
||||
gcm->T,
|
||||
ivLen,
|
||||
0,
|
||||
gcm->X0,
|
||||
gcm->CTR);
|
||||
|
||||
/* TAG should be zero again */
|
||||
PORT_Memset(gcm->T, 0, AES_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
/* Encrypt the initial counter, will be used to encrypt the GHASH value,
|
||||
* in the end */
|
||||
rv = (*gcm->cipher)(gcm->aes_context, gcm->X0, &j, AES_BLOCK_SIZE, gcm->CTR,
|
||||
AES_BLOCK_SIZE, AES_BLOCK_SIZE);
|
||||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* Promote the counter by 1 */
|
||||
gcm->CTR[14] += !(++gcm->CTR[15]);
|
||||
gcm->CTR[13] += !(gcm->CTR[15]) && !(gcm->CTR[14]);
|
||||
gcm->CTR[12] += !(gcm->CTR[15]) && !(gcm->CTR[14]) && !(gcm->CTR[13]);
|
||||
|
||||
/* Now hash AAD - it would actually make sense to seperate the context
|
||||
* creation from the AAD, because that would allow to reuse the H, which
|
||||
* only changes when the AES key changes, and not every package, like the
|
||||
* IV and AAD */
|
||||
ppc_aes_gcmHASH(gcm->Htbl, aad, aadLen, gcm->T);
|
||||
gcm->Alen += aadLen;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
void
|
||||
ppc_AES_GCM_DestroyContext(ppc_AES_GCMContext *gcm, PRBool freeit)
|
||||
{
|
||||
PORT_Memset(gcm, 0, sizeof(ppc_AES_GCMContext));
|
||||
if (freeit) {
|
||||
PORT_Free(gcm);
|
||||
}
|
||||
}
|
||||
|
||||
SECStatus
|
||||
ppc_AES_GCM_EncryptUpdate(ppc_AES_GCMContext *gcm,
|
||||
unsigned char *outbuf,
|
||||
unsigned int *outlen, unsigned int maxout,
|
||||
const unsigned char *inbuf, unsigned int inlen,
|
||||
unsigned int blocksize)
|
||||
{
|
||||
unsigned int tagBytes;
|
||||
unsigned char T[AES_BLOCK_SIZE];
|
||||
unsigned int j;
|
||||
|
||||
// GCM has a 16 octet block, with a 32-bit block counter
|
||||
// Limit in accordance with SP800-38D
|
||||
if (sizeof(inlen) > 4 &&
|
||||
inlen >= ((1ULL << 32) - 2) * AES_BLOCK_SIZE) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (!gcm->ctr_context_init) {
|
||||
PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE;
|
||||
if (UINT_MAX - inlen < tagBytes) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
if (maxout < inlen + tagBytes) {
|
||||
*outlen = inlen + tagBytes;
|
||||
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
ppc_aes_gcmCRYPT(
|
||||
inbuf,
|
||||
outbuf,
|
||||
inlen,
|
||||
gcm->CTR,
|
||||
gcm->aes_context->k.expandedKey,
|
||||
gcm->aes_context->Nr);
|
||||
ppc_aes_gcmHASH(
|
||||
gcm->Htbl,
|
||||
outbuf,
|
||||
inlen,
|
||||
gcm->T);
|
||||
|
||||
gcm->Mlen += inlen;
|
||||
|
||||
ppc_aes_gcmTAG(
|
||||
gcm->Htbl,
|
||||
gcm->T,
|
||||
gcm->Mlen,
|
||||
gcm->Alen,
|
||||
gcm->X0,
|
||||
T);
|
||||
|
||||
*outlen = inlen + tagBytes;
|
||||
|
||||
for (j = 0; j < tagBytes; j++) {
|
||||
outbuf[inlen + j] = T[j];
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
ppc_AES_GCM_DecryptUpdate(ppc_AES_GCMContext *gcm,
|
||||
unsigned char *outbuf,
|
||||
unsigned int *outlen, unsigned int maxout,
|
||||
const unsigned char *inbuf, unsigned int inlen,
|
||||
unsigned int blocksize)
|
||||
{
|
||||
unsigned int tagBytes;
|
||||
unsigned char T[AES_BLOCK_SIZE];
|
||||
const unsigned char *intag;
|
||||
|
||||
if (!gcm->ctr_context_init) {
|
||||
PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE;
|
||||
|
||||
/* get the authentication block */
|
||||
if (inlen < tagBytes) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
inlen -= tagBytes;
|
||||
intag = inbuf + inlen;
|
||||
|
||||
// GCM has a 16 octet block, with a 32-bit block counter
|
||||
// Limit in accordance with SP800-38D
|
||||
if (sizeof(inlen) > 4 &&
|
||||
inlen >= ((1ULL << 32) - 2) * AES_BLOCK_SIZE) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (maxout < inlen) {
|
||||
*outlen = inlen;
|
||||
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
ppc_aes_gcmHASH(
|
||||
gcm->Htbl,
|
||||
inbuf,
|
||||
inlen,
|
||||
gcm->T);
|
||||
ppc_aes_gcmCRYPT(
|
||||
inbuf,
|
||||
outbuf,
|
||||
inlen,
|
||||
gcm->CTR,
|
||||
gcm->aes_context->k.expandedKey,
|
||||
gcm->aes_context->Nr);
|
||||
|
||||
gcm->Mlen += inlen;
|
||||
ppc_aes_gcmTAG(
|
||||
gcm->Htbl,
|
||||
gcm->T,
|
||||
gcm->Mlen,
|
||||
gcm->Alen,
|
||||
gcm->X0,
|
||||
T);
|
||||
|
||||
if (NSS_SecureMemcmp(T, intag, tagBytes) != 0) {
|
||||
memset(outbuf, 0, inlen);
|
||||
*outlen = 0;
|
||||
/* force a CKR_ENCRYPTED_DATA_INVALID error at in softoken */
|
||||
PORT_SetError(SEC_ERROR_BAD_DATA);
|
||||
return SECFailure;
|
||||
}
|
||||
*outlen = inlen;
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
ppc_AES_GCM_EncryptAEAD(ppc_AES_GCMContext *gcm,
|
||||
unsigned char *outbuf,
|
||||
unsigned int *outlen, unsigned int maxout,
|
||||
const unsigned char *inbuf, unsigned int inlen,
|
||||
void *params, unsigned int paramLen,
|
||||
const unsigned char *aad, unsigned int aadLen,
|
||||
unsigned int blocksize)
|
||||
{
|
||||
unsigned int tagBytes;
|
||||
unsigned char T[AES_BLOCK_SIZE];
|
||||
const CK_GCM_MESSAGE_PARAMS *gcmParams =
|
||||
(const CK_GCM_MESSAGE_PARAMS *)params;
|
||||
SECStatus rv;
|
||||
|
||||
// GCM has a 16 octet block, with a 32-bit block counter
|
||||
// Limit in accordance with SP800-38D
|
||||
if (sizeof(inlen) > 4 &&
|
||||
inlen >= ((1ULL << 32) - 2) * AES_BLOCK_SIZE) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
/* paramLen comes all the way from the application layer, make sure
|
||||
* it's correct */
|
||||
if (paramLen != sizeof(CK_GCM_MESSAGE_PARAMS)) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* if we were initialized with the C_EncryptInit, we shouldn't be in this
|
||||
* function */
|
||||
if (gcm->ctr_context_init) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (maxout < inlen) {
|
||||
*outlen = inlen;
|
||||
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
rv = gcm_GenerateIV(&gcm->gcm_iv, gcmParams->pIv, gcmParams->ulIvLen,
|
||||
gcmParams->ulIvFixedBits, gcmParams->ivGenerator);
|
||||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
rv = ppc_aes_gcmInitCounter(gcm, gcmParams->pIv, gcmParams->ulIvLen,
|
||||
gcmParams->ulTagBits, aad, aadLen);
|
||||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE;
|
||||
|
||||
ppc_aes_gcmCRYPT(inbuf, outbuf, inlen, gcm->CTR, gcm->aes_context->k.expandedKey,
|
||||
gcm->aes_context->Nr);
|
||||
ppc_aes_gcmHASH(gcm->Htbl, outbuf, inlen, gcm->T);
|
||||
|
||||
gcm->Mlen += inlen;
|
||||
|
||||
ppc_aes_gcmTAG(gcm->Htbl, gcm->T, gcm->Mlen, gcm->Alen, gcm->X0, T);
|
||||
|
||||
*outlen = inlen;
|
||||
PORT_Memcpy(gcmParams->pTag, T, tagBytes);
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
ppc_AES_GCM_DecryptAEAD(ppc_AES_GCMContext *gcm,
|
||||
unsigned char *outbuf,
|
||||
unsigned int *outlen, unsigned int maxout,
|
||||
const unsigned char *inbuf, unsigned int inlen,
|
||||
void *params, unsigned int paramLen,
|
||||
const unsigned char *aad, unsigned int aadLen,
|
||||
unsigned int blocksize)
|
||||
{
|
||||
unsigned int tagBytes;
|
||||
unsigned char T[AES_BLOCK_SIZE];
|
||||
const unsigned char *intag;
|
||||
const CK_GCM_MESSAGE_PARAMS *gcmParams =
|
||||
(const CK_GCM_MESSAGE_PARAMS *)params;
|
||||
SECStatus rv;
|
||||
|
||||
/* paramLen comes all the way from the application layer, make sure
|
||||
* it's correct */
|
||||
if (paramLen != sizeof(CK_GCM_MESSAGE_PARAMS)) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
/* if we were initialized with the C_DecryptInit, we shouldn't be in this
|
||||
* function */
|
||||
if (gcm->ctr_context_init) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
// GCM has a 16 octet block, with a 32-bit block counter
|
||||
// Limit in accordance with SP800-38D
|
||||
if (sizeof(inlen) > 4 &&
|
||||
inlen >= ((1ULL << 32) - 2) * AES_BLOCK_SIZE) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (maxout < inlen) {
|
||||
*outlen = inlen;
|
||||
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
rv = ppc_aes_gcmInitCounter(gcm, gcmParams->pIv, gcmParams->ulIvLen,
|
||||
gcmParams->ulTagBits, aad, aadLen);
|
||||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE;
|
||||
intag = gcmParams->pTag;
|
||||
PORT_Assert(tagBytes != 0);
|
||||
|
||||
ppc_aes_gcmHASH(gcm->Htbl, inbuf, inlen, gcm->T);
|
||||
ppc_aes_gcmCRYPT(inbuf, outbuf, inlen, gcm->CTR, gcm->aes_context->k.expandedKey,
|
||||
gcm->aes_context->Nr);
|
||||
|
||||
gcm->Mlen += inlen;
|
||||
ppc_aes_gcmTAG(gcm->Htbl, gcm->T, gcm->Mlen, gcm->Alen, gcm->X0, T);
|
||||
|
||||
if (NSS_SecureMemcmp(T, intag, tagBytes) != 0) {
|
||||
memset(outbuf, 0, inlen);
|
||||
*outlen = 0;
|
||||
/* force a CKR_ENCRYPTED_DATA_INVALID error at in softoken */
|
||||
PORT_SetError(SEC_ERROR_BAD_DATA);
|
||||
return SECFailure;
|
||||
}
|
||||
*outlen = inlen;
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
76
security/nss/lib/freebl/ppc-gcm.h
Normal file
76
security/nss/lib/freebl/ppc-gcm.h
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/******************************************************************************/
|
||||
/* LICENSE: */
|
||||
/* This submission to NSS is to be made available under the terms of the */
|
||||
/* Mozilla Public License, v. 2.0. You can obtain one at http: */
|
||||
/* //mozilla.org/MPL/2.0/. */
|
||||
/******************************************************************************/
|
||||
|
||||
#ifndef PPC_GCM_H
|
||||
#define PPC_GCM_H 1
|
||||
|
||||
#include "blapii.h"
|
||||
|
||||
typedef struct ppc_AES_GCMContextStr ppc_AES_GCMContext;
|
||||
|
||||
ppc_AES_GCMContext *ppc_AES_GCM_CreateContext(void *context, freeblCipherFunc cipher,
|
||||
const unsigned char *params);
|
||||
|
||||
void ppc_AES_GCM_DestroyContext(ppc_AES_GCMContext *gcm, PRBool freeit);
|
||||
|
||||
SECStatus ppc_AES_GCM_EncryptUpdate(ppc_AES_GCMContext *gcm, unsigned char *outbuf,
|
||||
unsigned int *outlen, unsigned int maxout,
|
||||
const unsigned char *inbuf, unsigned int inlen,
|
||||
unsigned int blocksize);
|
||||
|
||||
SECStatus ppc_AES_GCM_DecryptUpdate(ppc_AES_GCMContext *gcm, unsigned char *outbuf,
|
||||
unsigned int *outlen, unsigned int maxout,
|
||||
const unsigned char *inbuf, unsigned int inlen,
|
||||
unsigned int blocksize);
|
||||
SECStatus ppc_AES_GCM_EncryptAEAD(ppc_AES_GCMContext *gcm,
|
||||
unsigned char *outbuf,
|
||||
unsigned int *outlen, unsigned int maxout,
|
||||
const unsigned char *inbuf, unsigned int inlen,
|
||||
void *params, unsigned int paramLen,
|
||||
const unsigned char *aad, unsigned int aadLen,
|
||||
unsigned int blocksize);
|
||||
SECStatus ppc_AES_GCM_DecryptAEAD(ppc_AES_GCMContext *gcm,
|
||||
unsigned char *outbuf,
|
||||
unsigned int *outlen, unsigned int maxout,
|
||||
const unsigned char *inbuf, unsigned int inlen,
|
||||
void *params, unsigned int paramLen,
|
||||
const unsigned char *aad, unsigned int aadLen,
|
||||
unsigned int blocksize);
|
||||
|
||||
/* Prototypes of the functions defined in the assembler file. */
|
||||
|
||||
/* Prepares the constants used in the aggregated reduction method */
|
||||
void ppc_aes_gcmINIT(unsigned char Htbl[8 * 16],
|
||||
PRUint32 *KS,
|
||||
int NR);
|
||||
|
||||
/* Produces the final GHASH value */
|
||||
void ppc_aes_gcmTAG(unsigned char Htbl[8 * 16],
|
||||
unsigned char *Tp,
|
||||
unsigned long Mlen,
|
||||
unsigned long Alen,
|
||||
unsigned char *X0,
|
||||
unsigned char *TAG);
|
||||
|
||||
/* Hashes the Additional Authenticated Data, should be used before enc/dec.
|
||||
Operates on any length of data. Partial block is padded internally. */
|
||||
void ppc_aes_gcmHASH(unsigned char Htbl[8 * 16],
|
||||
const unsigned char *AAD,
|
||||
unsigned long Alen,
|
||||
unsigned char *Tp);
|
||||
|
||||
/* Crypt only, used in combination with ppc_aes_gcmAAD().
|
||||
Operates on any length of data, however partial block should only be encrypted
|
||||
at the last call, otherwise the result will be incorrect. */
|
||||
void ppc_aes_gcmCRYPT(const unsigned char *PT,
|
||||
unsigned char *CT,
|
||||
unsigned long len,
|
||||
unsigned char *CTRP,
|
||||
PRUint32 *KS,
|
||||
int NR);
|
||||
|
||||
#endif
|
||||
1051
security/nss/lib/freebl/ppc-gcm.s
Normal file
1051
security/nss/lib/freebl/ppc-gcm.s
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -342,7 +342,7 @@ addToSeed(const SECItem *seed,
|
|||
CHECK_MPI_OK(mp_init(&modulus));
|
||||
SECITEM_TO_MPINT(*seed, &s); /* s = seed */
|
||||
/* seed += addend */
|
||||
if (addend < MP_DIGIT_MAX) {
|
||||
if (sizeof(addend) < sizeof(mp_digit) || addend < MP_DIGIT_MAX) {
|
||||
CHECK_MPI_OK(mp_add_d(&s, (mp_digit)addend, &s));
|
||||
} else {
|
||||
CHECK_MPI_OK(mp_init(&tmp));
|
||||
|
|
@ -711,7 +711,7 @@ cleanup:
|
|||
if (rv == SECFailure) {
|
||||
mp_zero(prime);
|
||||
if (prime_seed->data) {
|
||||
SECITEM_FreeItem(prime_seed, PR_FALSE);
|
||||
SECITEM_ZfreeItem(prime_seed, PR_FALSE);
|
||||
}
|
||||
*prime_gen_counter = 0;
|
||||
}
|
||||
|
|
@ -867,7 +867,7 @@ cleanup:
|
|||
if (rv == SECFailure) {
|
||||
mp_zero(prime);
|
||||
if (prime_seed->data) {
|
||||
SECITEM_FreeItem(prime_seed, PR_FALSE);
|
||||
SECITEM_ZfreeItem(prime_seed, PR_FALSE);
|
||||
}
|
||||
*prime_gen_counter = 0;
|
||||
}
|
||||
|
|
@ -905,6 +905,7 @@ findQfromSeed(
|
|||
*typePtr = FIPS186_1_TYPE;
|
||||
return SECSuccess;
|
||||
}
|
||||
mp_zero(Q_);
|
||||
return SECFailure;
|
||||
}
|
||||
/* 1024 could use FIPS186_1 or FIPS186_3 algorithms, we need to try
|
||||
|
|
@ -954,21 +955,23 @@ findQfromSeed(
|
|||
if ((offset < 0) ||
|
||||
(PORT_Memcmp(&seed->data[offset], qseed.data, qseed.len) != 0)) {
|
||||
/* we found q, but the seeds don't match. This isn't an
|
||||
* accident, someone has been tweeking with the seeds, just
|
||||
* fail a this point. */
|
||||
* accident, someone has been tweeking with the seeds, just
|
||||
* fail a this point. */
|
||||
SECITEM_FreeItem(&qseed, PR_FALSE);
|
||||
mp_zero(Q_);
|
||||
return SECFailure;
|
||||
}
|
||||
*qseed_len = qseed.len;
|
||||
*hashtypePtr = hashtype;
|
||||
*typePtr = FIPS186_3_ST_TYPE;
|
||||
*qgen_counter = count;
|
||||
SECITEM_FreeItem(&qseed, PR_FALSE);
|
||||
SECITEM_ZfreeItem(&qseed, PR_FALSE);
|
||||
return SECSuccess;
|
||||
}
|
||||
SECITEM_FreeItem(&qseed, PR_FALSE);
|
||||
SECITEM_ZfreeItem(&qseed, PR_FALSE);
|
||||
}
|
||||
/* no hash algorithms found which match seed to Q, fail */
|
||||
mp_zero(Q_);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
|
|
@ -1069,6 +1072,7 @@ makePfromQandSeed(
|
|||
CHECK_MPI_OK(mp_sub_d(&c, 1, &c)); /* c -= 1 */
|
||||
CHECK_MPI_OK(mp_sub(&X, &c, P)); /* P = X - c */
|
||||
cleanup:
|
||||
PORT_Memset(V_j, 0, sizeof V_j);
|
||||
mp_clear(&W);
|
||||
mp_clear(&X);
|
||||
mp_clear(&c);
|
||||
|
|
@ -1077,8 +1081,12 @@ cleanup:
|
|||
mp_clear(&tmp);
|
||||
if (err) {
|
||||
MP_TO_SEC_ERROR(err);
|
||||
mp_zero(P);
|
||||
return SECFailure;
|
||||
}
|
||||
if (rv != SECSuccess) {
|
||||
mp_zero(P);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
@ -1128,6 +1136,9 @@ cleanup:
|
|||
MP_TO_SEC_ERROR(err);
|
||||
rv = SECFailure;
|
||||
}
|
||||
if (rv != SECSuccess) {
|
||||
mp_zero(G);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
@ -1421,7 +1432,7 @@ step_5:
|
|||
** "will give an acceptable probability of error."
|
||||
*/
|
||||
/*CHECK_SEC_OK( prm_RabinTest(&Q, &passed) );*/
|
||||
err = mpp_pprime(&Q, prime_testcount_q(L, N));
|
||||
err = mpp_pprime_secure(&Q, prime_testcount_q(L, N));
|
||||
passed = (err == MP_YES) ? SECSuccess : SECFailure;
|
||||
/* ******************************************************************
|
||||
** Step 9. (Step 5 in 186-1) "If q is not prime, goto step 5 (1 in 186-1)."
|
||||
|
|
@ -1474,7 +1485,7 @@ step_5:
|
|||
** "Perform a robust primality test on p."
|
||||
*/
|
||||
/*CHECK_SEC_OK( prm_RabinTest(&P, &passed) );*/
|
||||
err = mpp_pprime(&P, prime_testcount_p(L, N));
|
||||
err = mpp_pprime_secure(&P, prime_testcount_p(L, N));
|
||||
passed = (err == MP_YES) ? SECSuccess : SECFailure;
|
||||
/* ******************************************************************
|
||||
** Step 11.8. "If p is determined to be primed return VALID
|
||||
|
|
@ -1534,10 +1545,10 @@ generate_G:
|
|||
*pVfy = verify;
|
||||
cleanup:
|
||||
if (pseed.data) {
|
||||
PORT_Free(pseed.data);
|
||||
SECITEM_ZfreeItem(&pseed, PR_FALSE);
|
||||
}
|
||||
if (qseed.data) {
|
||||
PORT_Free(qseed.data);
|
||||
SECITEM_ZfreeItem(&qseed, PR_FALSE);
|
||||
}
|
||||
mp_clear(&P);
|
||||
mp_clear(&Q);
|
||||
|
|
@ -1558,7 +1569,7 @@ cleanup:
|
|||
}
|
||||
}
|
||||
if (hit.data) {
|
||||
SECITEM_FreeItem(&hit, PR_FALSE);
|
||||
SECITEM_ZfreeItem(&hit, PR_FALSE);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
|
@ -1702,9 +1713,9 @@ PQG_VerifyParams(const PQGParams *params,
|
|||
CHECK_MPI_OK(mp_mod(&P, &Q, &r));
|
||||
CHECKPARAM(mp_cmp_d(&r, 1) == 0);
|
||||
/* 5. Q is prime */
|
||||
CHECKPARAM(mpp_pprime(&Q, prime_testcount_q(L, N)) == MP_YES);
|
||||
CHECKPARAM(mpp_pprime_secure(&Q, prime_testcount_q(L, N)) == MP_YES);
|
||||
/* 6. P is prime */
|
||||
CHECKPARAM(mpp_pprime(&P, prime_testcount_p(L, N)) == MP_YES);
|
||||
CHECKPARAM(mpp_pprime_secure(&P, prime_testcount_p(L, N)) == MP_YES);
|
||||
/* Steps 7-12 are done only if the optional PQGVerify is supplied. */
|
||||
/* continue processing P */
|
||||
/* 7. counter < 4*L */
|
||||
|
|
@ -1869,7 +1880,7 @@ cleanup:
|
|||
mp_clear(&r);
|
||||
mp_clear(&h);
|
||||
if (pseed_.data) {
|
||||
SECITEM_FreeItem(&pseed_, PR_FALSE);
|
||||
SECITEM_ZfreeItem(&pseed_, PR_FALSE);
|
||||
}
|
||||
if (err) {
|
||||
MP_TO_SEC_ERROR(err);
|
||||
|
|
@ -1887,11 +1898,11 @@ PQG_DestroyParams(PQGParams *params)
|
|||
if (params == NULL)
|
||||
return;
|
||||
if (params->arena != NULL) {
|
||||
PORT_FreeArena(params->arena, PR_FALSE); /* don't zero it */
|
||||
PORT_FreeArena(params->arena, PR_TRUE);
|
||||
} else {
|
||||
SECITEM_FreeItem(¶ms->prime, PR_FALSE); /* don't free prime */
|
||||
SECITEM_FreeItem(¶ms->subPrime, PR_FALSE); /* don't free subPrime */
|
||||
SECITEM_FreeItem(¶ms->base, PR_FALSE); /* don't free base */
|
||||
SECITEM_ZfreeItem(¶ms->prime, PR_FALSE); /* don't free prime */
|
||||
SECITEM_ZfreeItem(¶ms->subPrime, PR_FALSE); /* don't free subPrime */
|
||||
SECITEM_ZfreeItem(¶ms->base, PR_FALSE); /* don't free base */
|
||||
PORT_Free(params);
|
||||
}
|
||||
}
|
||||
|
|
@ -1906,10 +1917,10 @@ PQG_DestroyVerify(PQGVerify *vfy)
|
|||
if (vfy == NULL)
|
||||
return;
|
||||
if (vfy->arena != NULL) {
|
||||
PORT_FreeArena(vfy->arena, PR_FALSE); /* don't zero it */
|
||||
PORT_FreeArena(vfy->arena, PR_TRUE);
|
||||
} else {
|
||||
SECITEM_FreeItem(&vfy->seed, PR_FALSE); /* don't free seed */
|
||||
SECITEM_FreeItem(&vfy->h, PR_FALSE); /* don't free h */
|
||||
SECITEM_ZfreeItem(&vfy->seed, PR_FALSE); /* don't free seed */
|
||||
SECITEM_ZfreeItem(&vfy->h, PR_FALSE); /* don't free h */
|
||||
PORT_Free(vfy);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,12 +20,15 @@
|
|||
#include "gcm.h"
|
||||
#include "mpi.h"
|
||||
|
||||
#if (!defined(IS_LITTLE_ENDIAN) && !defined(NSS_X86_OR_X64)) || \
|
||||
(defined(__arm__) && !defined(__ARM_NEON) && !defined(__ARM_NEON__))
|
||||
#if !defined(IS_LITTLE_ENDIAN) && !defined(NSS_X86_OR_X64)
|
||||
// not test yet on big endian platform of arm
|
||||
#undef USE_HW_AES
|
||||
#endif
|
||||
|
||||
#ifdef __powerpc64__
|
||||
#include "ppc-crypto.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_HW_AES
|
||||
#ifdef NSS_X86_OR_X64
|
||||
#include "intel-aes.h"
|
||||
|
|
@ -36,11 +39,8 @@
|
|||
#ifdef INTEL_GCM
|
||||
#include "intel-gcm.h"
|
||||
#endif /* INTEL_GCM */
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if _MSC_VER < 1900
|
||||
#define inline
|
||||
#endif
|
||||
#if defined(USE_PPC_CRYPTO) && defined(PPC_GCM)
|
||||
#include "ppc-gcm.h"
|
||||
#endif
|
||||
|
||||
/* Forward declarations */
|
||||
|
|
@ -964,6 +964,7 @@ aes_InitContext(AESContext *cx, const unsigned char *key, unsigned int keysize,
|
|||
} else {
|
||||
rijndael_invkey_expansion(cx, key, Nk);
|
||||
}
|
||||
BLAPI_CLEAR_STACK(256)
|
||||
}
|
||||
cx->worker_cx = cx;
|
||||
cx->destroy = NULL;
|
||||
|
|
@ -1006,6 +1007,7 @@ AES_InitContext(AESContext *cx, const unsigned char *key, unsigned int keysize,
|
|||
}
|
||||
|
||||
/* finally, set up any mode specific contexts */
|
||||
cx->worker_aead = 0;
|
||||
switch (mode) {
|
||||
case NSS_AES_CTS:
|
||||
cx->worker_cx = CTS_CreateContext(cx, cx->worker, iv);
|
||||
|
|
@ -1020,21 +1022,36 @@ AES_InitContext(AESContext *cx, const unsigned char *key, unsigned int keysize,
|
|||
cx->worker_cx = intel_AES_GCM_CreateContext(cx, cx->worker, iv);
|
||||
cx->worker = (freeblCipherFunc)(encrypt ? intel_AES_GCM_EncryptUpdate
|
||||
: intel_AES_GCM_DecryptUpdate);
|
||||
cx->worker_aead = (freeblAeadFunc)(encrypt ? intel_AES_GCM_EncryptAEAD
|
||||
: intel_AES_GCM_DecryptAEAD);
|
||||
cx->destroy = (freeblDestroyFunc)intel_AES_GCM_DestroyContext;
|
||||
cx->isBlock = PR_FALSE;
|
||||
} else
|
||||
#elif defined(USE_PPC_CRYPTO) && defined(PPC_GCM)
|
||||
if (ppc_crypto_support() && (keysize % 8) == 0) {
|
||||
cx->worker_cx = ppc_AES_GCM_CreateContext(cx, cx->worker, iv);
|
||||
cx->worker = (freeblCipherFunc)(encrypt ? ppc_AES_GCM_EncryptUpdate
|
||||
: ppc_AES_GCM_DecryptUpdate);
|
||||
cx->worker_aead = (freeblAeadFunc)(encrypt ? ppc_AES_GCM_EncryptAEAD
|
||||
: ppc_AES_GCM_DecryptAEAD);
|
||||
cx->destroy = (freeblDestroyFunc)ppc_AES_GCM_DestroyContext;
|
||||
cx->isBlock = PR_FALSE;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
cx->worker_cx = GCM_CreateContext(cx, cx->worker, iv);
|
||||
cx->worker = (freeblCipherFunc)(encrypt ? GCM_EncryptUpdate
|
||||
: GCM_DecryptUpdate);
|
||||
cx->worker_aead = (freeblAeadFunc)(encrypt ? GCM_EncryptAEAD
|
||||
: GCM_DecryptAEAD);
|
||||
|
||||
cx->destroy = (freeblDestroyFunc)GCM_DestroyContext;
|
||||
cx->isBlock = PR_FALSE;
|
||||
}
|
||||
break;
|
||||
case NSS_AES_CTR:
|
||||
cx->worker_cx = CTR_CreateContext(cx, cx->worker, iv);
|
||||
#if defined(USE_HW_AES) && defined(_MSC_VER)
|
||||
#if defined(USE_HW_AES) && defined(_MSC_VER) && defined(NSS_X86_OR_X64)
|
||||
if (aesni_support() && (keysize % 8) == 0) {
|
||||
cx->worker = (freeblCipherFunc)CTR_Update_HW_AES;
|
||||
} else
|
||||
|
|
@ -1119,6 +1136,7 @@ AES_Encrypt(AESContext *cx, unsigned char *output,
|
|||
const unsigned char *input, unsigned int inputLen)
|
||||
{
|
||||
/* Check args */
|
||||
SECStatus rv;
|
||||
if (cx == NULL || output == NULL || (input == NULL && inputLen != 0)) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
|
|
@ -1153,8 +1171,10 @@ AES_Encrypt(AESContext *cx, unsigned char *output,
|
|||
}
|
||||
#endif
|
||||
|
||||
return (*cx->worker)(cx->worker_cx, output, outputLen, maxOutputLen,
|
||||
input, inputLen, AES_BLOCK_SIZE);
|
||||
rv = (*cx->worker)(cx->worker_cx, output, outputLen, maxOutputLen,
|
||||
input, inputLen, AES_BLOCK_SIZE);
|
||||
BLAPI_CLEAR_STACK(256)
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1168,6 +1188,7 @@ AES_Decrypt(AESContext *cx, unsigned char *output,
|
|||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen)
|
||||
{
|
||||
SECStatus rv;
|
||||
/* Check args */
|
||||
if (cx == NULL || output == NULL || (input == NULL && inputLen != 0)) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
|
|
@ -1177,11 +1198,68 @@ AES_Decrypt(AESContext *cx, unsigned char *output,
|
|||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
if ((cx->mode != NSS_AES_GCM) && (maxOutputLen < inputLen)) {
|
||||
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
*outputLen = inputLen;
|
||||
rv = (*cx->worker)(cx->worker_cx, output, outputLen, maxOutputLen,
|
||||
input, inputLen, AES_BLOCK_SIZE);
|
||||
BLAPI_CLEAR_STACK(256)
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* AES_Encrypt_AEAD
|
||||
*
|
||||
* Encrypt using GCM or CCM. include the nonce, extra data, and the tag
|
||||
*/
|
||||
SECStatus
|
||||
AES_AEAD(AESContext *cx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen,
|
||||
void *params, unsigned int paramsLen,
|
||||
const unsigned char *aad, unsigned int aadLen)
|
||||
{
|
||||
SECStatus rv;
|
||||
/* Check args */
|
||||
if (cx == NULL || output == NULL || (input == NULL && inputLen != 0) || (aad == NULL && aadLen != 0) || params == NULL) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
if (cx->worker_aead == NULL) {
|
||||
PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
|
||||
return SECFailure;
|
||||
}
|
||||
if (maxOutputLen < inputLen) {
|
||||
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
*outputLen = inputLen;
|
||||
return (*cx->worker)(cx->worker_cx, output, outputLen, maxOutputLen,
|
||||
input, inputLen, AES_BLOCK_SIZE);
|
||||
#if UINT_MAX > MP_32BIT_MAX
|
||||
/*
|
||||
* we can guarentee that GSM won't overlfow if we limit the input to
|
||||
* 2^36 bytes. For simplicity, we are limiting it to 2^32 for now.
|
||||
*
|
||||
* We do it here to cover both hardware and software GCM operations.
|
||||
*/
|
||||
{
|
||||
PR_STATIC_ASSERT(sizeof(unsigned int) > 4);
|
||||
}
|
||||
if (inputLen > MP_32BIT_MAX) {
|
||||
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
#else
|
||||
/* if we can't pass in a 32_bit number, then no such check needed */
|
||||
{
|
||||
PR_STATIC_ASSERT(sizeof(unsigned int) <= 4);
|
||||
}
|
||||
#endif
|
||||
|
||||
rv = (*cx->worker_aead)(cx->worker_cx, output, outputLen, maxOutputLen,
|
||||
input, inputLen, params, paramsLen, aad, aadLen,
|
||||
AES_BLOCK_SIZE);
|
||||
BLAPI_CLEAR_STACK(256)
|
||||
return rv;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ struct AESContextStr {
|
|||
unsigned int Nr;
|
||||
freeblCipherFunc worker;
|
||||
unsigned char iv[AES_BLOCK_SIZE];
|
||||
freeblAeadFunc worker_aead;
|
||||
freeblDestroyFunc destroy;
|
||||
void *worker_cx;
|
||||
PRBool isBlock;
|
||||
|
|
|
|||
|
|
@ -17,45 +17,43 @@
|
|||
#define WORD_BE(b0, b1, b2, b3) \
|
||||
(((b0) << 24) | ((b1) << 16) | ((b2) << 8) | b3)
|
||||
|
||||
static const PRUint8 __S[256] =
|
||||
{
|
||||
99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118,
|
||||
202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192,
|
||||
183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21,
|
||||
4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117,
|
||||
9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132,
|
||||
83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207,
|
||||
208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168,
|
||||
81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210,
|
||||
205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115,
|
||||
96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219,
|
||||
224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121,
|
||||
231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8,
|
||||
186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138,
|
||||
112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158,
|
||||
225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223,
|
||||
140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22,
|
||||
};
|
||||
static const PRUint8 __S[256] = {
|
||||
99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118,
|
||||
202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192,
|
||||
183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21,
|
||||
4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117,
|
||||
9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132,
|
||||
83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207,
|
||||
208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168,
|
||||
81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210,
|
||||
205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115,
|
||||
96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219,
|
||||
224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121,
|
||||
231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8,
|
||||
186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138,
|
||||
112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158,
|
||||
225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223,
|
||||
140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22
|
||||
};
|
||||
|
||||
static const PRUint8 __SInv[256] =
|
||||
{
|
||||
82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215, 251,
|
||||
124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222, 233, 203,
|
||||
84, 123, 148, 50, 166, 194, 35, 61, 238, 76, 149, 11, 66, 250, 195, 78,
|
||||
8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73, 109, 139, 209, 37,
|
||||
114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92, 204, 93, 101, 182, 146,
|
||||
108, 112, 72, 80, 253, 237, 185, 218, 94, 21, 70, 87, 167, 141, 157, 132,
|
||||
144, 216, 171, 0, 140, 188, 211, 10, 247, 228, 88, 5, 184, 179, 69, 6,
|
||||
208, 44, 30, 143, 202, 63, 15, 2, 193, 175, 189, 3, 1, 19, 138, 107,
|
||||
58, 145, 17, 65, 79, 103, 220, 234, 151, 242, 207, 206, 240, 180, 230, 115,
|
||||
150, 172, 116, 34, 231, 173, 53, 133, 226, 249, 55, 232, 28, 117, 223, 110,
|
||||
71, 241, 26, 113, 29, 41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27,
|
||||
252, 86, 62, 75, 198, 210, 121, 32, 154, 219, 192, 254, 120, 205, 90, 244,
|
||||
31, 221, 168, 51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128, 236, 95,
|
||||
96, 81, 127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156, 239,
|
||||
160, 224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97,
|
||||
23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12, 125
|
||||
};
|
||||
static const PRUint8 __SInv[256] = {
|
||||
82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215, 251,
|
||||
124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222, 233, 203,
|
||||
84, 123, 148, 50, 166, 194, 35, 61, 238, 76, 149, 11, 66, 250, 195, 78,
|
||||
8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73, 109, 139, 209, 37,
|
||||
114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92, 204, 93, 101, 182, 146,
|
||||
108, 112, 72, 80, 253, 237, 185, 218, 94, 21, 70, 87, 167, 141, 157, 132,
|
||||
144, 216, 171, 0, 140, 188, 211, 10, 247, 228, 88, 5, 184, 179, 69, 6,
|
||||
208, 44, 30, 143, 202, 63, 15, 2, 193, 175, 189, 3, 1, 19, 138, 107,
|
||||
58, 145, 17, 65, 79, 103, 220, 234, 151, 242, 207, 206, 240, 180, 230, 115,
|
||||
150, 172, 116, 34, 231, 173, 53, 133, 226, 249, 55, 232, 28, 117, 223, 110,
|
||||
71, 241, 26, 113, 29, 41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27,
|
||||
252, 86, 62, 75, 198, 210, 121, 32, 154, 219, 192, 254, 120, 205, 90, 244,
|
||||
31, 221, 168, 51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128, 236, 95,
|
||||
96, 81, 127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156, 239,
|
||||
160, 224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97,
|
||||
23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12, 125
|
||||
};
|
||||
|
||||
/* GF_MULTIPLY
|
||||
*
|
||||
|
|
|
|||
|
|
@ -22,6 +22,12 @@
|
|||
#include "secitem.h"
|
||||
#include "blapii.h"
|
||||
|
||||
/* The minimal required randomness is 64 bits */
|
||||
/* EXP_BLINDING_RANDOMNESS_LEN is the length of the randomness in mp_digits */
|
||||
/* for 32 bits platforts it is 2 mp_digits (= 2 * 32 bits), for 64 bits it is equal to 128 bits */
|
||||
#define EXP_BLINDING_RANDOMNESS_LEN ((128 + MP_DIGIT_BIT - 1) / MP_DIGIT_BIT)
|
||||
#define EXP_BLINDING_RANDOMNESS_LEN_BYTES (EXP_BLINDING_RANDOMNESS_LEN * sizeof(mp_digit))
|
||||
|
||||
/*
|
||||
** Number of times to attempt to generate a prime (p or q) from a random
|
||||
** seed (the seed changes for each iteration).
|
||||
|
|
@ -64,6 +70,8 @@ struct RSABlindingParamsStr {
|
|||
SECItem modulus; /* list element "key" */
|
||||
blindingParams *free, *bp; /* Blinding parameters queue */
|
||||
blindingParams array[RSA_BLINDING_PARAMS_MAX_CACHE_SIZE];
|
||||
/* precalculate montegomery reduction value */
|
||||
mp_digit n0i; /* n0i = -( n & MP_DIGIT) ** -1 mod mp_RADIX */
|
||||
};
|
||||
typedef struct RSABlindingParamsStr RSABlindingParams;
|
||||
|
||||
|
|
@ -208,7 +216,7 @@ generate_prime(mp_int *prime, int primeLen)
|
|||
pb[0] |= 0xC0; /* set two high-order bits */
|
||||
pb[primeLen - 1] |= 0x01; /* set low-order bit */
|
||||
CHECK_MPI_OK(mp_read_unsigned_octets(prime, pb, primeLen));
|
||||
err = mpp_make_prime(prime, primeLen * 8, PR_FALSE);
|
||||
err = mpp_make_prime_secure(prime, primeLen * 8, PR_FALSE);
|
||||
if (err != MP_NO)
|
||||
goto cleanup;
|
||||
/* keep going while err == MP_NO */
|
||||
|
|
@ -391,7 +399,7 @@ rsa_is_prime(mp_int *p)
|
|||
}
|
||||
|
||||
/* If that passed, run some Miller-Rabin tests */
|
||||
res = mpp_pprime(p, 2);
|
||||
res = mpp_pprime_secure(p, 2);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -893,6 +901,9 @@ cleanup:
|
|||
static unsigned int
|
||||
rsa_modulusLen(SECItem *modulus)
|
||||
{
|
||||
if (modulus->len == 0) {
|
||||
return 0;
|
||||
};
|
||||
unsigned char byteZero = modulus->data[0];
|
||||
unsigned int modLen = modulus->len - !byteZero;
|
||||
return modLen;
|
||||
|
|
@ -925,6 +936,13 @@ RSA_PublicKeyOp(RSAPublicKey *key,
|
|||
CHECK_MPI_OK(mp_init(&c));
|
||||
modLen = rsa_modulusLen(&key->modulus);
|
||||
expLen = rsa_modulusLen(&key->publicExponent);
|
||||
|
||||
if (modLen == 0) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
rv = SECFailure;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* 1. Obtain public key (n, e) */
|
||||
if (BAD_RSA_KEY_SIZE(modLen, expLen)) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_KEY);
|
||||
|
|
@ -1003,6 +1021,13 @@ static SECStatus
|
|||
rsa_PrivateKeyOpCRTNoCheck(RSAPrivateKey *key, mp_int *m, mp_int *c)
|
||||
{
|
||||
mp_int p, q, d_p, d_q, qInv;
|
||||
/*
|
||||
The length of the randomness comes from the papers:
|
||||
https://link.springer.com/chapter/10.1007/978-3-642-29912-4_7
|
||||
https://link.springer.com/chapter/10.1007/978-3-642-21554-4_5.
|
||||
*/
|
||||
mp_int blinding_dp, blinding_dq, r1, r2;
|
||||
unsigned char random_block[EXP_BLINDING_RANDOMNESS_LEN_BYTES];
|
||||
mp_int m1, m2, h, ctmp;
|
||||
mp_err err = MP_OKAY;
|
||||
SECStatus rv = SECSuccess;
|
||||
|
|
@ -1015,6 +1040,11 @@ rsa_PrivateKeyOpCRTNoCheck(RSAPrivateKey *key, mp_int *m, mp_int *c)
|
|||
MP_DIGITS(&m2) = 0;
|
||||
MP_DIGITS(&h) = 0;
|
||||
MP_DIGITS(&ctmp) = 0;
|
||||
MP_DIGITS(&blinding_dp) = 0;
|
||||
MP_DIGITS(&blinding_dq) = 0;
|
||||
MP_DIGITS(&r1) = 0;
|
||||
MP_DIGITS(&r2) = 0;
|
||||
|
||||
CHECK_MPI_OK(mp_init(&p));
|
||||
CHECK_MPI_OK(mp_init(&q));
|
||||
CHECK_MPI_OK(mp_init(&d_p));
|
||||
|
|
@ -1024,12 +1054,44 @@ rsa_PrivateKeyOpCRTNoCheck(RSAPrivateKey *key, mp_int *m, mp_int *c)
|
|||
CHECK_MPI_OK(mp_init(&m2));
|
||||
CHECK_MPI_OK(mp_init(&h));
|
||||
CHECK_MPI_OK(mp_init(&ctmp));
|
||||
CHECK_MPI_OK(mp_init(&blinding_dp));
|
||||
CHECK_MPI_OK(mp_init(&blinding_dq));
|
||||
CHECK_MPI_OK(mp_init_size(&r1, EXP_BLINDING_RANDOMNESS_LEN));
|
||||
CHECK_MPI_OK(mp_init_size(&r2, EXP_BLINDING_RANDOMNESS_LEN));
|
||||
|
||||
/* copy private key parameters into mp integers */
|
||||
SECITEM_TO_MPINT(key->prime1, &p); /* p */
|
||||
SECITEM_TO_MPINT(key->prime2, &q); /* q */
|
||||
SECITEM_TO_MPINT(key->exponent1, &d_p); /* d_p = d mod (p-1) */
|
||||
SECITEM_TO_MPINT(key->exponent2, &d_q); /* d_q = d mod (q-1) */
|
||||
SECITEM_TO_MPINT(key->coefficient, &qInv); /* qInv = q**-1 mod p */
|
||||
|
||||
// blinding_dp = 1
|
||||
CHECK_MPI_OK(mp_set_int(&blinding_dp, 1));
|
||||
// blinding_dp = p - 1
|
||||
CHECK_MPI_OK(mp_sub(&p, &blinding_dp, &blinding_dp));
|
||||
// generating a random value
|
||||
RNG_GenerateGlobalRandomBytes(random_block, EXP_BLINDING_RANDOMNESS_LEN_BYTES);
|
||||
MP_USED(&r1) = EXP_BLINDING_RANDOMNESS_LEN;
|
||||
memcpy(MP_DIGITS(&r1), random_block, sizeof(random_block));
|
||||
// blinding_dp = random * (p - 1)
|
||||
CHECK_MPI_OK(mp_mul(&blinding_dp, &r1, &blinding_dp));
|
||||
//d_p = d_p + random * (p - 1)
|
||||
CHECK_MPI_OK(mp_add(&d_p, &blinding_dp, &d_p));
|
||||
|
||||
// blinding_dq = 1
|
||||
CHECK_MPI_OK(mp_set_int(&blinding_dq, 1));
|
||||
// blinding_dq = q - 1
|
||||
CHECK_MPI_OK(mp_sub(&q, &blinding_dq, &blinding_dq));
|
||||
// generating a random value
|
||||
RNG_GenerateGlobalRandomBytes(random_block, EXP_BLINDING_RANDOMNESS_LEN_BYTES);
|
||||
memcpy(MP_DIGITS(&r2), random_block, sizeof(random_block));
|
||||
MP_USED(&r2) = EXP_BLINDING_RANDOMNESS_LEN;
|
||||
// blinding_dq = random * (q - 1)
|
||||
CHECK_MPI_OK(mp_mul(&blinding_dq, &r2, &blinding_dq));
|
||||
//d_q = d_q + random * (q-1)
|
||||
CHECK_MPI_OK(mp_add(&d_q, &blinding_dq, &d_q));
|
||||
|
||||
/* 1. m1 = c**d_p mod p */
|
||||
CHECK_MPI_OK(mp_mod(c, &p, &ctmp));
|
||||
CHECK_MPI_OK(mp_exptmod(&ctmp, &d_p, &p, &m1));
|
||||
|
|
@ -1052,6 +1114,10 @@ cleanup:
|
|||
mp_clear(&m2);
|
||||
mp_clear(&h);
|
||||
mp_clear(&ctmp);
|
||||
mp_clear(&blinding_dp);
|
||||
mp_clear(&blinding_dq);
|
||||
mp_clear(&r1);
|
||||
mp_clear(&r2);
|
||||
if (err) {
|
||||
MP_TO_SEC_ERROR(err);
|
||||
rv = SECFailure;
|
||||
|
|
@ -1146,6 +1212,8 @@ generate_blinding_params(RSAPrivateKey *key, mp_int *f, mp_int *g, mp_int *n,
|
|||
CHECK_MPI_OK(mp_exptmod(&k, &e, n, f));
|
||||
/* g = k**-1 mod n */
|
||||
CHECK_MPI_OK(mp_invmod(&k, n, g));
|
||||
/* g in montgomery form.. */
|
||||
CHECK_MPI_OK(mp_to_mont(g, n, g));
|
||||
cleanup:
|
||||
if (kb)
|
||||
PORT_ZFree(kb, modLen);
|
||||
|
|
@ -1182,13 +1250,16 @@ init_blinding_params(RSABlindingParams *rsabp, RSAPrivateKey *key,
|
|||
rsabp->bp = NULL;
|
||||
rsabp->free = bp;
|
||||
|
||||
/* precalculate montgomery reduction parameter */
|
||||
rsabp->n0i = mp_calculate_mont_n0i(n);
|
||||
|
||||
/* List elements are keyed using the modulus */
|
||||
return SECITEM_CopyItem(NULL, &rsabp->modulus, &key->modulus);
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
get_blinding_params(RSAPrivateKey *key, mp_int *n, unsigned int modLen,
|
||||
mp_int *f, mp_int *g)
|
||||
mp_int *f, mp_int *g, mp_digit *n0i)
|
||||
{
|
||||
RSABlindingParams *rsabp = NULL;
|
||||
blindingParams *bpUnlinked = NULL;
|
||||
|
|
@ -1248,11 +1319,18 @@ get_blinding_params(RSAPrivateKey *key, mp_int *n, unsigned int modLen,
|
|||
/* We've found (or created) the RSAblindingParams struct for this key.
|
||||
* Now, search its list of ready blinding params for a usable one.
|
||||
*/
|
||||
*n0i = rsabp->n0i;
|
||||
while (0 != (bp = rsabp->bp)) {
|
||||
#ifndef UNSAFE_FUZZER_MODE
|
||||
if (--(bp->counter) > 0)
|
||||
#endif
|
||||
{
|
||||
#ifdef UNSAFE_FUZZER_MODE
|
||||
/* Found a match and there are still remaining uses left */
|
||||
/* Return the parameters */
|
||||
CHECK_MPI_OK(mp_copy(&bp->f, f));
|
||||
CHECK_MPI_OK(mp_copy(&bp->g, g));
|
||||
|
||||
PZ_Unlock(blindingParamsList.lock);
|
||||
return SECSuccess;
|
||||
#else
|
||||
if (--(bp->counter) > 0) {
|
||||
/* Found a match and there are still remaining uses left */
|
||||
/* Return the parameters */
|
||||
CHECK_MPI_OK(mp_copy(&bp->f, f));
|
||||
|
|
@ -1282,6 +1360,7 @@ get_blinding_params(RSAPrivateKey *key, mp_int *n, unsigned int modLen,
|
|||
}
|
||||
PZ_Unlock(blindingParamsList.lock);
|
||||
return SECSuccess;
|
||||
#endif
|
||||
}
|
||||
/* We did not find a usable set of blinding params. Can we make one? */
|
||||
/* Find a free bp struct. */
|
||||
|
|
@ -1355,6 +1434,7 @@ cleanup:
|
|||
if (err) {
|
||||
MP_TO_SEC_ERROR(err);
|
||||
}
|
||||
*n0i = 0;
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
|
|
@ -1374,12 +1454,17 @@ rsa_PrivateKeyOp(RSAPrivateKey *key,
|
|||
mp_err err;
|
||||
mp_int n, c, m;
|
||||
mp_int f, g;
|
||||
mp_digit n0i;
|
||||
if (!key || !output || !input) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
/* check input out of range (needs to be in range [0..n-1]) */
|
||||
modLen = rsa_modulusLen(&key->modulus);
|
||||
if (modLen == 0) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
offset = (key->modulus.data[0] == 0) ? 1 : 0; /* may be leading 0 */
|
||||
if (memcmp(input, key->modulus.data + offset, modLen) >= 0) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
|
|
@ -1401,7 +1486,7 @@ rsa_PrivateKeyOp(RSAPrivateKey *key,
|
|||
** blinding factor
|
||||
*/
|
||||
if (nssRSAUseBlinding) {
|
||||
CHECK_SEC_OK(get_blinding_params(key, &n, modLen, &f, &g));
|
||||
CHECK_SEC_OK(get_blinding_params(key, &n, modLen, &f, &g, &n0i));
|
||||
/* c' = c*f mod n */
|
||||
CHECK_MPI_OK(mp_mulmod(&c, &f, &n, &c));
|
||||
}
|
||||
|
|
@ -1422,7 +1507,7 @@ rsa_PrivateKeyOp(RSAPrivateKey *key,
|
|||
*/
|
||||
if (nssRSAUseBlinding) {
|
||||
/* m = m'*g mod n */
|
||||
CHECK_MPI_OK(mp_mulmod(&m, &g, &n, &m));
|
||||
CHECK_MPI_OK(mp_mulmontmodCT(&m, &g, &n, n0i, &m));
|
||||
}
|
||||
err = mp_to_fixlen_octets(&m, output, modLen);
|
||||
if (err >= 0)
|
||||
|
|
@ -1593,7 +1678,7 @@ RSA_Cleanup(void)
|
|||
mp_clear(&bp->f);
|
||||
mp_clear(&bp->g);
|
||||
}
|
||||
SECITEM_FreeItem(&rsabp->modulus, PR_FALSE);
|
||||
SECITEM_ZfreeItem(&rsabp->modulus, PR_FALSE);
|
||||
PORT_Free(rsabp);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -80,6 +80,10 @@ constantTimeCondition(unsigned int c,
|
|||
static unsigned int
|
||||
rsa_modulusLen(SECItem *modulus)
|
||||
{
|
||||
if (modulus->len == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned char byteZero = modulus->data[0];
|
||||
unsigned int modLen = modulus->len - !byteZero;
|
||||
return modLen;
|
||||
|
|
@ -88,9 +92,17 @@ rsa_modulusLen(SECItem *modulus)
|
|||
static unsigned int
|
||||
rsa_modulusBits(SECItem *modulus)
|
||||
{
|
||||
if (modulus->len == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned char byteZero = modulus->data[0];
|
||||
unsigned int numBits = (modulus->len - 1) * 8;
|
||||
|
||||
if (byteZero == 0 && modulus->len == 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (byteZero == 0) {
|
||||
numBits -= 8;
|
||||
byteZero = modulus->data[1];
|
||||
|
|
@ -116,7 +128,7 @@ rsa_FormatOneBlock(unsigned modulusLen,
|
|||
unsigned char *block;
|
||||
unsigned char *bp;
|
||||
unsigned int padLen;
|
||||
int i, j;
|
||||
unsigned int i, j;
|
||||
SECStatus rv;
|
||||
|
||||
block = (unsigned char *)PORT_Alloc(modulusLen);
|
||||
|
|
@ -147,7 +159,7 @@ rsa_FormatOneBlock(unsigned modulusLen,
|
|||
padLen = modulusLen - data->len - 3;
|
||||
PORT_Assert(padLen >= RSA_BLOCK_MIN_PAD_LEN);
|
||||
if (padLen < RSA_BLOCK_MIN_PAD_LEN) {
|
||||
PORT_Free(block);
|
||||
PORT_ZFree(block, modulusLen);
|
||||
return NULL;
|
||||
}
|
||||
PORT_Memset(bp, RSA_BLOCK_PRIVATE_PAD_OCTET, padLen);
|
||||
|
|
@ -176,7 +188,7 @@ rsa_FormatOneBlock(unsigned modulusLen,
|
|||
padLen = modulusLen - (data->len + 3);
|
||||
PORT_Assert(padLen >= RSA_BLOCK_MIN_PAD_LEN);
|
||||
if (padLen < RSA_BLOCK_MIN_PAD_LEN) {
|
||||
PORT_Free(block);
|
||||
PORT_ZFree(block, modulusLen);
|
||||
return NULL;
|
||||
}
|
||||
j = modulusLen - 2;
|
||||
|
|
@ -205,7 +217,7 @@ rsa_FormatOneBlock(unsigned modulusLen,
|
|||
}
|
||||
}
|
||||
if (rv != SECSuccess) {
|
||||
PORT_Free(block);
|
||||
PORT_ZFree(block, modulusLen);
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -216,7 +228,7 @@ rsa_FormatOneBlock(unsigned modulusLen,
|
|||
|
||||
default:
|
||||
PORT_Assert(0);
|
||||
PORT_Free(block);
|
||||
PORT_ZFree(block, modulusLen);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -932,7 +944,162 @@ failure:
|
|||
return SECFailure;
|
||||
}
|
||||
|
||||
/* XXX Doesn't set error code */
|
||||
static HMACContext *
|
||||
rsa_GetHMACContext(const SECHashObject *hash, RSAPrivateKey *key,
|
||||
const unsigned char *input, unsigned int inputLen)
|
||||
{
|
||||
unsigned char keyHash[HASH_LENGTH_MAX];
|
||||
void *hashContext;
|
||||
HMACContext *hmac = NULL;
|
||||
unsigned int privKeyLen = key->privateExponent.len;
|
||||
unsigned int keyLen;
|
||||
SECStatus rv;
|
||||
|
||||
/* first get the key hash (should store in the key structure) */
|
||||
PORT_Memset(keyHash, 0, sizeof(keyHash));
|
||||
hashContext = (*hash->create)();
|
||||
if (hashContext == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
(*hash->begin)(hashContext);
|
||||
if (privKeyLen < inputLen) {
|
||||
int padLen = inputLen - privKeyLen;
|
||||
while (padLen > sizeof(keyHash)) {
|
||||
(*hash->update)(hashContext, keyHash, sizeof(keyHash));
|
||||
padLen -= sizeof(keyHash);
|
||||
}
|
||||
(*hash->update)(hashContext, keyHash, padLen);
|
||||
}
|
||||
(*hash->update)(hashContext, key->privateExponent.data, privKeyLen);
|
||||
(*hash->end)(hashContext, keyHash, &keyLen, sizeof(keyHash));
|
||||
(*hash->destroy)(hashContext, PR_TRUE);
|
||||
|
||||
/* now create the hmac key */
|
||||
hmac = HMAC_Create(hash, keyHash, keyLen, PR_TRUE);
|
||||
if (hmac == NULL) {
|
||||
PORT_Memset(keyHash, 0, sizeof(keyHash));
|
||||
return NULL;
|
||||
}
|
||||
HMAC_Begin(hmac);
|
||||
HMAC_Update(hmac, input, inputLen);
|
||||
rv = HMAC_Finish(hmac, keyHash, &keyLen, sizeof(keyHash));
|
||||
if (rv != SECSuccess) {
|
||||
PORT_Memset(keyHash, 0, sizeof(keyHash));
|
||||
HMAC_Destroy(hmac, PR_TRUE);
|
||||
return NULL;
|
||||
}
|
||||
/* Finally set the new key into the hash context. We
|
||||
* reuse the original context allocated above so we don't
|
||||
* need to allocate and free another one */
|
||||
rv = HMAC_ReInit(hmac, hash, keyHash, keyLen, PR_TRUE);
|
||||
PORT_Memset(keyHash, 0, sizeof(keyHash));
|
||||
if (rv != SECSuccess) {
|
||||
HMAC_Destroy(hmac, PR_TRUE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return hmac;
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
rsa_HMACPrf(HMACContext *hmac, const char *label, int labelLen,
|
||||
int hashLength, unsigned char *output, int length)
|
||||
{
|
||||
unsigned char iterator[2] = { 0, 0 };
|
||||
unsigned char encodedLen[2] = { 0, 0 };
|
||||
unsigned char hmacLast[HASH_LENGTH_MAX];
|
||||
unsigned int left = length;
|
||||
unsigned int hashReturn;
|
||||
SECStatus rv = SECSuccess;
|
||||
|
||||
/* encodedLen is in bits, length is in bytes, thus the shifts
|
||||
* do an implied multiply by 8 */
|
||||
encodedLen[0] = (length >> 5) & 0xff;
|
||||
encodedLen[1] = (length << 3) & 0xff;
|
||||
|
||||
while (left > hashLength) {
|
||||
HMAC_Begin(hmac);
|
||||
HMAC_Update(hmac, iterator, 2);
|
||||
HMAC_Update(hmac, (const unsigned char *)label, labelLen);
|
||||
HMAC_Update(hmac, encodedLen, 2);
|
||||
rv = HMAC_Finish(hmac, output, &hashReturn, hashLength);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
}
|
||||
iterator[1]++;
|
||||
if (iterator[1] == 0)
|
||||
iterator[0]++;
|
||||
left -= hashLength;
|
||||
output += hashLength;
|
||||
}
|
||||
if (left) {
|
||||
HMAC_Begin(hmac);
|
||||
HMAC_Update(hmac, iterator, 2);
|
||||
HMAC_Update(hmac, (const unsigned char *)label, labelLen);
|
||||
HMAC_Update(hmac, encodedLen, 2);
|
||||
rv = HMAC_Finish(hmac, hmacLast, &hashReturn, sizeof(hmacLast));
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
}
|
||||
PORT_Memcpy(output, hmacLast, left);
|
||||
PORT_Memset(hmacLast, 0, sizeof(hmacLast));
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* This function takes a 16-bit input number and
|
||||
* creates the smallest mask which covers
|
||||
* the whole number. Examples:
|
||||
* 0x81 -> 0xff
|
||||
* 0x1af -> 0x1ff
|
||||
* 0x4d1 -> 0x7ff
|
||||
*/
|
||||
static int
|
||||
makeMask16(int len)
|
||||
{
|
||||
// or the high bit in each bit location
|
||||
len |= (len >> 1);
|
||||
len |= (len >> 2);
|
||||
len |= (len >> 4);
|
||||
len |= (len >> 8);
|
||||
return len;
|
||||
}
|
||||
|
||||
#define STRING_AND_LENGTH(s) s, sizeof(s) - 1
|
||||
static int
|
||||
rsa_GetErrorLength(HMACContext *hmac, int hashLen, int maxLegalLen)
|
||||
{
|
||||
unsigned char out[128 * 2];
|
||||
unsigned char *outp;
|
||||
int outLength = 0;
|
||||
int lengthMask;
|
||||
SECStatus rv;
|
||||
|
||||
lengthMask = makeMask16(maxLegalLen);
|
||||
rv = rsa_HMACPrf(hmac, STRING_AND_LENGTH("length"), hashLen,
|
||||
out, sizeof(out));
|
||||
if (rv != SECSuccess) {
|
||||
return -1;
|
||||
}
|
||||
for (outp = out; outp < out + sizeof(out); outp += 2) {
|
||||
int candidate = outp[0] << 8 | outp[1];
|
||||
candidate = candidate & lengthMask;
|
||||
outLength = PORT_CT_SEL(PORT_CT_LT(candidate, maxLegalLen),
|
||||
candidate, outLength);
|
||||
}
|
||||
PORT_Memset(out, 0, sizeof(out));
|
||||
return outLength;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function can only fail in environmental cases: Programming errors
|
||||
* and out of memory situations. It can't fail if the keys are valid and
|
||||
* the inputs are the proper size. If the actual RSA decryption fails, a
|
||||
* fake value and a fake length, both of which have already been generated
|
||||
* based on the key and input, are returned.
|
||||
* Applications are expected to detect decryption failures based on the fact
|
||||
* that the decrypted value (usually a key) doesn't validate. The prevents
|
||||
* Blecheinbaucher style attacks against the key. */
|
||||
SECStatus
|
||||
RSA_DecryptBlock(RSAPrivateKey *key,
|
||||
unsigned char *output,
|
||||
|
|
@ -941,56 +1108,122 @@ RSA_DecryptBlock(RSAPrivateKey *key,
|
|||
const unsigned char *input,
|
||||
unsigned int inputLen)
|
||||
{
|
||||
PRInt8 rv;
|
||||
SECStatus rv;
|
||||
PRUint32 fail;
|
||||
unsigned int modulusLen = rsa_modulusLen(&key->modulus);
|
||||
unsigned int i;
|
||||
unsigned char *buffer = NULL;
|
||||
unsigned int outLen = 0;
|
||||
unsigned int copyOutLen = modulusLen - 11;
|
||||
unsigned char *errorBuffer = NULL;
|
||||
unsigned char *bp = NULL;
|
||||
unsigned char *ep = NULL;
|
||||
unsigned int outLen = modulusLen;
|
||||
unsigned int maxLegalLen = modulusLen - 10;
|
||||
unsigned int errorLength;
|
||||
const SECHashObject *hashObj;
|
||||
HMACContext *hmac = NULL;
|
||||
|
||||
/* failures in the top section indicate failures in the environment
|
||||
* (memory) or the library. OK to return errors in these cases because
|
||||
* it doesn't provide any oracle information to attackers. */
|
||||
if (inputLen != modulusLen || modulusLen < 10) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (copyOutLen > maxOutputLen) {
|
||||
copyOutLen = maxOutputLen;
|
||||
}
|
||||
|
||||
// Allocate enough space to decrypt + copyOutLen to allow copying outLen later.
|
||||
buffer = PORT_ZAlloc(modulusLen + 1 + copyOutLen);
|
||||
/* Allocate enough space to decrypt */
|
||||
buffer = PORT_ZAlloc(modulusLen);
|
||||
if (!buffer) {
|
||||
return SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
errorBuffer = PORT_ZAlloc(modulusLen);
|
||||
if (!errorBuffer) {
|
||||
goto loser;
|
||||
}
|
||||
hashObj = HASH_GetRawHashObject(HASH_AlgSHA256);
|
||||
if (hashObj == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
// rv is 0 if everything is going well and 1 if an error occurs.
|
||||
rv = RSA_PrivateKeyOp(key, buffer, input) != SECSuccess;
|
||||
rv |= (buffer[0] != RSA_BLOCK_FIRST_OCTET) |
|
||||
(buffer[1] != (unsigned char)RSA_BlockPublic);
|
||||
/* calculate the values to return in the error case rather than
|
||||
* the actual returned values. This data is the same for the
|
||||
* same input and private key. */
|
||||
hmac = rsa_GetHMACContext(hashObj, key, input, inputLen);
|
||||
if (hmac == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
errorLength = rsa_GetErrorLength(hmac, hashObj->length, maxLegalLen);
|
||||
if (((int)errorLength) < 0) {
|
||||
goto loser;
|
||||
}
|
||||
/* we always have to generate a full moduluslen error string. Otherwise
|
||||
* we create a timing dependency on errorLength, which could be used to
|
||||
* determine the difference between errorLength and outputLen and tell
|
||||
* us that there was a pkcs1 decryption failure */
|
||||
rv = rsa_HMACPrf(hmac, STRING_AND_LENGTH("message"),
|
||||
hashObj->length, errorBuffer, modulusLen);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
// There have to be at least 8 bytes of padding.
|
||||
HMAC_Destroy(hmac, PR_TRUE);
|
||||
hmac = NULL;
|
||||
|
||||
/* From here on out, we will always return success. If there is
|
||||
* an error, we will return deterministic output based on the key
|
||||
* and the input data. */
|
||||
rv = RSA_PrivateKeyOp(key, buffer, input);
|
||||
|
||||
fail = PORT_CT_NE(rv, SECSuccess);
|
||||
fail |= PORT_CT_NE(buffer[0], RSA_BLOCK_FIRST_OCTET) | PORT_CT_NE(buffer[1], RSA_BlockPublic);
|
||||
|
||||
/* There have to be at least 8 bytes of padding. */
|
||||
for (i = 2; i < 10; i++) {
|
||||
rv |= buffer[i] == RSA_BLOCK_AFTER_PAD_OCTET;
|
||||
fail |= PORT_CT_EQ(buffer[i], RSA_BLOCK_AFTER_PAD_OCTET);
|
||||
}
|
||||
|
||||
for (i = 10; i < modulusLen; i++) {
|
||||
unsigned int newLen = modulusLen - i - 1;
|
||||
unsigned int c = (buffer[i] == RSA_BLOCK_AFTER_PAD_OCTET) & (outLen == 0);
|
||||
outLen = constantTimeCondition(c, newLen, outLen);
|
||||
PRUint32 condition = PORT_CT_EQ(buffer[i], RSA_BLOCK_AFTER_PAD_OCTET) & PORT_CT_EQ(outLen, modulusLen);
|
||||
outLen = PORT_CT_SEL(condition, newLen, outLen);
|
||||
}
|
||||
rv |= outLen == 0;
|
||||
rv |= outLen > maxOutputLen;
|
||||
// this can only happen if a zero wasn't found above
|
||||
fail |= PORT_CT_GE(outLen, modulusLen);
|
||||
|
||||
// Note that output is set even if SECFailure is returned.
|
||||
PORT_Memcpy(output, buffer + modulusLen - outLen, copyOutLen);
|
||||
*outputLen = constantTimeCondition(outLen > maxOutputLen, maxOutputLen,
|
||||
outLen);
|
||||
outLen = PORT_CT_SEL(fail, errorLength, outLen);
|
||||
|
||||
/* index into the correct buffer. Do it before we truncate outLen if the
|
||||
* application was asking for less data than we can return */
|
||||
bp = buffer + modulusLen - outLen;
|
||||
ep = errorBuffer + modulusLen - outLen;
|
||||
|
||||
/* at this point, outLen returns no information about decryption failures,
|
||||
* no need to hide its value. maxOutputLen is how much data the
|
||||
* application is expecting, which is also not sensitive. */
|
||||
if (outLen > maxOutputLen) {
|
||||
outLen = maxOutputLen;
|
||||
}
|
||||
|
||||
/* we can't use PORT_Memcpy because caching could create a time dependency
|
||||
* on the status of fail. */
|
||||
for (i = 0; i < outLen; i++) {
|
||||
output[i] = PORT_CT_SEL(fail, ep[i], bp[i]);
|
||||
}
|
||||
|
||||
*outputLen = outLen;
|
||||
|
||||
PORT_Free(buffer);
|
||||
PORT_Free(errorBuffer);
|
||||
|
||||
for (i = 1; i < sizeof(rv) * 8; i <<= 1) {
|
||||
rv |= rv << i;
|
||||
return SECSuccess;
|
||||
|
||||
loser:
|
||||
if (hmac) {
|
||||
HMAC_Destroy(hmac, PR_TRUE);
|
||||
}
|
||||
return (SECStatus)rv;
|
||||
PORT_Free(buffer);
|
||||
PORT_Free(errorBuffer);
|
||||
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1409,6 +1642,7 @@ RSA_CheckSignRecover(RSAPublicKey *key,
|
|||
unsigned int modulusLen = rsa_modulusLen(&key->modulus);
|
||||
unsigned int i;
|
||||
unsigned char *buffer = NULL;
|
||||
unsigned int padLen;
|
||||
|
||||
if (sigLen != modulusLen) {
|
||||
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
|
||||
|
|
@ -1446,6 +1680,11 @@ RSA_CheckSignRecover(RSAPublicKey *key,
|
|||
goto done;
|
||||
}
|
||||
}
|
||||
padLen = i - 2;
|
||||
if (padLen < RSA_BLOCK_MIN_PAD_LEN) {
|
||||
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
|
||||
goto done;
|
||||
}
|
||||
if (*outputLen == 0) {
|
||||
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
|
||||
goto done;
|
||||
|
|
|
|||
36
security/nss/lib/freebl/scripts/LICENSE
Normal file
36
security/nss/lib/freebl/scripts/LICENSE
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
Copyright (c) 2006, CRYPTOGAMS by <appro@openssl.org>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain copyright notices,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
|
||||
* Neither the name of the CRYPTOGAMS nor the names of its
|
||||
copyright holder and contributors may be used to endorse or
|
||||
promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
ALTERNATIVELY, provided that this notice is retained in full, this
|
||||
product may be distributed under the terms of the GNU General Public
|
||||
License (GPL), in which case the provisions of the GPL apply INSTEAD OF
|
||||
those given above.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
19
security/nss/lib/freebl/scripts/gen.sh
Executable file
19
security/nss/lib/freebl/scripts/gen.sh
Executable file
|
|
@ -0,0 +1,19 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Run the scripts in this folder, generating the assembly,
|
||||
#
|
||||
|
||||
perl sha512p8-ppc.pl linux64le sha512-p8.s
|
||||
|
||||
# Add the license mention
|
||||
cat > hdr << "EOF"
|
||||
# Copyright (c) 2006, CRYPTOGAMS by <appro@openssl.org>
|
||||
# All rights reserved.
|
||||
# See the full LICENSE under scripts/.
|
||||
|
||||
EOF
|
||||
|
||||
cat hdr sha512-p8.s > ../sha512-p8.s
|
||||
|
||||
# Cleanup
|
||||
rm hdr sha512-p8.s
|
||||
352
security/nss/lib/freebl/scripts/ppc-xlate.pl
Normal file
352
security/nss/lib/freebl/scripts/ppc-xlate.pl
Normal file
|
|
@ -0,0 +1,352 @@
|
|||
#!/usr/bin/env perl
|
||||
|
||||
# PowerPC assembler distiller by \@dot-asm.
|
||||
|
||||
################################################################
|
||||
# Recognized "flavour"-s are:
|
||||
#
|
||||
# linux{32|64}[le] GNU assembler and ELF symbol decorations,
|
||||
# with little-endian option
|
||||
# linux64v2 GNU asssembler and big-endian instantiation
|
||||
# of latest ELF specification
|
||||
# aix{32|64} AIX assembler and symbol decorations
|
||||
# osx{32|64} Mac OS X assembler and symbol decoratons
|
||||
|
||||
my $flavour = shift;
|
||||
my $output = shift;
|
||||
open STDOUT,">$output" || die "can't open $output: $!";
|
||||
|
||||
my %GLOBALS;
|
||||
my %TYPES;
|
||||
my $dotinlocallabels=($flavour=~/linux/)?1:0;
|
||||
|
||||
################################################################
|
||||
# directives which need special treatment on different platforms
|
||||
################################################################
|
||||
my $type = sub {
|
||||
my ($dir,$name,$type) = @_;
|
||||
|
||||
$TYPES{$name} = $type;
|
||||
if ($flavour =~ /linux/) {
|
||||
$name =~ s|^\.||;
|
||||
".type $name,$type";
|
||||
} else {
|
||||
"";
|
||||
}
|
||||
};
|
||||
my $globl = sub {
|
||||
my $junk = shift;
|
||||
my $name = shift;
|
||||
my $global = \$GLOBALS{$name};
|
||||
my $type = \$TYPES{$name};
|
||||
my $ret;
|
||||
|
||||
$name =~ s|^\.||;
|
||||
|
||||
SWITCH: for ($flavour) {
|
||||
/aix/ && do { if (!$$type) {
|
||||
$$type = "\@function";
|
||||
}
|
||||
if ($$type =~ /function/) {
|
||||
$name = ".$name";
|
||||
}
|
||||
last;
|
||||
};
|
||||
/osx/ && do { $name = "_$name";
|
||||
last;
|
||||
};
|
||||
/linux.*(32|64(le|v2))/
|
||||
&& do { $ret .= ".globl $name";
|
||||
if (!$$type) {
|
||||
$ret .= "\n.type $name,\@function";
|
||||
$$type = "\@function";
|
||||
}
|
||||
last;
|
||||
};
|
||||
/linux.*64/ && do { $ret .= ".globl $name";
|
||||
if (!$$type) {
|
||||
$ret .= "\n.type $name,\@function";
|
||||
$$type = "\@function";
|
||||
}
|
||||
if ($$type =~ /function/) {
|
||||
$ret .= "\n.section \".opd\",\"aw\"";
|
||||
$ret .= "\n.align 3";
|
||||
$ret .= "\n$name:";
|
||||
$ret .= "\n.quad .$name,.TOC.\@tocbase,0";
|
||||
$ret .= "\n.previous";
|
||||
$name = ".$name";
|
||||
}
|
||||
last;
|
||||
};
|
||||
}
|
||||
|
||||
$ret = ".globl $name" if (!$ret);
|
||||
$$global = $name;
|
||||
$ret;
|
||||
};
|
||||
my $text = sub {
|
||||
my $ret = ($flavour =~ /aix/) ? ".csect\t.text[PR],7" : ".text";
|
||||
$ret = ".abiversion 2\n".$ret if ($flavour =~ /linux.*64(le|v2)/);
|
||||
$ret;
|
||||
};
|
||||
my $machine = sub {
|
||||
my $junk = shift;
|
||||
my $arch = shift;
|
||||
if ($flavour =~ /osx/)
|
||||
{ $arch =~ s/\"//g;
|
||||
$arch = ($flavour=~/64/) ? "ppc970-64" : "ppc970" if ($arch eq "any");
|
||||
}
|
||||
".machine $arch";
|
||||
};
|
||||
my $size = sub {
|
||||
if ($flavour =~ /linux/)
|
||||
{ shift;
|
||||
my $name = shift;
|
||||
my $real = $GLOBALS{$name} ? \$GLOBALS{$name} : \$name;
|
||||
my $ret = ".size $$real,.-$$real";
|
||||
$name =~ s|^\.||;
|
||||
if ($$real ne $name) {
|
||||
$ret .= "\n.size $name,.-$$real";
|
||||
}
|
||||
$ret;
|
||||
}
|
||||
else
|
||||
{ ""; }
|
||||
};
|
||||
my $asciz = sub {
|
||||
shift;
|
||||
my $line = join(",",@_);
|
||||
if ($line =~ /^"(.*)"$/)
|
||||
{ ".byte " . join(",",unpack("C*",$1),0) . "\n.align 2"; }
|
||||
else
|
||||
{ ""; }
|
||||
};
|
||||
my $quad = sub {
|
||||
shift;
|
||||
my @ret;
|
||||
my ($hi,$lo);
|
||||
for (@_) {
|
||||
if (/^0x([0-9a-f]*?)([0-9a-f]{1,8})$/io)
|
||||
{ $hi=$1?"0x$1":"0"; $lo="0x$2"; }
|
||||
elsif (/^([0-9]+)$/o)
|
||||
{ $hi=$1>>32; $lo=$1&0xffffffff; } # error-prone with 32-bit perl
|
||||
else
|
||||
{ $hi=undef; $lo=$_; }
|
||||
|
||||
if (defined($hi))
|
||||
{ push(@ret,$flavour=~/le$/o?".long\t$lo,$hi":".long\t$hi,$lo"); }
|
||||
else
|
||||
{ push(@ret,".quad $lo"); }
|
||||
}
|
||||
join("\n",@ret);
|
||||
};
|
||||
|
||||
################################################################
|
||||
# simplified mnemonics not handled by at least one assembler
|
||||
################################################################
|
||||
my $cmplw = sub {
|
||||
my $f = shift;
|
||||
my $cr = 0; $cr = shift if ($#_>1);
|
||||
# Some out-of-date 32-bit GNU assembler just can't handle cmplw...
|
||||
($flavour =~ /linux.*32/) ?
|
||||
" .long ".sprintf "0x%x",31<<26|$cr<<23|$_[0]<<16|$_[1]<<11|64 :
|
||||
" cmplw ".join(',',$cr,@_);
|
||||
};
|
||||
my $bdnz = sub {
|
||||
my $f = shift;
|
||||
my $bo = $f=~/[\+\-]/ ? 16+9 : 16; # optional "to be taken" hint
|
||||
" bc $bo,0,".shift;
|
||||
} if ($flavour!~/linux/);
|
||||
my $bltlr = sub {
|
||||
my $f = shift;
|
||||
my $bo = $f=~/\-/ ? 12+2 : 12; # optional "not to be taken" hint
|
||||
($flavour =~ /linux/) ? # GNU as doesn't allow most recent hints
|
||||
" .long ".sprintf "0x%x",19<<26|$bo<<21|16<<1 :
|
||||
" bclr $bo,0";
|
||||
};
|
||||
my $bnelr = sub {
|
||||
my $f = shift;
|
||||
my $bo = $f=~/\-/ ? 4+2 : 4; # optional "not to be taken" hint
|
||||
($flavour =~ /linux/) ? # GNU as doesn't allow most recent hints
|
||||
" .long ".sprintf "0x%x",19<<26|$bo<<21|2<<16|16<<1 :
|
||||
" bclr $bo,2";
|
||||
};
|
||||
my $beqlr = sub {
|
||||
my $f = shift;
|
||||
my $bo = $f=~/-/ ? 12+2 : 12; # optional "not to be taken" hint
|
||||
($flavour =~ /linux/) ? # GNU as doesn't allow most recent hints
|
||||
" .long ".sprintf "0x%X",19<<26|$bo<<21|2<<16|16<<1 :
|
||||
" bclr $bo,2";
|
||||
};
|
||||
# GNU assembler can't handle extrdi rA,rS,16,48, or when sum of last two
|
||||
# arguments is 64, with "operand out of range" error.
|
||||
my $extrdi = sub {
|
||||
my ($f,$ra,$rs,$n,$b) = @_;
|
||||
$b = ($b+$n)&63; $n = 64-$n;
|
||||
" rldicl $ra,$rs,$b,$n";
|
||||
};
|
||||
my $vmr = sub {
|
||||
my ($f,$vx,$vy) = @_;
|
||||
" vor $vx,$vy,$vy";
|
||||
};
|
||||
|
||||
# Some ABIs specify vrsave, special-purpose register #256, as reserved
|
||||
# for system use.
|
||||
my $no_vrsave = ($flavour =~ /aix|linux64(le|v2)/);
|
||||
my $mtspr = sub {
|
||||
my ($f,$idx,$ra) = @_;
|
||||
if ($idx == 256 && $no_vrsave) {
|
||||
" or $ra,$ra,$ra";
|
||||
} else {
|
||||
" mtspr $idx,$ra";
|
||||
}
|
||||
};
|
||||
my $mfspr = sub {
|
||||
my ($f,$rd,$idx) = @_;
|
||||
if ($idx == 256 && $no_vrsave) {
|
||||
" li $rd,-1";
|
||||
} else {
|
||||
" mfspr $rd,$idx";
|
||||
}
|
||||
};
|
||||
|
||||
# PowerISA 2.06 stuff
|
||||
sub vsxmem_op {
|
||||
my ($f, $vrt, $ra, $rb, $op) = @_;
|
||||
" .long ".sprintf "0x%X",(31<<26)|($vrt<<21)|($ra<<16)|($rb<<11)|($op*2+1);
|
||||
}
|
||||
# made-up unaligned memory reference AltiVec/VMX instructions
|
||||
my $lvx_u = sub { vsxmem_op(@_, 844); }; # lxvd2x
|
||||
my $stvx_u = sub { vsxmem_op(@_, 972); }; # stxvd2x
|
||||
my $lvdx_u = sub { vsxmem_op(@_, 588); }; # lxsdx
|
||||
my $stvdx_u = sub { vsxmem_op(@_, 716); }; # stxsdx
|
||||
my $lvx_4w = sub { vsxmem_op(@_, 780); }; # lxvw4x
|
||||
my $stvx_4w = sub { vsxmem_op(@_, 908); }; # stxvw4x
|
||||
my $lvx_splt = sub { vsxmem_op(@_, 332); }; # lxvdsx
|
||||
# VSX instruction[s] masqueraded as made-up AltiVec/VMX
|
||||
my $vpermdi = sub { # xxpermdi
|
||||
my ($f, $vrt, $vra, $vrb, $dm) = @_;
|
||||
$dm = oct($dm) if ($dm =~ /^0/);
|
||||
" .long ".sprintf "0x%X",(60<<26)|($vrt<<21)|($vra<<16)|($vrb<<11)|($dm<<8)|(10<<3)|7;
|
||||
};
|
||||
|
||||
# PowerISA 2.07 stuff
|
||||
sub vcrypto_op {
|
||||
my ($f, $vrt, $vra, $vrb, $op) = @_;
|
||||
" .long ".sprintf "0x%X",(4<<26)|($vrt<<21)|($vra<<16)|($vrb<<11)|$op;
|
||||
}
|
||||
sub vfour {
|
||||
my ($f, $vrt, $vra, $vrb, $vrc, $op) = @_;
|
||||
" .long ".sprintf "0x%X",(4<<26)|($vrt<<21)|($vra<<16)|($vrb<<11)|($vrc<<6)|$op;
|
||||
};
|
||||
my $vcipher = sub { vcrypto_op(@_, 1288); };
|
||||
my $vcipherlast = sub { vcrypto_op(@_, 1289); };
|
||||
my $vncipher = sub { vcrypto_op(@_, 1352); };
|
||||
my $vncipherlast= sub { vcrypto_op(@_, 1353); };
|
||||
my $vsbox = sub { vcrypto_op(@_, 0, 1480); };
|
||||
my $vshasigmad = sub { my ($st,$six)=splice(@_,-2); vcrypto_op(@_, $st<<4|$six, 1730); };
|
||||
my $vshasigmaw = sub { my ($st,$six)=splice(@_,-2); vcrypto_op(@_, $st<<4|$six, 1666); };
|
||||
my $vpmsumb = sub { vcrypto_op(@_, 1032); };
|
||||
my $vpmsumd = sub { vcrypto_op(@_, 1224); };
|
||||
my $vpmsubh = sub { vcrypto_op(@_, 1096); };
|
||||
my $vpmsumw = sub { vcrypto_op(@_, 1160); };
|
||||
# These are not really crypto, but vcrypto_op template works
|
||||
my $vaddudm = sub { vcrypto_op(@_, 192); };
|
||||
my $vadduqm = sub { vcrypto_op(@_, 256); };
|
||||
my $vmuleuw = sub { vcrypto_op(@_, 648); };
|
||||
my $vmulouw = sub { vcrypto_op(@_, 136); };
|
||||
my $vrld = sub { vcrypto_op(@_, 196); };
|
||||
my $vsld = sub { vcrypto_op(@_, 1476); };
|
||||
my $vsrd = sub { vcrypto_op(@_, 1732); };
|
||||
my $vsubudm = sub { vcrypto_op(@_, 1216); };
|
||||
my $vaddcuq = sub { vcrypto_op(@_, 320); };
|
||||
my $vaddeuqm = sub { vfour(@_,60); };
|
||||
my $vaddecuq = sub { vfour(@_,61); };
|
||||
my $vmrgew = sub { vfour(@_,0,1932); };
|
||||
my $vmrgow = sub { vfour(@_,0,1676); };
|
||||
|
||||
my $mtsle = sub {
|
||||
my ($f, $arg) = @_;
|
||||
" .long ".sprintf "0x%X",(31<<26)|($arg<<21)|(147*2);
|
||||
};
|
||||
|
||||
# VSX instructions masqueraded as AltiVec/VMX
|
||||
my $mtvrd = sub {
|
||||
my ($f, $vrt, $ra) = @_;
|
||||
" .long ".sprintf "0x%X",(31<<26)|($vrt<<21)|($ra<<16)|(179<<1)|1;
|
||||
};
|
||||
my $mtvrwz = sub {
|
||||
my ($f, $vrt, $ra) = @_;
|
||||
" .long ".sprintf "0x%X",(31<<26)|($vrt<<21)|($ra<<16)|(243<<1)|1;
|
||||
};
|
||||
my $lvwzx_u = sub { vsxmem_op(@_, 12); }; # lxsiwzx
|
||||
my $stvwx_u = sub { vsxmem_op(@_, 140); }; # stxsiwx
|
||||
|
||||
# PowerISA 3.0 stuff
|
||||
my $maddhdu = sub { vfour(@_,49); };
|
||||
my $maddld = sub { vfour(@_,51); };
|
||||
my $darn = sub {
|
||||
my ($f, $rt, $l) = @_;
|
||||
" .long ".sprintf "0x%X",(31<<26)|($rt<<21)|($l<<16)|(755<<1);
|
||||
};
|
||||
my $iseleq = sub {
|
||||
my ($f, $rt, $ra, $rb) = @_;
|
||||
" .long ".sprintf "0x%X",(31<<26)|($rt<<21)|($ra<<16)|($rb<<11)|(2<<6)|30;
|
||||
};
|
||||
# VSX instruction[s] masqueraded as made-up AltiVec/VMX
|
||||
my $vspltib = sub { # xxspltib
|
||||
my ($f, $vrt, $imm8) = @_;
|
||||
$imm8 = oct($imm8) if ($imm8 =~ /^0/);
|
||||
$imm8 &= 0xff;
|
||||
" .long ".sprintf "0x%X",(60<<26)|($vrt<<21)|($imm8<<11)|(360<<1)|1;
|
||||
};
|
||||
|
||||
# PowerISA 3.0B stuff
|
||||
my $addex = sub {
|
||||
my ($f, $rt, $ra, $rb, $cy) = @_; # only cy==0 is specified in 3.0B
|
||||
" .long ".sprintf "0x%X",(31<<26)|($rt<<21)|($ra<<16)|($rb<<11)|($cy<<9)|(170<<1);
|
||||
};
|
||||
my $vmsumudm = sub { vfour(@_,35); };
|
||||
|
||||
while($line=<>) {
|
||||
|
||||
$line =~ s|[#!;].*$||; # get rid of asm-style comments...
|
||||
$line =~ s|/\*.*\*/||; # ... and C-style comments...
|
||||
$line =~ s|^\s+||; # ... and skip white spaces in beginning...
|
||||
$line =~ s|\s+$||; # ... and at the end
|
||||
|
||||
{
|
||||
$line =~ s|\.L(\w+)|L$1|g; # common denominator for Locallabel
|
||||
$line =~ s|\bL(\w+)|\.L$1|g if ($dotinlocallabels);
|
||||
}
|
||||
|
||||
{
|
||||
$line =~ s|(^[\.\w]+)\:\s*||;
|
||||
my $label = $1;
|
||||
if ($label) {
|
||||
my $xlated = ($GLOBALS{$label} or $label);
|
||||
print "$xlated:";
|
||||
if ($flavour =~ /linux.*64(le|v2)/) {
|
||||
if ($TYPES{$label} =~ /function/) {
|
||||
printf "\n.localentry %s,0\n",$xlated;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
$line =~ s|^\s*(\.?)(\w+)([\.\+\-]?)\s*||;
|
||||
my $c = $1; $c = "\t" if ($c eq "");
|
||||
my $mnemonic = $2;
|
||||
my $f = $3;
|
||||
my $opcode = eval("\$$mnemonic");
|
||||
$line =~ s/\b(c?[rf]|v|vs)([0-9]+)\b/$2/g if ($c ne "." and $flavour !~ /osx/);
|
||||
if (ref($opcode) eq 'CODE') { $line = &$opcode($f,split(/,\s*/,$line)); }
|
||||
elsif ($mnemonic) { $line = $c.$mnemonic.$f."\t".$line; }
|
||||
}
|
||||
|
||||
print $line if ($line);
|
||||
print "\n";
|
||||
}
|
||||
|
||||
close STDOUT;
|
||||
413
security/nss/lib/freebl/scripts/sha512p8-ppc.pl
Normal file
413
security/nss/lib/freebl/scripts/sha512p8-ppc.pl
Normal file
|
|
@ -0,0 +1,413 @@
|
|||
#!/usr/bin/env perl
|
||||
|
||||
# ====================================================================
|
||||
# Written by Andy Polyakov, @dot-asm, initially for use in the OpenSSL
|
||||
# project. The module is dual licensed under OpenSSL and CRYPTOGAMS
|
||||
# licenses depending on where you obtain it. For further details see
|
||||
# https://github.com/dot-asm/cryptogams/.
|
||||
# ====================================================================
|
||||
|
||||
# SHA256/512 for PowerISA v2.07.
|
||||
#
|
||||
# Accurate performance measurements are problematic, because it's
|
||||
# always virtualized setup with possibly throttled processor.
|
||||
# Relative comparison is therefore more informative. This module is
|
||||
# ~60% faster than integer-only sha512-ppc.pl. To anchor to something
|
||||
# else, SHA256 is 24% slower than sha1-ppc.pl and 2.5x slower than
|
||||
# hardware-assisted aes-128-cbc encrypt. SHA512 is 20% faster than
|
||||
# sha1-ppc.pl and 1.6x slower than aes-128-cbc. Another interesting
|
||||
# result is degree of computational resources' utilization. POWER8 is
|
||||
# "massively multi-threaded chip" and difference between single- and
|
||||
# maximum multi-process benchmark results tells that utilization is
|
||||
# whooping 94%. For sha512-ppc.pl we get [not unimpressive] 84% and
|
||||
# for sha1-ppc.pl - 73%. 100% means that multi-process result equals
|
||||
# to single-process one, given that all threads end up on the same
|
||||
# physical core.
|
||||
#
|
||||
######################################################################
|
||||
# Believed-to-be-accurate results in cycles per processed byte [on
|
||||
# little-endian system]. Numbers in square brackets are for 64-bit
|
||||
# build of sha512-ppc.pl, presented for reference.
|
||||
#
|
||||
# POWER8 POWER9
|
||||
# SHA256 9.7 [15.8] 11.2 [12.5]
|
||||
# SHA512 6.1 [10.3] 7.0 [7.9]
|
||||
|
||||
$flavour=shift;
|
||||
$output =shift;
|
||||
|
||||
if ($flavour =~ /64/) {
|
||||
$SIZE_T=8;
|
||||
$LRSAVE=2*$SIZE_T;
|
||||
$STU="stdu";
|
||||
$POP="ld";
|
||||
$PUSH="std";
|
||||
} elsif ($flavour =~ /32/) {
|
||||
$SIZE_T=4;
|
||||
$LRSAVE=$SIZE_T;
|
||||
$STU="stwu";
|
||||
$POP="lwz";
|
||||
$PUSH="stw";
|
||||
} else { die "nonsense $flavour"; }
|
||||
|
||||
$LENDIAN=($flavour=~/le/);
|
||||
|
||||
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
|
||||
( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
|
||||
( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
|
||||
die "can't locate ppc-xlate.pl";
|
||||
|
||||
open STDOUT,"| $^X $xlate $flavour $output" || die "can't call $xlate: $!";
|
||||
|
||||
if ($output =~ /512/) {
|
||||
$bits=512;
|
||||
$SZ=8;
|
||||
$sz="d";
|
||||
$rounds=80;
|
||||
} else {
|
||||
$bits=256;
|
||||
$SZ=4;
|
||||
$sz="w";
|
||||
$rounds=64;
|
||||
}
|
||||
|
||||
$func="sha${bits}_block_p8";
|
||||
$LOCALS=8*$SIZE_T+8*16;
|
||||
$FRAME=$LOCALS+9*16+6*$SIZE_T;
|
||||
|
||||
$sp ="r1";
|
||||
$toc="r2";
|
||||
$ctx="r3";
|
||||
$inp="r4";
|
||||
$num="r5";
|
||||
$Tbl="r6";
|
||||
$idx="r7";
|
||||
$lrsave="r8";
|
||||
$offload="r11";
|
||||
$vrsave="r12";
|
||||
@I = ($x00,$x10,$x20,$x30,$x40,$x50,$x60,$x70) = (0,map("r$_",(10,26..31)));
|
||||
|
||||
@V=($A,$B,$C,$D,$E,$F,$G,$H)=map("v$_",(0..7));
|
||||
@X=map("v$_",(8..19,24..27));
|
||||
($Ki,$Func,$Sigma,$lemask)=map("v$_",(28..31));
|
||||
|
||||
sub ROUND {
|
||||
my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
|
||||
my $j=($i+1)%16;
|
||||
my $k=($i+2)%8;
|
||||
|
||||
$code.=<<___ if ($i<15 && ($i%(16/$SZ))==(16/$SZ-1));
|
||||
lvx_u @X[$i+1],0,$inp ; load X[i] in advance
|
||||
addi $inp,$inp,16
|
||||
___
|
||||
$code.=<<___ if ($i<16 && ($i%(16/$SZ)));
|
||||
vsldoi @X[$i],@X[$i-1],@X[$i-1],$SZ
|
||||
___
|
||||
$code.=<<___ if ($LENDIAN && $i<16 && ($i%(16/$SZ))==0);
|
||||
vperm @X[$i],@X[$i],@X[$i],$lemask
|
||||
___
|
||||
$code.=<<___ if ($i>=15);
|
||||
vshasigma${sz} $Sigma,@X[($j+1)%16],0,0
|
||||
vaddu${sz}m @X[$j],@X[$j],$Sigma
|
||||
vshasigma${sz} $Sigma,@X[($j+14)%16],0,15
|
||||
vaddu${sz}m @X[$j],@X[$j],$Sigma
|
||||
vaddu${sz}m @X[$j],@X[$j],@X[($j+9)%16]
|
||||
___
|
||||
$code.=<<___;
|
||||
vaddu${sz}m $h,$h,@X[$i%16] ; h+=X[i]
|
||||
vsel $Func,$g,$f,$e ; Ch(e,f,g)
|
||||
vaddu${sz}m $g,$g,$Ki ; future h+=K[i]
|
||||
vaddu${sz}m $h,$h,$Func ; h+=Ch(e,f,g)
|
||||
vshasigma${sz} $Sigma,$e,1,15 ; Sigma1(e)
|
||||
vaddu${sz}m $h,$h,$Sigma ; h+=Sigma1(e)
|
||||
vxor $Func,$a,$b
|
||||
vsel $Func,$b,$c,$Func ; Maj(a,b,c)
|
||||
vaddu${sz}m $d,$d,$h ; d+=h
|
||||
vshasigma${sz} $Sigma,$a,1,0 ; Sigma0(a)
|
||||
vaddu${sz}m $Sigma,$Sigma,$Func ; Sigma0(a)+Maj(a,b,c)
|
||||
vaddu${sz}m $h,$h,$Sigma ; h+=Sigma0(a)+Maj(a,b,c)
|
||||
lvx $Ki,@I[$k],$idx ; load next K[i]
|
||||
___
|
||||
$code.=<<___ if ($k == 7);
|
||||
addi $idx,$idx,0x80
|
||||
___
|
||||
}
|
||||
|
||||
$code=<<___;
|
||||
.machine "any"
|
||||
.text
|
||||
|
||||
.globl $func
|
||||
.align 6
|
||||
$func:
|
||||
$STU $sp,-$FRAME($sp)
|
||||
mflr $lrsave
|
||||
li r10,`$LOCALS+15`
|
||||
li r11,`$LOCALS+31`
|
||||
stvx v24,r10,$sp # ABI says so
|
||||
addi r10,r10,32
|
||||
mfspr $vrsave,256
|
||||
stvx v25,r11,$sp
|
||||
addi r11,r11,32
|
||||
stvx v26,r10,$sp
|
||||
addi r10,r10,32
|
||||
stvx v27,r11,$sp
|
||||
addi r11,r11,32
|
||||
stvx v28,r10,$sp
|
||||
addi r10,r10,32
|
||||
stvx v29,r11,$sp
|
||||
addi r11,r11,32
|
||||
stvx v30,r10,$sp
|
||||
stvx v31,r11,$sp
|
||||
li r11,-4096+255 # 0xfffff0ff
|
||||
stw $vrsave,`$FRAME-6*$SIZE_T-4`($sp) # save vrsave
|
||||
li $x10,0x10
|
||||
$PUSH r26,`$FRAME-6*$SIZE_T`($sp)
|
||||
li $x20,0x20
|
||||
$PUSH r27,`$FRAME-5*$SIZE_T`($sp)
|
||||
li $x30,0x30
|
||||
$PUSH r28,`$FRAME-4*$SIZE_T`($sp)
|
||||
li $x40,0x40
|
||||
$PUSH r29,`$FRAME-3*$SIZE_T`($sp)
|
||||
li $x50,0x50
|
||||
$PUSH r30,`$FRAME-2*$SIZE_T`($sp)
|
||||
li $x60,0x60
|
||||
$PUSH r31,`$FRAME-1*$SIZE_T`($sp)
|
||||
li $x70,0x70
|
||||
$PUSH $lrsave,`$FRAME+$LRSAVE`($sp)
|
||||
mtspr 256,r11
|
||||
|
||||
bl LPICmeup
|
||||
addi $offload,$sp,`8*$SIZE_T+15`
|
||||
___
|
||||
$code.=<<___ if ($LENDIAN);
|
||||
li $idx,8
|
||||
lvsl $lemask,0,$idx
|
||||
vspltisb $Ki,0x0f
|
||||
vxor $lemask,$lemask,$Ki
|
||||
___
|
||||
$code.=<<___ if ($SZ==4);
|
||||
lvx_4w $A,$x00,$ctx
|
||||
lvx_4w $E,$x10,$ctx
|
||||
vsldoi $B,$A,$A,4 # unpack
|
||||
vsldoi $C,$A,$A,8
|
||||
vsldoi $D,$A,$A,12
|
||||
vsldoi $F,$E,$E,4
|
||||
vsldoi $G,$E,$E,8
|
||||
vsldoi $H,$E,$E,12
|
||||
___
|
||||
$code.=<<___ if ($SZ==8);
|
||||
lvx_u $A,$x00,$ctx
|
||||
lvx_u $C,$x10,$ctx
|
||||
lvx_u $E,$x20,$ctx
|
||||
vsldoi $B,$A,$A,8 # unpack
|
||||
lvx_u $G,$x30,$ctx
|
||||
vsldoi $D,$C,$C,8
|
||||
vsldoi $F,$E,$E,8
|
||||
vsldoi $H,$G,$G,8
|
||||
___
|
||||
$code.=<<___;
|
||||
li r0,`($rounds-16)/16` # inner loop counter
|
||||
b Loop
|
||||
.align 5
|
||||
Loop:
|
||||
lvx $Ki,$x00,$Tbl
|
||||
lvx_u @X[0],0,$inp
|
||||
addi $inp,$inp,16
|
||||
mr $idx,$Tbl # copy $Tbl
|
||||
stvx $A,$x00,$offload # offload $A-$H
|
||||
stvx $B,$x10,$offload
|
||||
stvx $C,$x20,$offload
|
||||
stvx $D,$x30,$offload
|
||||
stvx $E,$x40,$offload
|
||||
stvx $F,$x50,$offload
|
||||
stvx $G,$x60,$offload
|
||||
stvx $H,$x70,$offload
|
||||
vaddu${sz}m $H,$H,$Ki # h+K[i]
|
||||
lvx $Ki,$x10,$Tbl
|
||||
___
|
||||
for ($i=0;$i<16;$i++) { &ROUND($i,@V); unshift(@V,pop(@V)); }
|
||||
$code.=<<___;
|
||||
mtctr r0
|
||||
b L16_xx
|
||||
.align 5
|
||||
L16_xx:
|
||||
___
|
||||
for (;$i<32;$i++) { &ROUND($i,@V); unshift(@V,pop(@V)); }
|
||||
$code.=<<___;
|
||||
bdnz L16_xx
|
||||
|
||||
lvx @X[2],$x00,$offload
|
||||
subic. $num,$num,1
|
||||
lvx @X[3],$x10,$offload
|
||||
vaddu${sz}m $A,$A,@X[2]
|
||||
lvx @X[4],$x20,$offload
|
||||
vaddu${sz}m $B,$B,@X[3]
|
||||
lvx @X[5],$x30,$offload
|
||||
vaddu${sz}m $C,$C,@X[4]
|
||||
lvx @X[6],$x40,$offload
|
||||
vaddu${sz}m $D,$D,@X[5]
|
||||
lvx @X[7],$x50,$offload
|
||||
vaddu${sz}m $E,$E,@X[6]
|
||||
lvx @X[8],$x60,$offload
|
||||
vaddu${sz}m $F,$F,@X[7]
|
||||
lvx @X[9],$x70,$offload
|
||||
vaddu${sz}m $G,$G,@X[8]
|
||||
vaddu${sz}m $H,$H,@X[9]
|
||||
bne Loop
|
||||
___
|
||||
$code.=<<___ if ($SZ==4);
|
||||
lvx @X[0],$x20,$idx
|
||||
vperm $A,$A,$B,$Ki # pack the answer
|
||||
lvx @X[1],$x30,$idx
|
||||
vperm $E,$E,$F,$Ki
|
||||
vperm $A,$A,$C,@X[0]
|
||||
vperm $E,$E,$G,@X[0]
|
||||
vperm $A,$A,$D,@X[1]
|
||||
vperm $E,$E,$H,@X[1]
|
||||
stvx_4w $A,$x00,$ctx
|
||||
stvx_4w $E,$x10,$ctx
|
||||
___
|
||||
$code.=<<___ if ($SZ==8);
|
||||
vperm $A,$A,$B,$Ki # pack the answer
|
||||
vperm $C,$C,$D,$Ki
|
||||
vperm $E,$E,$F,$Ki
|
||||
vperm $G,$G,$H,$Ki
|
||||
stvx_u $A,$x00,$ctx
|
||||
stvx_u $C,$x10,$ctx
|
||||
stvx_u $E,$x20,$ctx
|
||||
stvx_u $G,$x30,$ctx
|
||||
___
|
||||
$code.=<<___;
|
||||
addi $offload,$sp,`$LOCALS+15`
|
||||
mtlr $lrsave
|
||||
mtspr 256,$vrsave
|
||||
lvx v24,$x00,$offload # ABI says so
|
||||
lvx v25,$x10,$offload
|
||||
lvx v26,$x20,$offload
|
||||
lvx v27,$x30,$offload
|
||||
lvx v28,$x40,$offload
|
||||
lvx v29,$x50,$offload
|
||||
lvx v30,$x60,$offload
|
||||
lvx v31,$x70,$offload
|
||||
$POP r26,`$FRAME-6*$SIZE_T`($sp)
|
||||
$POP r27,`$FRAME-5*$SIZE_T`($sp)
|
||||
$POP r28,`$FRAME-4*$SIZE_T`($sp)
|
||||
$POP r29,`$FRAME-3*$SIZE_T`($sp)
|
||||
$POP r30,`$FRAME-2*$SIZE_T`($sp)
|
||||
$POP r31,`$FRAME-1*$SIZE_T`($sp)
|
||||
addi $sp,$sp,$FRAME
|
||||
blr
|
||||
.long 0
|
||||
.byte 0,12,4,1,0x80,6,3,0
|
||||
.long 0
|
||||
.size $func,.-$func
|
||||
___
|
||||
|
||||
# Ugly hack here, because PPC assembler syntax seem to vary too
|
||||
# much from platforms to platform...
|
||||
$code.=<<___;
|
||||
.align 6
|
||||
LPICmeup:
|
||||
mflr r0
|
||||
bcl 20,31,\$+4
|
||||
mflr $Tbl ; vvvvvv "distance" between . and 1st data entry
|
||||
addi $Tbl,$Tbl,`64-8`
|
||||
mtlr r0
|
||||
blr
|
||||
.long 0
|
||||
.byte 0,12,0x14,0,0,0,0,0
|
||||
.space `64-9*4`
|
||||
___
|
||||
|
||||
if ($SZ==8) {
|
||||
local *table = sub {
|
||||
foreach(@_) { $code.=".quad $_,$_\n"; }
|
||||
};
|
||||
table(
|
||||
"0x428a2f98d728ae22","0x7137449123ef65cd",
|
||||
"0xb5c0fbcfec4d3b2f","0xe9b5dba58189dbbc",
|
||||
"0x3956c25bf348b538","0x59f111f1b605d019",
|
||||
"0x923f82a4af194f9b","0xab1c5ed5da6d8118",
|
||||
"0xd807aa98a3030242","0x12835b0145706fbe",
|
||||
"0x243185be4ee4b28c","0x550c7dc3d5ffb4e2",
|
||||
"0x72be5d74f27b896f","0x80deb1fe3b1696b1",
|
||||
"0x9bdc06a725c71235","0xc19bf174cf692694",
|
||||
"0xe49b69c19ef14ad2","0xefbe4786384f25e3",
|
||||
"0x0fc19dc68b8cd5b5","0x240ca1cc77ac9c65",
|
||||
"0x2de92c6f592b0275","0x4a7484aa6ea6e483",
|
||||
"0x5cb0a9dcbd41fbd4","0x76f988da831153b5",
|
||||
"0x983e5152ee66dfab","0xa831c66d2db43210",
|
||||
"0xb00327c898fb213f","0xbf597fc7beef0ee4",
|
||||
"0xc6e00bf33da88fc2","0xd5a79147930aa725",
|
||||
"0x06ca6351e003826f","0x142929670a0e6e70",
|
||||
"0x27b70a8546d22ffc","0x2e1b21385c26c926",
|
||||
"0x4d2c6dfc5ac42aed","0x53380d139d95b3df",
|
||||
"0x650a73548baf63de","0x766a0abb3c77b2a8",
|
||||
"0x81c2c92e47edaee6","0x92722c851482353b",
|
||||
"0xa2bfe8a14cf10364","0xa81a664bbc423001",
|
||||
"0xc24b8b70d0f89791","0xc76c51a30654be30",
|
||||
"0xd192e819d6ef5218","0xd69906245565a910",
|
||||
"0xf40e35855771202a","0x106aa07032bbd1b8",
|
||||
"0x19a4c116b8d2d0c8","0x1e376c085141ab53",
|
||||
"0x2748774cdf8eeb99","0x34b0bcb5e19b48a8",
|
||||
"0x391c0cb3c5c95a63","0x4ed8aa4ae3418acb",
|
||||
"0x5b9cca4f7763e373","0x682e6ff3d6b2b8a3",
|
||||
"0x748f82ee5defb2fc","0x78a5636f43172f60",
|
||||
"0x84c87814a1f0ab72","0x8cc702081a6439ec",
|
||||
"0x90befffa23631e28","0xa4506cebde82bde9",
|
||||
"0xbef9a3f7b2c67915","0xc67178f2e372532b",
|
||||
"0xca273eceea26619c","0xd186b8c721c0c207",
|
||||
"0xeada7dd6cde0eb1e","0xf57d4f7fee6ed178",
|
||||
"0x06f067aa72176fba","0x0a637dc5a2c898a6",
|
||||
"0x113f9804bef90dae","0x1b710b35131c471b",
|
||||
"0x28db77f523047d84","0x32caab7b40c72493",
|
||||
"0x3c9ebe0a15c9bebc","0x431d67c49c100d4c",
|
||||
"0x4cc5d4becb3e42b6","0x597f299cfc657e2a",
|
||||
"0x5fcb6fab3ad6faec","0x6c44198c4a475817","0");
|
||||
$code.=<<___ if (!$LENDIAN);
|
||||
.quad 0x0001020304050607,0x1011121314151617
|
||||
___
|
||||
$code.=<<___ if ($LENDIAN); # quad-swapped
|
||||
.quad 0x1011121314151617,0x0001020304050607
|
||||
___
|
||||
} else {
|
||||
local *table = sub {
|
||||
foreach(@_) { $code.=".long $_,$_,$_,$_\n"; }
|
||||
};
|
||||
table(
|
||||
"0x428a2f98","0x71374491","0xb5c0fbcf","0xe9b5dba5",
|
||||
"0x3956c25b","0x59f111f1","0x923f82a4","0xab1c5ed5",
|
||||
"0xd807aa98","0x12835b01","0x243185be","0x550c7dc3",
|
||||
"0x72be5d74","0x80deb1fe","0x9bdc06a7","0xc19bf174",
|
||||
"0xe49b69c1","0xefbe4786","0x0fc19dc6","0x240ca1cc",
|
||||
"0x2de92c6f","0x4a7484aa","0x5cb0a9dc","0x76f988da",
|
||||
"0x983e5152","0xa831c66d","0xb00327c8","0xbf597fc7",
|
||||
"0xc6e00bf3","0xd5a79147","0x06ca6351","0x14292967",
|
||||
"0x27b70a85","0x2e1b2138","0x4d2c6dfc","0x53380d13",
|
||||
"0x650a7354","0x766a0abb","0x81c2c92e","0x92722c85",
|
||||
"0xa2bfe8a1","0xa81a664b","0xc24b8b70","0xc76c51a3",
|
||||
"0xd192e819","0xd6990624","0xf40e3585","0x106aa070",
|
||||
"0x19a4c116","0x1e376c08","0x2748774c","0x34b0bcb5",
|
||||
"0x391c0cb3","0x4ed8aa4a","0x5b9cca4f","0x682e6ff3",
|
||||
"0x748f82ee","0x78a5636f","0x84c87814","0x8cc70208",
|
||||
"0x90befffa","0xa4506ceb","0xbef9a3f7","0xc67178f2","0");
|
||||
$code.=<<___ if (!$LENDIAN);
|
||||
.long 0x00010203,0x10111213,0x10111213,0x10111213
|
||||
.long 0x00010203,0x04050607,0x10111213,0x10111213
|
||||
.long 0x00010203,0x04050607,0x08090a0b,0x10111213
|
||||
___
|
||||
$code.=<<___ if ($LENDIAN); # word-swapped
|
||||
.long 0x10111213,0x10111213,0x10111213,0x00010203
|
||||
.long 0x10111213,0x10111213,0x04050607,0x00010203
|
||||
.long 0x10111213,0x08090a0b,0x04050607,0x00010203
|
||||
___
|
||||
}
|
||||
$code.=<<___;
|
||||
.asciz "SHA${bits} for PowerISA 2.07, CRYPTOGAMS by <appro\@openssl.org>"
|
||||
.align 2
|
||||
___
|
||||
|
||||
$code =~ s/\`([^\`]*)\`/eval $1/gem;
|
||||
print $code;
|
||||
close STDOUT;
|
||||
28
security/nss/lib/freebl/secmpi.c
Normal file
28
security/nss/lib/freebl/secmpi.c
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#include "blapi.h"
|
||||
|
||||
#include "mpi.h"
|
||||
#include "mpprime.h"
|
||||
|
||||
mp_err
|
||||
mpp_random_secure(mp_int *a)
|
||||
{
|
||||
SECStatus rv;
|
||||
rv = RNG_GenerateGlobalRandomBytes((unsigned char *)MP_DIGITS(a), MP_USED(a) * sizeof(mp_digit));
|
||||
if (rv != SECSuccess) {
|
||||
return MP_UNDEF;
|
||||
}
|
||||
MP_SIGN(a) = MP_ZPOS;
|
||||
return MP_OKAY;
|
||||
}
|
||||
|
||||
mp_err
|
||||
mpp_pprime_secure(mp_int *a, int nt)
|
||||
{
|
||||
return mpp_pprime_ext_random(a, nt, &mpp_random_secure);
|
||||
}
|
||||
|
||||
mp_err
|
||||
mpp_make_prime_secure(mp_int *start, mp_size nBits, mp_size strong)
|
||||
{
|
||||
return mpp_make_prime_ext_random(start, nBits, strong, &mpp_random_secure);
|
||||
}
|
||||
|
|
@ -52,3 +52,12 @@
|
|||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); \
|
||||
break; \
|
||||
}
|
||||
|
||||
/* Fill the `used` digits of an mp_int with random bits */
|
||||
mp_err mpp_random_secure(mp_int *a);
|
||||
|
||||
/* Pseudo-primality testing using `mpp_random_secure` to choose Miller-Rabin base */
|
||||
mp_err mpp_pprime_secure(mp_int *a, int nt);
|
||||
|
||||
/* Variant of `mpp_make_prime` using `mpp_random_secure` to choose Miller-Rabin base */
|
||||
mp_err mpp_make_prime_secure(mp_int *start, mp_size nBits, mp_size strong);
|
||||
|
|
|
|||
264
security/nss/lib/freebl/sha1-armv8.c
Normal file
264
security/nss/lib/freebl/sha1-armv8.c
Normal file
|
|
@ -0,0 +1,264 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifdef USE_HW_SHA1
|
||||
|
||||
#ifndef __ARM_FEATURE_CRYPTO
|
||||
#error "Compiler option is invalid"
|
||||
#endif
|
||||
|
||||
#ifdef FREEBL_NO_DEPEND
|
||||
#include "stubs.h"
|
||||
#endif
|
||||
|
||||
#include <arm_neon.h>
|
||||
#include <memory.h>
|
||||
#include "blapi.h"
|
||||
#include "sha_fast.h"
|
||||
|
||||
#if !defined(SHA_PUT_W_IN_STACK)
|
||||
#define H2X 11
|
||||
#else
|
||||
#define H2X 0
|
||||
#endif
|
||||
|
||||
static void shaCompress(SHA_HW_t *X, const PRUint32 *datain);
|
||||
|
||||
void
|
||||
SHA1_Compress_Native(SHA1Context *ctx)
|
||||
{
|
||||
shaCompress(&ctx->H[H2X], ctx->u.w);
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA: Add data to context.
|
||||
*/
|
||||
void
|
||||
SHA1_Update_Native(SHA1Context *ctx, const unsigned char *dataIn, unsigned int len)
|
||||
{
|
||||
unsigned int lenB;
|
||||
unsigned int togo;
|
||||
|
||||
if (!len) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* accumulate the byte count. */
|
||||
lenB = (unsigned int)(ctx->size) & 63U;
|
||||
|
||||
ctx->size += len;
|
||||
|
||||
/*
|
||||
* Read the data into W and process blocks as they get full
|
||||
*/
|
||||
if (lenB > 0) {
|
||||
togo = 64U - lenB;
|
||||
if (len < togo) {
|
||||
togo = len;
|
||||
}
|
||||
memcpy(ctx->u.b + lenB, dataIn, togo);
|
||||
len -= togo;
|
||||
dataIn += togo;
|
||||
lenB = (lenB + togo) & 63U;
|
||||
if (!lenB) {
|
||||
shaCompress(&ctx->H[H2X], ctx->u.w);
|
||||
}
|
||||
}
|
||||
|
||||
while (len >= 64U) {
|
||||
len -= 64U;
|
||||
shaCompress(&ctx->H[H2X], (PRUint32 *)dataIn);
|
||||
dataIn += 64U;
|
||||
}
|
||||
|
||||
if (len) {
|
||||
memcpy(ctx->u.b, dataIn, len);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA: Compression function, unrolled.
|
||||
*/
|
||||
static void
|
||||
shaCompress(SHA_HW_t *X, const PRUint32 *inbuf)
|
||||
{
|
||||
#define XH(n) X[n - H2X]
|
||||
|
||||
const uint32x4_t K0 = vdupq_n_u32(0x5a827999);
|
||||
const uint32x4_t K1 = vdupq_n_u32(0x6ed9eba1);
|
||||
const uint32x4_t K2 = vdupq_n_u32(0x8f1bbcdc);
|
||||
const uint32x4_t K3 = vdupq_n_u32(0xca62c1d6);
|
||||
|
||||
uint32x4_t abcd = vld1q_u32(&XH(0));
|
||||
PRUint32 e = XH(4);
|
||||
|
||||
const uint32x4_t origABCD = abcd;
|
||||
const PRUint32 origE = e;
|
||||
|
||||
uint32x4_t w0 = vld1q_u32(inbuf);
|
||||
uint32x4_t w1 = vld1q_u32(inbuf + 4);
|
||||
uint32x4_t w2 = vld1q_u32(inbuf + 8);
|
||||
uint32x4_t w3 = vld1q_u32(inbuf + 12);
|
||||
|
||||
w0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(w0)));
|
||||
w1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(w1)));
|
||||
w2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(w2)));
|
||||
w3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(w3)));
|
||||
|
||||
uint32x4_t t0 = vaddq_u32(w0, K0);
|
||||
uint32x4_t t1 = vaddq_u32(w1, K0);
|
||||
|
||||
PRUint32 tmpE;
|
||||
|
||||
/*
|
||||
* Using the following ARM instructions to accelerate SHA1
|
||||
*
|
||||
* sha1c for round 0 - 20
|
||||
* sha1p for round 20 - 40
|
||||
* sha1m for round 40 - 60
|
||||
* sha1p for round 60 - 80
|
||||
* sha1su0 and shasu1 for message schedule
|
||||
* sha1h for rotate left 30
|
||||
*/
|
||||
|
||||
/* Round 0-3 */
|
||||
tmpE = vsha1h_u32(vgetq_lane_u32(abcd, 0));
|
||||
abcd = vsha1cq_u32(abcd, e, t0);
|
||||
t0 = vaddq_u32(w2, K0);
|
||||
w0 = vsha1su0q_u32(w0, w1, w2);
|
||||
|
||||
/* Round 4-7 */
|
||||
e = vsha1h_u32(vgetq_lane_u32(abcd, 0));
|
||||
abcd = vsha1cq_u32(abcd, tmpE, t1);
|
||||
t1 = vaddq_u32(w3, K0);
|
||||
w0 = vsha1su1q_u32(w0, w3);
|
||||
w1 = vsha1su0q_u32(w1, w2, w3);
|
||||
|
||||
/* Round 8-11 */
|
||||
tmpE = vsha1h_u32(vgetq_lane_u32(abcd, 0));
|
||||
abcd = vsha1cq_u32(abcd, e, t0);
|
||||
t0 = vaddq_u32(w0, K0);
|
||||
w1 = vsha1su1q_u32(w1, w0);
|
||||
w2 = vsha1su0q_u32(w2, w3, w0);
|
||||
|
||||
/* Round 12-15 */
|
||||
e = vsha1h_u32(vgetq_lane_u32(abcd, 0));
|
||||
abcd = vsha1cq_u32(abcd, tmpE, t1);
|
||||
t1 = vaddq_u32(w1, K1);
|
||||
w2 = vsha1su1q_u32(w2, w1);
|
||||
w3 = vsha1su0q_u32(w3, w0, w1);
|
||||
|
||||
/* Round 16-19 */
|
||||
tmpE = vsha1h_u32(vgetq_lane_u32(abcd, 0));
|
||||
abcd = vsha1cq_u32(abcd, e, t0);
|
||||
t0 = vaddq_u32(w2, K1);
|
||||
w3 = vsha1su1q_u32(w3, w2);
|
||||
w0 = vsha1su0q_u32(w0, w1, w2);
|
||||
|
||||
/* Round 20-23 */
|
||||
e = vsha1h_u32(vgetq_lane_u32(abcd, 0));
|
||||
abcd = vsha1pq_u32(abcd, tmpE, t1);
|
||||
t1 = vaddq_u32(w3, K1);
|
||||
w0 = vsha1su1q_u32(w0, w3);
|
||||
w1 = vsha1su0q_u32(w1, w2, w3);
|
||||
|
||||
/* Round 24-27 */
|
||||
tmpE = vsha1h_u32(vgetq_lane_u32(abcd, 0));
|
||||
abcd = vsha1pq_u32(abcd, e, t0);
|
||||
t0 = vaddq_u32(w0, K1);
|
||||
w1 = vsha1su1q_u32(w1, w0);
|
||||
w2 = vsha1su0q_u32(w2, w3, w0);
|
||||
|
||||
/* Round 28-31 */
|
||||
e = vsha1h_u32(vgetq_lane_u32(abcd, 0));
|
||||
abcd = vsha1pq_u32(abcd, tmpE, t1);
|
||||
t1 = vaddq_u32(w1, K1);
|
||||
w2 = vsha1su1q_u32(w2, w1);
|
||||
w3 = vsha1su0q_u32(w3, w0, w1);
|
||||
|
||||
/* Round 32-35 */
|
||||
tmpE = vsha1h_u32(vgetq_lane_u32(abcd, 0));
|
||||
abcd = vsha1pq_u32(abcd, e, t0);
|
||||
t0 = vaddq_u32(w2, K2);
|
||||
w3 = vsha1su1q_u32(w3, w2);
|
||||
w0 = vsha1su0q_u32(w0, w1, w2);
|
||||
|
||||
/* Round 36-39 */
|
||||
e = vsha1h_u32(vgetq_lane_u32(abcd, 0));
|
||||
abcd = vsha1pq_u32(abcd, tmpE, t1);
|
||||
t1 = vaddq_u32(w3, K2);
|
||||
w0 = vsha1su1q_u32(w0, w3);
|
||||
w1 = vsha1su0q_u32(w1, w2, w3);
|
||||
|
||||
/* Round 40-43 */
|
||||
tmpE = vsha1h_u32(vgetq_lane_u32(abcd, 0));
|
||||
abcd = vsha1mq_u32(abcd, e, t0);
|
||||
t0 = vaddq_u32(w0, K2);
|
||||
w1 = vsha1su1q_u32(w1, w0);
|
||||
w2 = vsha1su0q_u32(w2, w3, w0);
|
||||
|
||||
/* Round 44-47 */
|
||||
e = vsha1h_u32(vgetq_lane_u32(abcd, 0));
|
||||
abcd = vsha1mq_u32(abcd, tmpE, t1);
|
||||
t1 = vaddq_u32(w1, K2);
|
||||
w2 = vsha1su1q_u32(w2, w1);
|
||||
w3 = vsha1su0q_u32(w3, w0, w1);
|
||||
|
||||
/* Round 48-51 */
|
||||
tmpE = vsha1h_u32(vgetq_lane_u32(abcd, 0));
|
||||
abcd = vsha1mq_u32(abcd, e, t0);
|
||||
t0 = vaddq_u32(w2, K2);
|
||||
w3 = vsha1su1q_u32(w3, w2);
|
||||
w0 = vsha1su0q_u32(w0, w1, w2);
|
||||
|
||||
/* Round 52-55 */
|
||||
e = vsha1h_u32(vgetq_lane_u32(abcd, 0));
|
||||
abcd = vsha1mq_u32(abcd, tmpE, t1);
|
||||
t1 = vaddq_u32(w3, K3);
|
||||
w0 = vsha1su1q_u32(w0, w3);
|
||||
w1 = vsha1su0q_u32(w1, w2, w3);
|
||||
|
||||
/* Round 56-59 */
|
||||
tmpE = vsha1h_u32(vgetq_lane_u32(abcd, 0));
|
||||
abcd = vsha1mq_u32(abcd, e, t0);
|
||||
t0 = vaddq_u32(w0, K3);
|
||||
w1 = vsha1su1q_u32(w1, w0);
|
||||
w2 = vsha1su0q_u32(w2, w3, w0);
|
||||
|
||||
/* Round 60-63 */
|
||||
e = vsha1h_u32(vgetq_lane_u32(abcd, 0));
|
||||
abcd = vsha1pq_u32(abcd, tmpE, t1);
|
||||
t1 = vaddq_u32(w1, K3);
|
||||
w2 = vsha1su1q_u32(w2, w1);
|
||||
w3 = vsha1su0q_u32(w3, w0, w1);
|
||||
|
||||
/* Round 64-67 */
|
||||
tmpE = vsha1h_u32(vgetq_lane_u32(abcd, 0));
|
||||
abcd = vsha1pq_u32(abcd, e, t0);
|
||||
t0 = vaddq_u32(w2, K3);
|
||||
w3 = vsha1su1q_u32(w3, w2);
|
||||
w0 = vsha1su0q_u32(w0, w1, w2);
|
||||
|
||||
/* Round 68-71 */
|
||||
e = vsha1h_u32(vgetq_lane_u32(abcd, 0));
|
||||
abcd = vsha1pq_u32(abcd, tmpE, t1);
|
||||
t1 = vaddq_u32(w3, K3);
|
||||
w0 = vsha1su1q_u32(w0, w3);
|
||||
|
||||
/* Round 72-75 */
|
||||
tmpE = vsha1h_u32(vgetq_lane_u32(abcd, 0));
|
||||
abcd = vsha1pq_u32(abcd, e, t0);
|
||||
|
||||
/* Round 76-79 */
|
||||
e = vsha1h_u32(vgetq_lane_u32(abcd, 0));
|
||||
abcd = vsha1pq_u32(abcd, tmpE, t1);
|
||||
|
||||
e += origE;
|
||||
abcd = vaddq_u32(origABCD, abcd);
|
||||
|
||||
vst1q_u32(&XH(0), abcd);
|
||||
XH(4) = e;
|
||||
}
|
||||
|
||||
#endif /* USE_HW_SHA1 */
|
||||
203
security/nss/lib/freebl/sha256-armv8.c
Normal file
203
security/nss/lib/freebl/sha256-armv8.c
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifdef USE_HW_SHA2
|
||||
|
||||
#ifndef __ARM_FEATURE_CRYPTO
|
||||
#error "Compiler option is invalid"
|
||||
#endif
|
||||
|
||||
#ifdef FREEBL_NO_DEPEND
|
||||
#include "stubs.h"
|
||||
#endif
|
||||
|
||||
#include "prcpucfg.h"
|
||||
#include "prtypes.h" /* for PRUintXX */
|
||||
#include "prlong.h"
|
||||
#include "blapi.h"
|
||||
#include "sha256.h"
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
/* SHA-256 constants, K256. */
|
||||
static const PRUint32 __attribute__((aligned(16))) K256[64] = {
|
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
|
||||
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
||||
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
|
||||
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
|
||||
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
||||
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
|
||||
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
|
||||
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
|
||||
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
||||
};
|
||||
|
||||
#define ROUND(n, a, b, c, d) \
|
||||
{ \
|
||||
uint32x4_t t = vaddq_u32(a, k##n); \
|
||||
uint32x4_t wt = w0; \
|
||||
w0 = vsha256hq_u32(w0, w1, t); \
|
||||
w1 = vsha256h2q_u32(w1, wt, t); \
|
||||
if (n < 12) { \
|
||||
a = vsha256su0q_u32(a, b); \
|
||||
a = vsha256su1q_u32(a, c, d); \
|
||||
} \
|
||||
}
|
||||
|
||||
void
|
||||
SHA256_Compress_Native(SHA256Context *ctx)
|
||||
{
|
||||
const uint32x4_t k0 = vld1q_u32(K256);
|
||||
const uint32x4_t k1 = vld1q_u32(K256 + 4);
|
||||
const uint32x4_t k2 = vld1q_u32(K256 + 8);
|
||||
const uint32x4_t k3 = vld1q_u32(K256 + 12);
|
||||
const uint32x4_t k4 = vld1q_u32(K256 + 16);
|
||||
const uint32x4_t k5 = vld1q_u32(K256 + 20);
|
||||
const uint32x4_t k6 = vld1q_u32(K256 + 24);
|
||||
const uint32x4_t k7 = vld1q_u32(K256 + 28);
|
||||
const uint32x4_t k8 = vld1q_u32(K256 + 32);
|
||||
const uint32x4_t k9 = vld1q_u32(K256 + 36);
|
||||
const uint32x4_t k10 = vld1q_u32(K256 + 40);
|
||||
const uint32x4_t k11 = vld1q_u32(K256 + 44);
|
||||
const uint32x4_t k12 = vld1q_u32(K256 + 48);
|
||||
const uint32x4_t k13 = vld1q_u32(K256 + 52);
|
||||
const uint32x4_t k14 = vld1q_u32(K256 + 56);
|
||||
const uint32x4_t k15 = vld1q_u32(K256 + 60);
|
||||
|
||||
uint32x4_t h0 = vld1q_u32(ctx->h);
|
||||
uint32x4_t h1 = vld1q_u32(ctx->h + 4);
|
||||
|
||||
unsigned char *input = ctx->u.b;
|
||||
|
||||
uint32x4_t a = vreinterpretq_u32_u8(vrev32q_u8(vld1q_u8(input)));
|
||||
uint32x4_t b = vreinterpretq_u32_u8(vrev32q_u8(vld1q_u8(input + 16)));
|
||||
uint32x4_t c = vreinterpretq_u32_u8(vrev32q_u8(vld1q_u8(input + 32)));
|
||||
uint32x4_t d = vreinterpretq_u32_u8(vrev32q_u8(vld1q_u8(input + 48)));
|
||||
|
||||
uint32x4_t w0 = h0;
|
||||
uint32x4_t w1 = h1;
|
||||
|
||||
ROUND(0, a, b, c, d)
|
||||
ROUND(1, b, c, d, a)
|
||||
ROUND(2, c, d, a, b)
|
||||
ROUND(3, d, a, b, c)
|
||||
ROUND(4, a, b, c, d)
|
||||
ROUND(5, b, c, d, a)
|
||||
ROUND(6, c, d, a, b)
|
||||
ROUND(7, d, a, b, c)
|
||||
ROUND(8, a, b, c, d)
|
||||
ROUND(9, b, c, d, a)
|
||||
ROUND(10, c, d, a, b)
|
||||
ROUND(11, d, a, b, c)
|
||||
ROUND(12, a, b, c, d)
|
||||
ROUND(13, b, c, d, a)
|
||||
ROUND(14, c, d, a, b)
|
||||
ROUND(15, d, a, b, c)
|
||||
|
||||
h0 = vaddq_u32(h0, w0);
|
||||
h1 = vaddq_u32(h1, w1);
|
||||
|
||||
vst1q_u32(ctx->h, h0);
|
||||
vst1q_u32(ctx->h + 4, h1);
|
||||
}
|
||||
|
||||
void
|
||||
SHA256_Update_Native(SHA256Context *ctx, const unsigned char *input,
|
||||
unsigned int inputLen)
|
||||
{
|
||||
const uint32x4_t k0 = vld1q_u32(K256);
|
||||
const uint32x4_t k1 = vld1q_u32(K256 + 4);
|
||||
const uint32x4_t k2 = vld1q_u32(K256 + 8);
|
||||
const uint32x4_t k3 = vld1q_u32(K256 + 12);
|
||||
const uint32x4_t k4 = vld1q_u32(K256 + 16);
|
||||
const uint32x4_t k5 = vld1q_u32(K256 + 20);
|
||||
const uint32x4_t k6 = vld1q_u32(K256 + 24);
|
||||
const uint32x4_t k7 = vld1q_u32(K256 + 28);
|
||||
const uint32x4_t k8 = vld1q_u32(K256 + 32);
|
||||
const uint32x4_t k9 = vld1q_u32(K256 + 36);
|
||||
const uint32x4_t k10 = vld1q_u32(K256 + 40);
|
||||
const uint32x4_t k11 = vld1q_u32(K256 + 44);
|
||||
const uint32x4_t k12 = vld1q_u32(K256 + 48);
|
||||
const uint32x4_t k13 = vld1q_u32(K256 + 52);
|
||||
const uint32x4_t k14 = vld1q_u32(K256 + 56);
|
||||
const uint32x4_t k15 = vld1q_u32(K256 + 60);
|
||||
|
||||
unsigned int inBuf = ctx->sizeLo & 0x3f;
|
||||
if (!inputLen) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Add inputLen into the count of bytes processed, before processing */
|
||||
if ((ctx->sizeLo += inputLen) < inputLen) {
|
||||
ctx->sizeHi++;
|
||||
}
|
||||
|
||||
/* if data already in buffer, attemp to fill rest of buffer */
|
||||
if (inBuf) {
|
||||
unsigned int todo = SHA256_BLOCK_LENGTH - inBuf;
|
||||
if (inputLen < todo) {
|
||||
todo = inputLen;
|
||||
}
|
||||
memcpy(ctx->u.b + inBuf, input, todo);
|
||||
input += todo;
|
||||
inputLen -= todo;
|
||||
if (inBuf + todo == SHA256_BLOCK_LENGTH) {
|
||||
SHA256_Compress_Native(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
uint32x4_t h0 = vld1q_u32(ctx->h);
|
||||
uint32x4_t h1 = vld1q_u32(ctx->h + 4);
|
||||
|
||||
/* if enough data to fill one or more whole buffers, process them. */
|
||||
while (inputLen >= SHA256_BLOCK_LENGTH) {
|
||||
uint32x4_t a, b, c, d;
|
||||
a = vreinterpretq_u32_u8(vrev32q_u8(vld1q_u8(input)));
|
||||
b = vreinterpretq_u32_u8(vrev32q_u8(vld1q_u8(input + 16)));
|
||||
c = vreinterpretq_u32_u8(vrev32q_u8(vld1q_u8(input + 32)));
|
||||
d = vreinterpretq_u32_u8(vrev32q_u8(vld1q_u8(input + 48)));
|
||||
input += SHA256_BLOCK_LENGTH;
|
||||
inputLen -= SHA256_BLOCK_LENGTH;
|
||||
|
||||
uint32x4_t w0 = h0;
|
||||
uint32x4_t w1 = h1;
|
||||
|
||||
ROUND(0, a, b, c, d)
|
||||
ROUND(1, b, c, d, a)
|
||||
ROUND(2, c, d, a, b)
|
||||
ROUND(3, d, a, b, c)
|
||||
ROUND(4, a, b, c, d)
|
||||
ROUND(5, b, c, d, a)
|
||||
ROUND(6, c, d, a, b)
|
||||
ROUND(7, d, a, b, c)
|
||||
ROUND(8, a, b, c, d)
|
||||
ROUND(9, b, c, d, a)
|
||||
ROUND(10, c, d, a, b)
|
||||
ROUND(11, d, a, b, c)
|
||||
ROUND(12, a, b, c, d)
|
||||
ROUND(13, b, c, d, a)
|
||||
ROUND(14, c, d, a, b)
|
||||
ROUND(15, d, a, b, c)
|
||||
|
||||
h0 = vaddq_u32(h0, w0);
|
||||
h1 = vaddq_u32(h1, w1);
|
||||
}
|
||||
|
||||
vst1q_u32(ctx->h, h0);
|
||||
vst1q_u32(ctx->h + 4, h1);
|
||||
|
||||
/* if data left over, fill it into buffer */
|
||||
if (inputLen) {
|
||||
memcpy(ctx->u.b, input, inputLen);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* USE_HW_SHA2 */
|
||||
236
security/nss/lib/freebl/sha256-x86.c
Normal file
236
security/nss/lib/freebl/sha256-x86.c
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifdef USE_HW_SHA2
|
||||
|
||||
#include <immintrin.h>
|
||||
|
||||
#ifdef FREEBL_NO_DEPEND
|
||||
#include "stubs.h"
|
||||
#endif
|
||||
|
||||
#include "blapii.h"
|
||||
#include "prcpucfg.h"
|
||||
#include "prtypes.h" /* for PRUintXX */
|
||||
#include "prlong.h"
|
||||
#include "blapi.h"
|
||||
#include "sha256.h"
|
||||
|
||||
/* SHA-256 constants, K256. */
|
||||
pre_align static const PRUint32 K256[64] post_align = {
|
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
|
||||
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
||||
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
|
||||
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
|
||||
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
||||
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
|
||||
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
|
||||
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
|
||||
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
||||
};
|
||||
|
||||
#define ROUND(n, a, b, c, d) \
|
||||
{ \
|
||||
__m128i t = _mm_add_epi32(a, k##n); \
|
||||
w1 = _mm_sha256rnds2_epu32(w1, w0, t); \
|
||||
t = _mm_shuffle_epi32(t, 0x0e); \
|
||||
w0 = _mm_sha256rnds2_epu32(w0, w1, t); \
|
||||
if (n < 12) { \
|
||||
a = _mm_sha256msg1_epu32(a, b); \
|
||||
a = _mm_add_epi32(a, _mm_alignr_epi8(d, c, 4)); \
|
||||
a = _mm_sha256msg2_epu32(a, d); \
|
||||
} \
|
||||
}
|
||||
|
||||
void
|
||||
SHA256_Compress_Native(SHA256Context *ctx)
|
||||
{
|
||||
__m128i h0, h1, th;
|
||||
__m128i a, b, c, d;
|
||||
__m128i w0, w1;
|
||||
const __m128i shuffle = _mm_set_epi8(12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3);
|
||||
|
||||
const __m128i *K = (__m128i *)K256;
|
||||
const __m128i k0 = _mm_load_si128(K);
|
||||
const __m128i k1 = _mm_load_si128(K + 1);
|
||||
const __m128i k2 = _mm_load_si128(K + 2);
|
||||
const __m128i k3 = _mm_load_si128(K + 3);
|
||||
const __m128i k4 = _mm_load_si128(K + 4);
|
||||
const __m128i k5 = _mm_load_si128(K + 5);
|
||||
const __m128i k6 = _mm_load_si128(K + 6);
|
||||
const __m128i k7 = _mm_load_si128(K + 7);
|
||||
const __m128i k8 = _mm_load_si128(K + 8);
|
||||
const __m128i k9 = _mm_load_si128(K + 9);
|
||||
const __m128i k10 = _mm_load_si128(K + 10);
|
||||
const __m128i k11 = _mm_load_si128(K + 11);
|
||||
const __m128i k12 = _mm_load_si128(K + 12);
|
||||
const __m128i k13 = _mm_load_si128(K + 13);
|
||||
const __m128i k14 = _mm_load_si128(K + 14);
|
||||
const __m128i k15 = _mm_load_si128(K + 15);
|
||||
|
||||
const __m128i *input = (__m128i *)ctx->u.b;
|
||||
|
||||
h0 = _mm_loadu_si128((__m128i *)(ctx->h));
|
||||
h1 = _mm_loadu_si128((__m128i *)(ctx->h + 4));
|
||||
|
||||
/* H0123:4567 -> H01256:H2367 */
|
||||
th = _mm_shuffle_epi32(h0, 0xb1);
|
||||
h1 = _mm_shuffle_epi32(h1, 0x1b);
|
||||
h0 = _mm_alignr_epi8(th, h1, 8);
|
||||
h1 = _mm_blend_epi16(h1, th, 0xf0);
|
||||
|
||||
a = _mm_shuffle_epi8(_mm_loadu_si128(input), shuffle);
|
||||
b = _mm_shuffle_epi8(_mm_loadu_si128(input + 1), shuffle);
|
||||
c = _mm_shuffle_epi8(_mm_loadu_si128(input + 2), shuffle);
|
||||
d = _mm_shuffle_epi8(_mm_loadu_si128(input + 3), shuffle);
|
||||
|
||||
w0 = h0;
|
||||
w1 = h1;
|
||||
|
||||
ROUND(0, a, b, c, d)
|
||||
ROUND(1, b, c, d, a)
|
||||
ROUND(2, c, d, a, b)
|
||||
ROUND(3, d, a, b, c)
|
||||
ROUND(4, a, b, c, d)
|
||||
ROUND(5, b, c, d, a)
|
||||
ROUND(6, c, d, a, b)
|
||||
ROUND(7, d, a, b, c)
|
||||
ROUND(8, a, b, c, d)
|
||||
ROUND(9, b, c, d, a)
|
||||
ROUND(10, c, d, a, b)
|
||||
ROUND(11, d, a, b, c)
|
||||
ROUND(12, a, b, c, d)
|
||||
ROUND(13, b, c, d, a)
|
||||
ROUND(14, c, d, a, b)
|
||||
ROUND(15, d, a, b, c)
|
||||
|
||||
h0 = _mm_add_epi32(h0, w0);
|
||||
h1 = _mm_add_epi32(h1, w1);
|
||||
|
||||
/* H0145:2367 -> H0123:4567 */
|
||||
th = _mm_shuffle_epi32(h0, 0x1b);
|
||||
h1 = _mm_shuffle_epi32(h1, 0xb1);
|
||||
h0 = _mm_blend_epi16(th, h1, 0xf0);
|
||||
h1 = _mm_alignr_epi8(h1, th, 8);
|
||||
|
||||
_mm_storeu_si128((__m128i *)ctx->h, h0);
|
||||
_mm_storeu_si128((__m128i *)(ctx->h + 4), h1);
|
||||
}
|
||||
|
||||
void
|
||||
SHA256_Update_Native(SHA256Context *ctx, const unsigned char *input,
|
||||
unsigned int inputLen)
|
||||
{
|
||||
__m128i h0, h1, th;
|
||||
const __m128i shuffle = _mm_set_epi8(12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3);
|
||||
|
||||
const __m128i *K = (__m128i *)K256;
|
||||
const __m128i k0 = _mm_load_si128(K);
|
||||
const __m128i k1 = _mm_load_si128(K + 1);
|
||||
const __m128i k2 = _mm_load_si128(K + 2);
|
||||
const __m128i k3 = _mm_load_si128(K + 3);
|
||||
const __m128i k4 = _mm_load_si128(K + 4);
|
||||
const __m128i k5 = _mm_load_si128(K + 5);
|
||||
const __m128i k6 = _mm_load_si128(K + 6);
|
||||
const __m128i k7 = _mm_load_si128(K + 7);
|
||||
const __m128i k8 = _mm_load_si128(K + 8);
|
||||
const __m128i k9 = _mm_load_si128(K + 9);
|
||||
const __m128i k10 = _mm_load_si128(K + 10);
|
||||
const __m128i k11 = _mm_load_si128(K + 11);
|
||||
const __m128i k12 = _mm_load_si128(K + 12);
|
||||
const __m128i k13 = _mm_load_si128(K + 13);
|
||||
const __m128i k14 = _mm_load_si128(K + 14);
|
||||
const __m128i k15 = _mm_load_si128(K + 15);
|
||||
|
||||
unsigned int inBuf = ctx->sizeLo & 0x3f;
|
||||
if (!inputLen) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Add inputLen into the count of bytes processed, before processing */
|
||||
if ((ctx->sizeLo += inputLen) < inputLen) {
|
||||
ctx->sizeHi++;
|
||||
}
|
||||
|
||||
/* if data already in buffer, attempt to fill rest of buffer */
|
||||
if (inBuf) {
|
||||
unsigned int todo = SHA256_BLOCK_LENGTH - inBuf;
|
||||
if (inputLen < todo) {
|
||||
todo = inputLen;
|
||||
}
|
||||
memcpy(ctx->u.b + inBuf, input, todo);
|
||||
input += todo;
|
||||
inputLen -= todo;
|
||||
if (inBuf + todo == SHA256_BLOCK_LENGTH) {
|
||||
SHA256_Compress_Native(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
h0 = _mm_loadu_si128((__m128i *)(ctx->h));
|
||||
h1 = _mm_loadu_si128((__m128i *)(ctx->h + 4));
|
||||
|
||||
/* H0123:4567 -> H01256:H2367 */
|
||||
th = _mm_shuffle_epi32(h0, 0xb1);
|
||||
h1 = _mm_shuffle_epi32(h1, 0x1b);
|
||||
h0 = _mm_alignr_epi8(th, h1, 8);
|
||||
h1 = _mm_blend_epi16(h1, th, 0xf0);
|
||||
|
||||
/* if enough data to fill one or more whole buffers, process them. */
|
||||
while (inputLen >= SHA256_BLOCK_LENGTH) {
|
||||
__m128i a, b, c, d;
|
||||
__m128i w0, w1;
|
||||
a = _mm_shuffle_epi8(_mm_loadu_si128((__m128i *)input), shuffle);
|
||||
b = _mm_shuffle_epi8(_mm_loadu_si128((__m128i *)(input + 16)), shuffle);
|
||||
c = _mm_shuffle_epi8(_mm_loadu_si128((__m128i *)(input + 32)), shuffle);
|
||||
d = _mm_shuffle_epi8(_mm_loadu_si128((__m128i *)(input + 48)), shuffle);
|
||||
input += SHA256_BLOCK_LENGTH;
|
||||
inputLen -= SHA256_BLOCK_LENGTH;
|
||||
|
||||
w0 = h0;
|
||||
w1 = h1;
|
||||
|
||||
ROUND(0, a, b, c, d)
|
||||
ROUND(1, b, c, d, a)
|
||||
ROUND(2, c, d, a, b)
|
||||
ROUND(3, d, a, b, c)
|
||||
ROUND(4, a, b, c, d)
|
||||
ROUND(5, b, c, d, a)
|
||||
ROUND(6, c, d, a, b)
|
||||
ROUND(7, d, a, b, c)
|
||||
ROUND(8, a, b, c, d)
|
||||
ROUND(9, b, c, d, a)
|
||||
ROUND(10, c, d, a, b)
|
||||
ROUND(11, d, a, b, c)
|
||||
ROUND(12, a, b, c, d)
|
||||
ROUND(13, b, c, d, a)
|
||||
ROUND(14, c, d, a, b)
|
||||
ROUND(15, d, a, b, c)
|
||||
|
||||
h0 = _mm_add_epi32(h0, w0);
|
||||
h1 = _mm_add_epi32(h1, w1);
|
||||
}
|
||||
|
||||
// H01234567 -> H01256 and H2367
|
||||
th = _mm_shuffle_epi32(h0, 0x1b);
|
||||
h1 = _mm_shuffle_epi32(h1, 0xb1);
|
||||
h0 = _mm_blend_epi16(th, h1, 0xf0);
|
||||
h1 = _mm_alignr_epi8(h1, th, 8);
|
||||
|
||||
_mm_storeu_si128((__m128i *)ctx->h, h0);
|
||||
_mm_storeu_si128((__m128i *)(ctx->h + 4), h1);
|
||||
|
||||
/* if data left over, fill it into buffer */
|
||||
if (inputLen) {
|
||||
memcpy(ctx->u.b, input, inputLen);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* USE_HW_SHA2 */
|
||||
|
|
@ -7,6 +7,12 @@
|
|||
|
||||
#include "prtypes.h"
|
||||
|
||||
struct SHA256ContextStr;
|
||||
|
||||
typedef void (*sha256_compress_t)(struct SHA256ContextStr *);
|
||||
typedef void (*sha256_update_t)(struct SHA256ContextStr *, const unsigned char *,
|
||||
unsigned int);
|
||||
|
||||
struct SHA256ContextStr {
|
||||
union {
|
||||
PRUint32 w[64]; /* message schedule, input buffer, plus 48 words */
|
||||
|
|
@ -14,6 +20,8 @@ struct SHA256ContextStr {
|
|||
} u;
|
||||
PRUint32 h[8]; /* 8 state variables */
|
||||
PRUint32 sizeHi, sizeLo; /* 64-bit count of hashed bytes. */
|
||||
sha256_compress_t compress;
|
||||
sha256_update_t update;
|
||||
};
|
||||
|
||||
#endif /* _SHA_256_H_ */
|
||||
|
|
|
|||
851
security/nss/lib/freebl/sha512-p8.s
Normal file
851
security/nss/lib/freebl/sha512-p8.s
Normal file
|
|
@ -0,0 +1,851 @@
|
|||
# Copyright (c) 2006, CRYPTOGAMS by <appro@openssl.org>
|
||||
# All rights reserved.
|
||||
# See the full LICENSE under scripts/.
|
||||
|
||||
.machine "any"
|
||||
.abiversion 2
|
||||
.text
|
||||
|
||||
.globl sha512_block_p8
|
||||
.type sha512_block_p8,@function
|
||||
.align 6
|
||||
sha512_block_p8:
|
||||
.localentry sha512_block_p8,0
|
||||
|
||||
stdu 1,-384(1)
|
||||
mflr 8
|
||||
li 10,207
|
||||
li 11,223
|
||||
stvx 24,10,1
|
||||
addi 10,10,32
|
||||
li 12,-1
|
||||
stvx 25,11,1
|
||||
addi 11,11,32
|
||||
stvx 26,10,1
|
||||
addi 10,10,32
|
||||
stvx 27,11,1
|
||||
addi 11,11,32
|
||||
stvx 28,10,1
|
||||
addi 10,10,32
|
||||
stvx 29,11,1
|
||||
addi 11,11,32
|
||||
stvx 30,10,1
|
||||
stvx 31,11,1
|
||||
li 11,-4096+255
|
||||
stw 12,332(1)
|
||||
li 10,0x10
|
||||
std 26,336(1)
|
||||
li 26,0x20
|
||||
std 27,344(1)
|
||||
li 27,0x30
|
||||
std 28,352(1)
|
||||
li 28,0x40
|
||||
std 29,360(1)
|
||||
li 29,0x50
|
||||
std 30,368(1)
|
||||
li 30,0x60
|
||||
std 31,376(1)
|
||||
li 31,0x70
|
||||
std 8,400(1)
|
||||
or 11,11,11
|
||||
|
||||
bl .LPICmeup
|
||||
addi 11,1,79
|
||||
li 7,8
|
||||
lvsl 31,0,7
|
||||
vspltisb 28,0x0f
|
||||
vxor 31,31,28
|
||||
.long 0x7C001E99
|
||||
.long 0x7C4A1E99
|
||||
.long 0x7C9A1E99
|
||||
vsldoi 1,0,0,8
|
||||
.long 0x7CDB1E99
|
||||
vsldoi 3,2,2,8
|
||||
vsldoi 5,4,4,8
|
||||
vsldoi 7,6,6,8
|
||||
li 0,4
|
||||
b .Loop
|
||||
.align 5
|
||||
.Loop:
|
||||
lvx 28,0,6
|
||||
.long 0x7D002699
|
||||
addi 4,4,16
|
||||
mr 7,6
|
||||
stvx 0,0,11
|
||||
stvx 1,10,11
|
||||
stvx 2,26,11
|
||||
stvx 3,27,11
|
||||
stvx 4,28,11
|
||||
stvx 5,29,11
|
||||
stvx 6,30,11
|
||||
stvx 7,31,11
|
||||
.long 0x10E7E0C0
|
||||
lvx 28,10,6
|
||||
vperm 8,8,8,31
|
||||
.long 0x10E740C0
|
||||
vsel 29,6,5,4
|
||||
.long 0x10C6E0C0
|
||||
.long 0x10E7E8C0
|
||||
.long 0x13C4FEC2
|
||||
.long 0x10E7F0C0
|
||||
vxor 29,0,1
|
||||
vsel 29,1,2,29
|
||||
.long 0x106338C0
|
||||
.long 0x13C086C2
|
||||
.long 0x13DEE8C0
|
||||
.long 0x10E7F0C0
|
||||
lvx 28,26,7
|
||||
.long 0x7D402699
|
||||
addi 4,4,16
|
||||
vsldoi 9,8,8,8
|
||||
.long 0x10C648C0
|
||||
vsel 29,5,4,3
|
||||
.long 0x10A5E0C0
|
||||
.long 0x10C6E8C0
|
||||
.long 0x13C3FEC2
|
||||
.long 0x10C6F0C0
|
||||
vxor 29,7,0
|
||||
vsel 29,0,1,29
|
||||
.long 0x104230C0
|
||||
.long 0x13C786C2
|
||||
.long 0x13DEE8C0
|
||||
.long 0x10C6F0C0
|
||||
lvx 28,27,7
|
||||
vperm 10,10,10,31
|
||||
.long 0x10A550C0
|
||||
vsel 29,4,3,2
|
||||
.long 0x1084E0C0
|
||||
.long 0x10A5E8C0
|
||||
.long 0x13C2FEC2
|
||||
.long 0x10A5F0C0
|
||||
vxor 29,6,7
|
||||
vsel 29,7,0,29
|
||||
.long 0x102128C0
|
||||
.long 0x13C686C2
|
||||
.long 0x13DEE8C0
|
||||
.long 0x10A5F0C0
|
||||
lvx 28,28,7
|
||||
.long 0x7D802699
|
||||
addi 4,4,16
|
||||
vsldoi 11,10,10,8
|
||||
.long 0x108458C0
|
||||
vsel 29,3,2,1
|
||||
.long 0x1063E0C0
|
||||
.long 0x1084E8C0
|
||||
.long 0x13C1FEC2
|
||||
.long 0x1084F0C0
|
||||
vxor 29,5,6
|
||||
vsel 29,6,7,29
|
||||
.long 0x100020C0
|
||||
.long 0x13C586C2
|
||||
.long 0x13DEE8C0
|
||||
.long 0x1084F0C0
|
||||
lvx 28,29,7
|
||||
vperm 12,12,12,31
|
||||
.long 0x106360C0
|
||||
vsel 29,2,1,0
|
||||
.long 0x1042E0C0
|
||||
.long 0x1063E8C0
|
||||
.long 0x13C0FEC2
|
||||
.long 0x1063F0C0
|
||||
vxor 29,4,5
|
||||
vsel 29,5,6,29
|
||||
.long 0x10E718C0
|
||||
.long 0x13C486C2
|
||||
.long 0x13DEE8C0
|
||||
.long 0x1063F0C0
|
||||
lvx 28,30,7
|
||||
.long 0x7DC02699
|
||||
addi 4,4,16
|
||||
vsldoi 13,12,12,8
|
||||
.long 0x104268C0
|
||||
vsel 29,1,0,7
|
||||
.long 0x1021E0C0
|
||||
.long 0x1042E8C0
|
||||
.long 0x13C7FEC2
|
||||
.long 0x1042F0C0
|
||||
vxor 29,3,4
|
||||
vsel 29,4,5,29
|
||||
.long 0x10C610C0
|
||||
.long 0x13C386C2
|
||||
.long 0x13DEE8C0
|
||||
.long 0x1042F0C0
|
||||
lvx 28,31,7
|
||||
addi 7,7,0x80
|
||||
vperm 14,14,14,31
|
||||
.long 0x102170C0
|
||||
vsel 29,0,7,6
|
||||
.long 0x1000E0C0
|
||||
.long 0x1021E8C0
|
||||
.long 0x13C6FEC2
|
||||
.long 0x1021F0C0
|
||||
vxor 29,2,3
|
||||
vsel 29,3,4,29
|
||||
.long 0x10A508C0
|
||||
.long 0x13C286C2
|
||||
.long 0x13DEE8C0
|
||||
.long 0x1021F0C0
|
||||
lvx 28,0,7
|
||||
.long 0x7E002699
|
||||
addi 4,4,16
|
||||
vsldoi 15,14,14,8
|
||||
.long 0x100078C0
|
||||
vsel 29,7,6,5
|
||||
.long 0x10E7E0C0
|
||||
.long 0x1000E8C0
|
||||
.long 0x13C5FEC2
|
||||
.long 0x1000F0C0
|
||||
vxor 29,1,2
|
||||
vsel 29,2,3,29
|
||||
.long 0x108400C0
|
||||
.long 0x13C186C2
|
||||
.long 0x13DEE8C0
|
||||
.long 0x1000F0C0
|
||||
lvx 28,10,7
|
||||
vperm 16,16,16,31
|
||||
.long 0x10E780C0
|
||||
vsel 29,6,5,4
|
||||
.long 0x10C6E0C0
|
||||
.long 0x10E7E8C0
|
||||
.long 0x13C4FEC2
|
||||
.long 0x10E7F0C0
|
||||
vxor 29,0,1
|
||||
vsel 29,1,2,29
|
||||
.long 0x106338C0
|
||||
.long 0x13C086C2
|
||||
.long 0x13DEE8C0
|
||||
.long 0x10E7F0C0
|
||||
lvx 28,26,7
|
||||
.long 0x7E402699
|
||||
addi 4,4,16
|
||||
vsldoi 17,16,16,8
|
||||
.long 0x10C688C0
|
||||
vsel 29,5,4,3
|
||||
.long 0x10A5E0C0
|
||||
.long 0x10C6E8C0
|
||||
.long 0x13C3FEC2
|
||||
.long 0x10C6F0C0
|
||||
vxor 29,7,0
|
||||
vsel 29,0,1,29
|
||||
.long 0x104230C0
|
||||
.long 0x13C786C2
|
||||
.long 0x13DEE8C0
|
||||
.long 0x10C6F0C0
|
||||
lvx 28,27,7
|
||||
vperm 18,18,18,31
|
||||
.long 0x10A590C0
|
||||
vsel 29,4,3,2
|
||||
.long 0x1084E0C0
|
||||
.long 0x10A5E8C0
|
||||
.long 0x13C2FEC2
|
||||
.long 0x10A5F0C0
|
||||
vxor 29,6,7
|
||||
vsel 29,7,0,29
|
||||
.long 0x102128C0
|
||||
.long 0x13C686C2
|
||||
.long 0x13DEE8C0
|
||||
.long 0x10A5F0C0
|
||||
lvx 28,28,7
|
||||
.long 0x7F002699
|
||||
addi 4,4,16
|
||||
vsldoi 19,18,18,8
|
||||
.long 0x108498C0
|
||||
vsel 29,3,2,1
|
||||
.long 0x1063E0C0
|
||||
.long 0x1084E8C0
|
||||
.long 0x13C1FEC2
|
||||
.long 0x1084F0C0
|
||||
vxor 29,5,6
|
||||
vsel 29,6,7,29
|
||||
.long 0x100020C0
|
||||
.long 0x13C586C2
|
||||
.long 0x13DEE8C0
|
||||
.long 0x1084F0C0
|
||||
lvx 28,29,7
|
||||
vperm 24,24,24,31
|
||||
.long 0x1063C0C0
|
||||
vsel 29,2,1,0
|
||||
.long 0x1042E0C0
|
||||
.long 0x1063E8C0
|
||||
.long 0x13C0FEC2
|
||||
.long 0x1063F0C0
|
||||
vxor 29,4,5
|
||||
vsel 29,5,6,29
|
||||
.long 0x10E718C0
|
||||
.long 0x13C486C2
|
||||
.long 0x13DEE8C0
|
||||
.long 0x1063F0C0
|
||||
lvx 28,30,7
|
||||
.long 0x7F402699
|
||||
addi 4,4,16
|
||||
vsldoi 25,24,24,8
|
||||
.long 0x1042C8C0
|
||||
vsel 29,1,0,7
|
||||
.long 0x1021E0C0
|
||||
.long 0x1042E8C0
|
||||
.long 0x13C7FEC2
|
||||
.long 0x1042F0C0
|
||||
vxor 29,3,4
|
||||
vsel 29,4,5,29
|
||||
.long 0x10C610C0
|
||||
.long 0x13C386C2
|
||||
.long 0x13DEE8C0
|
||||
.long 0x1042F0C0
|
||||
lvx 28,31,7
|
||||
addi 7,7,0x80
|
||||
vperm 26,26,26,31
|
||||
.long 0x1021D0C0
|
||||
vsel 29,0,7,6
|
||||
.long 0x1000E0C0
|
||||
.long 0x1021E8C0
|
||||
.long 0x13C6FEC2
|
||||
.long 0x1021F0C0
|
||||
vxor 29,2,3
|
||||
vsel 29,3,4,29
|
||||
.long 0x10A508C0
|
||||
.long 0x13C286C2
|
||||
.long 0x13DEE8C0
|
||||
.long 0x1021F0C0
|
||||
lvx 28,0,7
|
||||
vsldoi 27,26,26,8
|
||||
.long 0x13C906C2
|
||||
.long 0x1108F0C0
|
||||
.long 0x13DA7EC2
|
||||
.long 0x1108F0C0
|
||||
.long 0x110888C0
|
||||
.long 0x1000D8C0
|
||||
vsel 29,7,6,5
|
||||
.long 0x10E7E0C0
|
||||
.long 0x1000E8C0
|
||||
.long 0x13C5FEC2
|
||||
.long 0x1000F0C0
|
||||
vxor 29,1,2
|
||||
vsel 29,2,3,29
|
||||
.long 0x108400C0
|
||||
.long 0x13C186C2
|
||||
.long 0x13DEE8C0
|
||||
.long 0x1000F0C0
|
||||
lvx 28,10,7
|
||||
mtctr 0
|
||||
b .L16_xx
|
||||
.align 5
|
||||
.L16_xx:
|
||||
.long 0x13CA06C2
|
||||
.long 0x1129F0C0
|
||||
.long 0x13DB7EC2
|
||||
.long 0x1129F0C0
|
||||
.long 0x112990C0
|
||||
.long 0x10E740C0
|
||||
vsel 29,6,5,4
|
||||
.long 0x10C6E0C0
|
||||
.long 0x10E7E8C0
|
||||
.long 0x13C4FEC2
|
||||
.long 0x10E7F0C0
|
||||
vxor 29,0,1
|
||||
vsel 29,1,2,29
|
||||
.long 0x106338C0
|
||||
.long 0x13C086C2
|
||||
.long 0x13DEE8C0
|
||||
.long 0x10E7F0C0
|
||||
lvx 28,26,7
|
||||
.long 0x13CB06C2
|
||||
.long 0x114AF0C0
|
||||
.long 0x13C87EC2
|
||||
.long 0x114AF0C0
|
||||
.long 0x114A98C0
|
||||
.long 0x10C648C0
|
||||
vsel 29,5,4,3
|
||||
.long 0x10A5E0C0
|
||||
.long 0x10C6E8C0
|
||||
.long 0x13C3FEC2
|
||||
.long 0x10C6F0C0
|
||||
vxor 29,7,0
|
||||
vsel 29,0,1,29
|
||||
.long 0x104230C0
|
||||
.long 0x13C786C2
|
||||
.long 0x13DEE8C0
|
||||
.long 0x10C6F0C0
|
||||
lvx 28,27,7
|
||||
.long 0x13CC06C2
|
||||
.long 0x116BF0C0
|
||||
.long 0x13C97EC2
|
||||
.long 0x116BF0C0
|
||||
.long 0x116BC0C0
|
||||
.long 0x10A550C0
|
||||
vsel 29,4,3,2
|
||||
.long 0x1084E0C0
|
||||
.long 0x10A5E8C0
|
||||
.long 0x13C2FEC2
|
||||
.long 0x10A5F0C0
|
||||
vxor 29,6,7
|
||||
vsel 29,7,0,29
|
||||
.long 0x102128C0
|
||||
.long 0x13C686C2
|
||||
.long 0x13DEE8C0
|
||||
.long 0x10A5F0C0
|
||||
lvx 28,28,7
|
||||
.long 0x13CD06C2
|
||||
.long 0x118CF0C0
|
||||
.long 0x13CA7EC2
|
||||
.long 0x118CF0C0
|
||||
.long 0x118CC8C0
|
||||
.long 0x108458C0
|
||||
vsel 29,3,2,1
|
||||
.long 0x1063E0C0
|
||||
.long 0x1084E8C0
|
||||
.long 0x13C1FEC2
|
||||
.long 0x1084F0C0
|
||||
vxor 29,5,6
|
||||
vsel 29,6,7,29
|
||||
.long 0x100020C0
|
||||
.long 0x13C586C2
|
||||
.long 0x13DEE8C0
|
||||
.long 0x1084F0C0
|
||||
lvx 28,29,7
|
||||
.long 0x13CE06C2
|
||||
.long 0x11ADF0C0
|
||||
.long 0x13CB7EC2
|
||||
.long 0x11ADF0C0
|
||||
.long 0x11ADD0C0
|
||||
.long 0x106360C0
|
||||
vsel 29,2,1,0
|
||||
.long 0x1042E0C0
|
||||
.long 0x1063E8C0
|
||||
.long 0x13C0FEC2
|
||||
.long 0x1063F0C0
|
||||
vxor 29,4,5
|
||||
vsel 29,5,6,29
|
||||
.long 0x10E718C0
|
||||
.long 0x13C486C2
|
||||
.long 0x13DEE8C0
|
||||
.long 0x1063F0C0
|
||||
lvx 28,30,7
|
||||
.long 0x13CF06C2
|
||||
.long 0x11CEF0C0
|
||||
.long 0x13CC7EC2
|
||||
.long 0x11CEF0C0
|
||||
.long 0x11CED8C0
|
||||
.long 0x104268C0
|
||||
vsel 29,1,0,7
|
||||
.long 0x1021E0C0
|
||||
.long 0x1042E8C0
|
||||
.long 0x13C7FEC2
|
||||
.long 0x1042F0C0
|
||||
vxor 29,3,4
|
||||
vsel 29,4,5,29
|
||||
.long 0x10C610C0
|
||||
.long 0x13C386C2
|
||||
.long 0x13DEE8C0
|
||||
.long 0x1042F0C0
|
||||
lvx 28,31,7
|
||||
addi 7,7,0x80
|
||||
.long 0x13D006C2
|
||||
.long 0x11EFF0C0
|
||||
.long 0x13CD7EC2
|
||||
.long 0x11EFF0C0
|
||||
.long 0x11EF40C0
|
||||
.long 0x102170C0
|
||||
vsel 29,0,7,6
|
||||
.long 0x1000E0C0
|
||||
.long 0x1021E8C0
|
||||
.long 0x13C6FEC2
|
||||
.long 0x1021F0C0
|
||||
vxor 29,2,3
|
||||
vsel 29,3,4,29
|
||||
.long 0x10A508C0
|
||||
.long 0x13C286C2
|
||||
.long 0x13DEE8C0
|
||||
.long 0x1021F0C0
|
||||
lvx 28,0,7
|
||||
.long 0x13D106C2
|
||||
.long 0x1210F0C0
|
||||
.long 0x13CE7EC2
|
||||
.long 0x1210F0C0
|
||||
.long 0x121048C0
|
||||
.long 0x100078C0
|
||||
vsel 29,7,6,5
|
||||
.long 0x10E7E0C0
|
||||
.long 0x1000E8C0
|
||||
.long 0x13C5FEC2
|
||||
.long 0x1000F0C0
|
||||
vxor 29,1,2
|
||||
vsel 29,2,3,29
|
||||
.long 0x108400C0
|
||||
.long 0x13C186C2
|
||||
.long 0x13DEE8C0
|
||||
.long 0x1000F0C0
|
||||
lvx 28,10,7
|
||||
.long 0x13D206C2
|
||||
.long 0x1231F0C0
|
||||
.long 0x13CF7EC2
|
||||
.long 0x1231F0C0
|
||||
.long 0x123150C0
|
||||
.long 0x10E780C0
|
||||
vsel 29,6,5,4
|
||||
.long 0x10C6E0C0
|
||||
.long 0x10E7E8C0
|
||||
.long 0x13C4FEC2
|
||||
.long 0x10E7F0C0
|
||||
vxor 29,0,1
|
||||
vsel 29,1,2,29
|
||||
.long 0x106338C0
|
||||
.long 0x13C086C2
|
||||
.long 0x13DEE8C0
|
||||
.long 0x10E7F0C0
|
||||
lvx 28,26,7
|
||||
.long 0x13D306C2
|
||||
.long 0x1252F0C0
|
||||
.long 0x13D07EC2
|
||||
.long 0x1252F0C0
|
||||
.long 0x125258C0
|
||||
.long 0x10C688C0
|
||||
vsel 29,5,4,3
|
||||
.long 0x10A5E0C0
|
||||
.long 0x10C6E8C0
|
||||
.long 0x13C3FEC2
|
||||
.long 0x10C6F0C0
|
||||
vxor 29,7,0
|
||||
vsel 29,0,1,29
|
||||
.long 0x104230C0
|
||||
.long 0x13C786C2
|
||||
.long 0x13DEE8C0
|
||||
.long 0x10C6F0C0
|
||||
lvx 28,27,7
|
||||
.long 0x13D806C2
|
||||
.long 0x1273F0C0
|
||||
.long 0x13D17EC2
|
||||
.long 0x1273F0C0
|
||||
.long 0x127360C0
|
||||
.long 0x10A590C0
|
||||
vsel 29,4,3,2
|
||||
.long 0x1084E0C0
|
||||
.long 0x10A5E8C0
|
||||
.long 0x13C2FEC2
|
||||
.long 0x10A5F0C0
|
||||
vxor 29,6,7
|
||||
vsel 29,7,0,29
|
||||
.long 0x102128C0
|
||||
.long 0x13C686C2
|
||||
.long 0x13DEE8C0
|
||||
.long 0x10A5F0C0
|
||||
lvx 28,28,7
|
||||
.long 0x13D906C2
|
||||
.long 0x1318F0C0
|
||||
.long 0x13D27EC2
|
||||
.long 0x1318F0C0
|
||||
.long 0x131868C0
|
||||
.long 0x108498C0
|
||||
vsel 29,3,2,1
|
||||
.long 0x1063E0C0
|
||||
.long 0x1084E8C0
|
||||
.long 0x13C1FEC2
|
||||
.long 0x1084F0C0
|
||||
vxor 29,5,6
|
||||
vsel 29,6,7,29
|
||||
.long 0x100020C0
|
||||
.long 0x13C586C2
|
||||
.long 0x13DEE8C0
|
||||
.long 0x1084F0C0
|
||||
lvx 28,29,7
|
||||
.long 0x13DA06C2
|
||||
.long 0x1339F0C0
|
||||
.long 0x13D37EC2
|
||||
.long 0x1339F0C0
|
||||
.long 0x133970C0
|
||||
.long 0x1063C0C0
|
||||
vsel 29,2,1,0
|
||||
.long 0x1042E0C0
|
||||
.long 0x1063E8C0
|
||||
.long 0x13C0FEC2
|
||||
.long 0x1063F0C0
|
||||
vxor 29,4,5
|
||||
vsel 29,5,6,29
|
||||
.long 0x10E718C0
|
||||
.long 0x13C486C2
|
||||
.long 0x13DEE8C0
|
||||
.long 0x1063F0C0
|
||||
lvx 28,30,7
|
||||
.long 0x13DB06C2
|
||||
.long 0x135AF0C0
|
||||
.long 0x13D87EC2
|
||||
.long 0x135AF0C0
|
||||
.long 0x135A78C0
|
||||
.long 0x1042C8C0
|
||||
vsel 29,1,0,7
|
||||
.long 0x1021E0C0
|
||||
.long 0x1042E8C0
|
||||
.long 0x13C7FEC2
|
||||
.long 0x1042F0C0
|
||||
vxor 29,3,4
|
||||
vsel 29,4,5,29
|
||||
.long 0x10C610C0
|
||||
.long 0x13C386C2
|
||||
.long 0x13DEE8C0
|
||||
.long 0x1042F0C0
|
||||
lvx 28,31,7
|
||||
addi 7,7,0x80
|
||||
.long 0x13C806C2
|
||||
.long 0x137BF0C0
|
||||
.long 0x13D97EC2
|
||||
.long 0x137BF0C0
|
||||
.long 0x137B80C0
|
||||
.long 0x1021D0C0
|
||||
vsel 29,0,7,6
|
||||
.long 0x1000E0C0
|
||||
.long 0x1021E8C0
|
||||
.long 0x13C6FEC2
|
||||
.long 0x1021F0C0
|
||||
vxor 29,2,3
|
||||
vsel 29,3,4,29
|
||||
.long 0x10A508C0
|
||||
.long 0x13C286C2
|
||||
.long 0x13DEE8C0
|
||||
.long 0x1021F0C0
|
||||
lvx 28,0,7
|
||||
.long 0x13C906C2
|
||||
.long 0x1108F0C0
|
||||
.long 0x13DA7EC2
|
||||
.long 0x1108F0C0
|
||||
.long 0x110888C0
|
||||
.long 0x1000D8C0
|
||||
vsel 29,7,6,5
|
||||
.long 0x10E7E0C0
|
||||
.long 0x1000E8C0
|
||||
.long 0x13C5FEC2
|
||||
.long 0x1000F0C0
|
||||
vxor 29,1,2
|
||||
vsel 29,2,3,29
|
||||
.long 0x108400C0
|
||||
.long 0x13C186C2
|
||||
.long 0x13DEE8C0
|
||||
.long 0x1000F0C0
|
||||
lvx 28,10,7
|
||||
bdnz .L16_xx
|
||||
|
||||
lvx 10,0,11
|
||||
subic. 5,5,1
|
||||
lvx 11,10,11
|
||||
.long 0x100050C0
|
||||
lvx 12,26,11
|
||||
.long 0x102158C0
|
||||
lvx 13,27,11
|
||||
.long 0x104260C0
|
||||
lvx 14,28,11
|
||||
.long 0x106368C0
|
||||
lvx 15,29,11
|
||||
.long 0x108470C0
|
||||
lvx 16,30,11
|
||||
.long 0x10A578C0
|
||||
lvx 17,31,11
|
||||
.long 0x10C680C0
|
||||
.long 0x10E788C0
|
||||
bne .Loop
|
||||
vperm 0,0,1,28
|
||||
vperm 2,2,3,28
|
||||
vperm 4,4,5,28
|
||||
vperm 6,6,7,28
|
||||
.long 0x7C001F99
|
||||
.long 0x7C4A1F99
|
||||
.long 0x7C9A1F99
|
||||
.long 0x7CDB1F99
|
||||
addi 11,1,207
|
||||
mtlr 8
|
||||
or 12,12,12
|
||||
lvx 24,0,11
|
||||
lvx 25,10,11
|
||||
lvx 26,26,11
|
||||
lvx 27,27,11
|
||||
lvx 28,28,11
|
||||
lvx 29,29,11
|
||||
lvx 30,30,11
|
||||
lvx 31,31,11
|
||||
ld 26,336(1)
|
||||
ld 27,344(1)
|
||||
ld 28,352(1)
|
||||
ld 29,360(1)
|
||||
ld 30,368(1)
|
||||
ld 31,376(1)
|
||||
addi 1,1,384
|
||||
blr
|
||||
.long 0
|
||||
.byte 0,12,4,1,0x80,6,3,0
|
||||
.long 0
|
||||
.size sha512_block_p8,.-sha512_block_p8
|
||||
.align 6
|
||||
.LPICmeup:
|
||||
mflr 0
|
||||
bcl 20,31,$+4
|
||||
mflr 6
|
||||
addi 6,6,56
|
||||
mtlr 0
|
||||
blr
|
||||
.long 0
|
||||
.byte 0,12,0x14,0,0,0,0,0
|
||||
.space 28
|
||||
.long 0xd728ae22,0x428a2f98
|
||||
.long 0xd728ae22,0x428a2f98
|
||||
.long 0x23ef65cd,0x71374491
|
||||
.long 0x23ef65cd,0x71374491
|
||||
.long 0xec4d3b2f,0xb5c0fbcf
|
||||
.long 0xec4d3b2f,0xb5c0fbcf
|
||||
.long 0x8189dbbc,0xe9b5dba5
|
||||
.long 0x8189dbbc,0xe9b5dba5
|
||||
.long 0xf348b538,0x3956c25b
|
||||
.long 0xf348b538,0x3956c25b
|
||||
.long 0xb605d019,0x59f111f1
|
||||
.long 0xb605d019,0x59f111f1
|
||||
.long 0xaf194f9b,0x923f82a4
|
||||
.long 0xaf194f9b,0x923f82a4
|
||||
.long 0xda6d8118,0xab1c5ed5
|
||||
.long 0xda6d8118,0xab1c5ed5
|
||||
.long 0xa3030242,0xd807aa98
|
||||
.long 0xa3030242,0xd807aa98
|
||||
.long 0x45706fbe,0x12835b01
|
||||
.long 0x45706fbe,0x12835b01
|
||||
.long 0x4ee4b28c,0x243185be
|
||||
.long 0x4ee4b28c,0x243185be
|
||||
.long 0xd5ffb4e2,0x550c7dc3
|
||||
.long 0xd5ffb4e2,0x550c7dc3
|
||||
.long 0xf27b896f,0x72be5d74
|
||||
.long 0xf27b896f,0x72be5d74
|
||||
.long 0x3b1696b1,0x80deb1fe
|
||||
.long 0x3b1696b1,0x80deb1fe
|
||||
.long 0x25c71235,0x9bdc06a7
|
||||
.long 0x25c71235,0x9bdc06a7
|
||||
.long 0xcf692694,0xc19bf174
|
||||
.long 0xcf692694,0xc19bf174
|
||||
.long 0x9ef14ad2,0xe49b69c1
|
||||
.long 0x9ef14ad2,0xe49b69c1
|
||||
.long 0x384f25e3,0xefbe4786
|
||||
.long 0x384f25e3,0xefbe4786
|
||||
.long 0x8b8cd5b5,0x0fc19dc6
|
||||
.long 0x8b8cd5b5,0x0fc19dc6
|
||||
.long 0x77ac9c65,0x240ca1cc
|
||||
.long 0x77ac9c65,0x240ca1cc
|
||||
.long 0x592b0275,0x2de92c6f
|
||||
.long 0x592b0275,0x2de92c6f
|
||||
.long 0x6ea6e483,0x4a7484aa
|
||||
.long 0x6ea6e483,0x4a7484aa
|
||||
.long 0xbd41fbd4,0x5cb0a9dc
|
||||
.long 0xbd41fbd4,0x5cb0a9dc
|
||||
.long 0x831153b5,0x76f988da
|
||||
.long 0x831153b5,0x76f988da
|
||||
.long 0xee66dfab,0x983e5152
|
||||
.long 0xee66dfab,0x983e5152
|
||||
.long 0x2db43210,0xa831c66d
|
||||
.long 0x2db43210,0xa831c66d
|
||||
.long 0x98fb213f,0xb00327c8
|
||||
.long 0x98fb213f,0xb00327c8
|
||||
.long 0xbeef0ee4,0xbf597fc7
|
||||
.long 0xbeef0ee4,0xbf597fc7
|
||||
.long 0x3da88fc2,0xc6e00bf3
|
||||
.long 0x3da88fc2,0xc6e00bf3
|
||||
.long 0x930aa725,0xd5a79147
|
||||
.long 0x930aa725,0xd5a79147
|
||||
.long 0xe003826f,0x06ca6351
|
||||
.long 0xe003826f,0x06ca6351
|
||||
.long 0x0a0e6e70,0x14292967
|
||||
.long 0x0a0e6e70,0x14292967
|
||||
.long 0x46d22ffc,0x27b70a85
|
||||
.long 0x46d22ffc,0x27b70a85
|
||||
.long 0x5c26c926,0x2e1b2138
|
||||
.long 0x5c26c926,0x2e1b2138
|
||||
.long 0x5ac42aed,0x4d2c6dfc
|
||||
.long 0x5ac42aed,0x4d2c6dfc
|
||||
.long 0x9d95b3df,0x53380d13
|
||||
.long 0x9d95b3df,0x53380d13
|
||||
.long 0x8baf63de,0x650a7354
|
||||
.long 0x8baf63de,0x650a7354
|
||||
.long 0x3c77b2a8,0x766a0abb
|
||||
.long 0x3c77b2a8,0x766a0abb
|
||||
.long 0x47edaee6,0x81c2c92e
|
||||
.long 0x47edaee6,0x81c2c92e
|
||||
.long 0x1482353b,0x92722c85
|
||||
.long 0x1482353b,0x92722c85
|
||||
.long 0x4cf10364,0xa2bfe8a1
|
||||
.long 0x4cf10364,0xa2bfe8a1
|
||||
.long 0xbc423001,0xa81a664b
|
||||
.long 0xbc423001,0xa81a664b
|
||||
.long 0xd0f89791,0xc24b8b70
|
||||
.long 0xd0f89791,0xc24b8b70
|
||||
.long 0x0654be30,0xc76c51a3
|
||||
.long 0x0654be30,0xc76c51a3
|
||||
.long 0xd6ef5218,0xd192e819
|
||||
.long 0xd6ef5218,0xd192e819
|
||||
.long 0x5565a910,0xd6990624
|
||||
.long 0x5565a910,0xd6990624
|
||||
.long 0x5771202a,0xf40e3585
|
||||
.long 0x5771202a,0xf40e3585
|
||||
.long 0x32bbd1b8,0x106aa070
|
||||
.long 0x32bbd1b8,0x106aa070
|
||||
.long 0xb8d2d0c8,0x19a4c116
|
||||
.long 0xb8d2d0c8,0x19a4c116
|
||||
.long 0x5141ab53,0x1e376c08
|
||||
.long 0x5141ab53,0x1e376c08
|
||||
.long 0xdf8eeb99,0x2748774c
|
||||
.long 0xdf8eeb99,0x2748774c
|
||||
.long 0xe19b48a8,0x34b0bcb5
|
||||
.long 0xe19b48a8,0x34b0bcb5
|
||||
.long 0xc5c95a63,0x391c0cb3
|
||||
.long 0xc5c95a63,0x391c0cb3
|
||||
.long 0xe3418acb,0x4ed8aa4a
|
||||
.long 0xe3418acb,0x4ed8aa4a
|
||||
.long 0x7763e373,0x5b9cca4f
|
||||
.long 0x7763e373,0x5b9cca4f
|
||||
.long 0xd6b2b8a3,0x682e6ff3
|
||||
.long 0xd6b2b8a3,0x682e6ff3
|
||||
.long 0x5defb2fc,0x748f82ee
|
||||
.long 0x5defb2fc,0x748f82ee
|
||||
.long 0x43172f60,0x78a5636f
|
||||
.long 0x43172f60,0x78a5636f
|
||||
.long 0xa1f0ab72,0x84c87814
|
||||
.long 0xa1f0ab72,0x84c87814
|
||||
.long 0x1a6439ec,0x8cc70208
|
||||
.long 0x1a6439ec,0x8cc70208
|
||||
.long 0x23631e28,0x90befffa
|
||||
.long 0x23631e28,0x90befffa
|
||||
.long 0xde82bde9,0xa4506ceb
|
||||
.long 0xde82bde9,0xa4506ceb
|
||||
.long 0xb2c67915,0xbef9a3f7
|
||||
.long 0xb2c67915,0xbef9a3f7
|
||||
.long 0xe372532b,0xc67178f2
|
||||
.long 0xe372532b,0xc67178f2
|
||||
.long 0xea26619c,0xca273ece
|
||||
.long 0xea26619c,0xca273ece
|
||||
.long 0x21c0c207,0xd186b8c7
|
||||
.long 0x21c0c207,0xd186b8c7
|
||||
.long 0xcde0eb1e,0xeada7dd6
|
||||
.long 0xcde0eb1e,0xeada7dd6
|
||||
.long 0xee6ed178,0xf57d4f7f
|
||||
.long 0xee6ed178,0xf57d4f7f
|
||||
.long 0x72176fba,0x06f067aa
|
||||
.long 0x72176fba,0x06f067aa
|
||||
.long 0xa2c898a6,0x0a637dc5
|
||||
.long 0xa2c898a6,0x0a637dc5
|
||||
.long 0xbef90dae,0x113f9804
|
||||
.long 0xbef90dae,0x113f9804
|
||||
.long 0x131c471b,0x1b710b35
|
||||
.long 0x131c471b,0x1b710b35
|
||||
.long 0x23047d84,0x28db77f5
|
||||
.long 0x23047d84,0x28db77f5
|
||||
.long 0x40c72493,0x32caab7b
|
||||
.long 0x40c72493,0x32caab7b
|
||||
.long 0x15c9bebc,0x3c9ebe0a
|
||||
.long 0x15c9bebc,0x3c9ebe0a
|
||||
.long 0x9c100d4c,0x431d67c4
|
||||
.long 0x9c100d4c,0x431d67c4
|
||||
.long 0xcb3e42b6,0x4cc5d4be
|
||||
.long 0xcb3e42b6,0x4cc5d4be
|
||||
.long 0xfc657e2a,0x597f299c
|
||||
.long 0xfc657e2a,0x597f299c
|
||||
.long 0x3ad6faec,0x5fcb6fab
|
||||
.long 0x3ad6faec,0x5fcb6fab
|
||||
.long 0x4a475817,0x6c44198c
|
||||
.long 0x4a475817,0x6c44198c
|
||||
.long 0,0
|
||||
.long 0,0
|
||||
.long 0x14151617,0x10111213
|
||||
.long 0x04050607,0x00010203
|
||||
.byte 83,72,65,53,49,50,32,102,111,114,32,80,111,119,101,114,73,83,65,32,50,46,48,55,44,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
|
||||
.align 2
|
||||
.align 2
|
||||
|
|
@ -18,8 +18,11 @@
|
|||
#include "prlong.h"
|
||||
#include "secport.h" /* for PORT_XXX */
|
||||
#include "blapi.h"
|
||||
#include "blapii.h"
|
||||
#include "secerr.h"
|
||||
#include "sha256.h" /* for struct SHA256ContextStr */
|
||||
#include "crypto_primitives.h"
|
||||
#include "ppc-crypto.h" /* for USE_PPC_CRYPTO */
|
||||
|
||||
/* ============= Common constants and defines ======================= */
|
||||
|
||||
|
|
@ -43,7 +46,7 @@ static const PRUint8 pad[240] = {
|
|||
/* ============= SHA256 implementation ================================== */
|
||||
|
||||
/* SHA-256 constants, K256. */
|
||||
static const PRUint32 K256[64] = {
|
||||
pre_align static const PRUint32 K256[64] post_align = {
|
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
|
||||
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
||||
|
|
@ -154,6 +157,30 @@ swap4b(PRUint32 value)
|
|||
#define s0(x) (ROTR32(x, 7) ^ ROTR32(x, 18) ^ SHR(x, 3))
|
||||
#define s1(x) (ROTR32(x, 17) ^ ROTR32(x, 19) ^ SHR(x, 10))
|
||||
|
||||
void SHA256_Compress_Native(SHA256Context *ctx);
|
||||
void SHA256_Update_Native(SHA256Context *ctx, const unsigned char *input, unsigned int inputLen);
|
||||
|
||||
static void SHA256_Compress_Generic(SHA256Context *ctx);
|
||||
static void SHA256_Update_Generic(SHA256Context *ctx, const unsigned char *input,
|
||||
unsigned int inputLen);
|
||||
|
||||
#if !defined(USE_HW_SHA2)
|
||||
void
|
||||
SHA256_Compress_Native(SHA256Context *ctx)
|
||||
{
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
PORT_Assert(0);
|
||||
}
|
||||
|
||||
void
|
||||
SHA256_Update_Native(SHA256Context *ctx, const unsigned char *input,
|
||||
unsigned int inputLen)
|
||||
{
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
PORT_Assert(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
SHA256Context *
|
||||
SHA256_NewContext(void)
|
||||
{
|
||||
|
|
@ -173,13 +200,181 @@ SHA256_DestroyContext(SHA256Context *ctx, PRBool freeit)
|
|||
void
|
||||
SHA256_Begin(SHA256Context *ctx)
|
||||
{
|
||||
PRBool use_hw_sha2 = PR_FALSE;
|
||||
|
||||
memset(ctx, 0, sizeof *ctx);
|
||||
memcpy(H, H256, sizeof H256);
|
||||
|
||||
#if defined(USE_HW_SHA2) && defined(IS_LITTLE_ENDIAN)
|
||||
/* arm's implementation is tested on little endian only */
|
||||
use_hw_sha2 = arm_sha2_support() || (sha_support() && ssse3_support() && sse4_1_support());
|
||||
#endif
|
||||
|
||||
if (use_hw_sha2) {
|
||||
ctx->compress = SHA256_Compress_Native;
|
||||
ctx->update = SHA256_Update_Native;
|
||||
} else {
|
||||
ctx->compress = SHA256_Compress_Generic;
|
||||
ctx->update = SHA256_Update_Generic;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(USE_PPC_CRYPTO)
|
||||
|
||||
#define ROUND(n, a, b, c, d, e, f, g, h) \
|
||||
s0 = __builtin_crypto_vshasigmaw(e, 1, 0xf); \
|
||||
h += s0 + vec_sel(g, f, e) + w[n / 4]; \
|
||||
d += h; \
|
||||
s0 = __builtin_crypto_vshasigmaw(a, 1, 0); \
|
||||
h += s0 + vec_sel(b, c, vec_xor(a, b)); \
|
||||
if (n % 4 != 3) \
|
||||
w[n / 4] = vec_sro(w[n / 4], rshift);
|
||||
|
||||
#else
|
||||
|
||||
#define ROUND(n, a, b, c, d, e, f, g, h) \
|
||||
h += S1(e) + Ch(e, f, g) + K256[n] + W[n]; \
|
||||
d += h; \
|
||||
h += S0(a) + Maj(a, b, c);
|
||||
|
||||
#endif
|
||||
|
||||
#define SHA256_UNROLLED_ROUNDS \
|
||||
ROUND(0, a, b, c, d, e, f, g, h) \
|
||||
ROUND(1, h, a, b, c, d, e, f, g) \
|
||||
ROUND(2, g, h, a, b, c, d, e, f) \
|
||||
ROUND(3, f, g, h, a, b, c, d, e) \
|
||||
ROUND(4, e, f, g, h, a, b, c, d) \
|
||||
ROUND(5, d, e, f, g, h, a, b, c) \
|
||||
ROUND(6, c, d, e, f, g, h, a, b) \
|
||||
ROUND(7, b, c, d, e, f, g, h, a) \
|
||||
\
|
||||
ROUND(8, a, b, c, d, e, f, g, h) \
|
||||
ROUND(9, h, a, b, c, d, e, f, g) \
|
||||
ROUND(10, g, h, a, b, c, d, e, f) \
|
||||
ROUND(11, f, g, h, a, b, c, d, e) \
|
||||
ROUND(12, e, f, g, h, a, b, c, d) \
|
||||
ROUND(13, d, e, f, g, h, a, b, c) \
|
||||
ROUND(14, c, d, e, f, g, h, a, b) \
|
||||
ROUND(15, b, c, d, e, f, g, h, a) \
|
||||
\
|
||||
ROUND(16, a, b, c, d, e, f, g, h) \
|
||||
ROUND(17, h, a, b, c, d, e, f, g) \
|
||||
ROUND(18, g, h, a, b, c, d, e, f) \
|
||||
ROUND(19, f, g, h, a, b, c, d, e) \
|
||||
ROUND(20, e, f, g, h, a, b, c, d) \
|
||||
ROUND(21, d, e, f, g, h, a, b, c) \
|
||||
ROUND(22, c, d, e, f, g, h, a, b) \
|
||||
ROUND(23, b, c, d, e, f, g, h, a) \
|
||||
\
|
||||
ROUND(24, a, b, c, d, e, f, g, h) \
|
||||
ROUND(25, h, a, b, c, d, e, f, g) \
|
||||
ROUND(26, g, h, a, b, c, d, e, f) \
|
||||
ROUND(27, f, g, h, a, b, c, d, e) \
|
||||
ROUND(28, e, f, g, h, a, b, c, d) \
|
||||
ROUND(29, d, e, f, g, h, a, b, c) \
|
||||
ROUND(30, c, d, e, f, g, h, a, b) \
|
||||
ROUND(31, b, c, d, e, f, g, h, a) \
|
||||
\
|
||||
ROUND(32, a, b, c, d, e, f, g, h) \
|
||||
ROUND(33, h, a, b, c, d, e, f, g) \
|
||||
ROUND(34, g, h, a, b, c, d, e, f) \
|
||||
ROUND(35, f, g, h, a, b, c, d, e) \
|
||||
ROUND(36, e, f, g, h, a, b, c, d) \
|
||||
ROUND(37, d, e, f, g, h, a, b, c) \
|
||||
ROUND(38, c, d, e, f, g, h, a, b) \
|
||||
ROUND(39, b, c, d, e, f, g, h, a) \
|
||||
\
|
||||
ROUND(40, a, b, c, d, e, f, g, h) \
|
||||
ROUND(41, h, a, b, c, d, e, f, g) \
|
||||
ROUND(42, g, h, a, b, c, d, e, f) \
|
||||
ROUND(43, f, g, h, a, b, c, d, e) \
|
||||
ROUND(44, e, f, g, h, a, b, c, d) \
|
||||
ROUND(45, d, e, f, g, h, a, b, c) \
|
||||
ROUND(46, c, d, e, f, g, h, a, b) \
|
||||
ROUND(47, b, c, d, e, f, g, h, a) \
|
||||
\
|
||||
ROUND(48, a, b, c, d, e, f, g, h) \
|
||||
ROUND(49, h, a, b, c, d, e, f, g) \
|
||||
ROUND(50, g, h, a, b, c, d, e, f) \
|
||||
ROUND(51, f, g, h, a, b, c, d, e) \
|
||||
ROUND(52, e, f, g, h, a, b, c, d) \
|
||||
ROUND(53, d, e, f, g, h, a, b, c) \
|
||||
ROUND(54, c, d, e, f, g, h, a, b) \
|
||||
ROUND(55, b, c, d, e, f, g, h, a) \
|
||||
\
|
||||
ROUND(56, a, b, c, d, e, f, g, h) \
|
||||
ROUND(57, h, a, b, c, d, e, f, g) \
|
||||
ROUND(58, g, h, a, b, c, d, e, f) \
|
||||
ROUND(59, f, g, h, a, b, c, d, e) \
|
||||
ROUND(60, e, f, g, h, a, b, c, d) \
|
||||
ROUND(61, d, e, f, g, h, a, b, c) \
|
||||
ROUND(62, c, d, e, f, g, h, a, b) \
|
||||
ROUND(63, b, c, d, e, f, g, h, a)
|
||||
|
||||
static void
|
||||
SHA256_Compress(SHA256Context *ctx)
|
||||
SHA256_Compress_Generic(SHA256Context *ctx)
|
||||
{
|
||||
#if defined(USE_PPC_CRYPTO)
|
||||
vec_u32 w[16], s0, s1;
|
||||
const vec_u8 rshift = (vec_u8)vec_splats(4 << 3);
|
||||
const vec_u8 shifthalf = (vec_u8)vec_splats(8 << 3);
|
||||
const vec_u8 bswap4 = (vec_u8){
|
||||
3, 2, 1, 0, 7, 6, 5, 4, 11,
|
||||
10, 9, 8, 15, 14, 13, 12
|
||||
};
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
w[i] = vec_vsx_ld(0, &W[i * 4]);
|
||||
w[i] = vec_perm(w[i], w[i], bswap4);
|
||||
}
|
||||
|
||||
/* prepare the message schedule */
|
||||
for (i = 4; i < 16; i++) {
|
||||
vec_u32 off1 = vec_sld(w[i - 3], w[i - 4], 12);
|
||||
vec_u32 off2 = vec_sld(w[i - 1], w[i - 2], 12);
|
||||
s0 = __builtin_crypto_vshasigmaw(off1, 0, 0);
|
||||
/* first half, s1 depends on two prior ints */
|
||||
s1 = __builtin_crypto_vshasigmaw(w[i - 1], 0, 0xf);
|
||||
s1 = vec_sro(s1, shifthalf);
|
||||
w[i] = w[i - 4] + s0 + off2 + s1;
|
||||
|
||||
/* second half s1 */
|
||||
s1 = __builtin_crypto_vshasigmaw(w[i], 0, 0xf);
|
||||
s1 = vec_slo(s1, shifthalf);
|
||||
w[i] += s1;
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
w[i] += vec_ld(0, &K256[i * 4]);
|
||||
}
|
||||
|
||||
vec_u32 a, b, c, d, e, f, g, h;
|
||||
a = vec_splats(H[0]);
|
||||
b = vec_splats(H[1]);
|
||||
c = vec_splats(H[2]);
|
||||
d = vec_splats(H[3]);
|
||||
e = vec_splats(H[4]);
|
||||
f = vec_splats(H[5]);
|
||||
g = vec_splats(H[6]);
|
||||
h = vec_splats(H[7]);
|
||||
|
||||
SHA256_UNROLLED_ROUNDS;
|
||||
|
||||
H[0] += a[0];
|
||||
H[1] += b[0];
|
||||
H[2] += c[0];
|
||||
H[3] += d[0];
|
||||
H[4] += e[0];
|
||||
H[5] += f[0];
|
||||
H[6] += g[0];
|
||||
H[7] += h[0];
|
||||
|
||||
#undef ROUND
|
||||
|
||||
#else /* USE_PPC_CRYPTO*/
|
||||
|
||||
{
|
||||
#if defined(IS_LITTLE_ENDIAN)
|
||||
BYTESWAP4(W[0]);
|
||||
|
|
@ -280,11 +475,6 @@ SHA256_Compress(SHA256Context *ctx)
|
|||
g = H[6];
|
||||
h = H[7];
|
||||
|
||||
#define ROUND(n, a, b, c, d, e, f, g, h) \
|
||||
h += S1(e) + Ch(e, f, g) + K256[n] + W[n]; \
|
||||
d += h; \
|
||||
h += S0(a) + Maj(a, b, c);
|
||||
|
||||
#ifdef NOUNROLL256
|
||||
{
|
||||
int t;
|
||||
|
|
@ -300,77 +490,7 @@ SHA256_Compress(SHA256Context *ctx)
|
|||
}
|
||||
}
|
||||
#else
|
||||
ROUND(0, a, b, c, d, e, f, g, h)
|
||||
ROUND(1, h, a, b, c, d, e, f, g)
|
||||
ROUND(2, g, h, a, b, c, d, e, f)
|
||||
ROUND(3, f, g, h, a, b, c, d, e)
|
||||
ROUND(4, e, f, g, h, a, b, c, d)
|
||||
ROUND(5, d, e, f, g, h, a, b, c)
|
||||
ROUND(6, c, d, e, f, g, h, a, b)
|
||||
ROUND(7, b, c, d, e, f, g, h, a)
|
||||
|
||||
ROUND(8, a, b, c, d, e, f, g, h)
|
||||
ROUND(9, h, a, b, c, d, e, f, g)
|
||||
ROUND(10, g, h, a, b, c, d, e, f)
|
||||
ROUND(11, f, g, h, a, b, c, d, e)
|
||||
ROUND(12, e, f, g, h, a, b, c, d)
|
||||
ROUND(13, d, e, f, g, h, a, b, c)
|
||||
ROUND(14, c, d, e, f, g, h, a, b)
|
||||
ROUND(15, b, c, d, e, f, g, h, a)
|
||||
|
||||
ROUND(16, a, b, c, d, e, f, g, h)
|
||||
ROUND(17, h, a, b, c, d, e, f, g)
|
||||
ROUND(18, g, h, a, b, c, d, e, f)
|
||||
ROUND(19, f, g, h, a, b, c, d, e)
|
||||
ROUND(20, e, f, g, h, a, b, c, d)
|
||||
ROUND(21, d, e, f, g, h, a, b, c)
|
||||
ROUND(22, c, d, e, f, g, h, a, b)
|
||||
ROUND(23, b, c, d, e, f, g, h, a)
|
||||
|
||||
ROUND(24, a, b, c, d, e, f, g, h)
|
||||
ROUND(25, h, a, b, c, d, e, f, g)
|
||||
ROUND(26, g, h, a, b, c, d, e, f)
|
||||
ROUND(27, f, g, h, a, b, c, d, e)
|
||||
ROUND(28, e, f, g, h, a, b, c, d)
|
||||
ROUND(29, d, e, f, g, h, a, b, c)
|
||||
ROUND(30, c, d, e, f, g, h, a, b)
|
||||
ROUND(31, b, c, d, e, f, g, h, a)
|
||||
|
||||
ROUND(32, a, b, c, d, e, f, g, h)
|
||||
ROUND(33, h, a, b, c, d, e, f, g)
|
||||
ROUND(34, g, h, a, b, c, d, e, f)
|
||||
ROUND(35, f, g, h, a, b, c, d, e)
|
||||
ROUND(36, e, f, g, h, a, b, c, d)
|
||||
ROUND(37, d, e, f, g, h, a, b, c)
|
||||
ROUND(38, c, d, e, f, g, h, a, b)
|
||||
ROUND(39, b, c, d, e, f, g, h, a)
|
||||
|
||||
ROUND(40, a, b, c, d, e, f, g, h)
|
||||
ROUND(41, h, a, b, c, d, e, f, g)
|
||||
ROUND(42, g, h, a, b, c, d, e, f)
|
||||
ROUND(43, f, g, h, a, b, c, d, e)
|
||||
ROUND(44, e, f, g, h, a, b, c, d)
|
||||
ROUND(45, d, e, f, g, h, a, b, c)
|
||||
ROUND(46, c, d, e, f, g, h, a, b)
|
||||
ROUND(47, b, c, d, e, f, g, h, a)
|
||||
|
||||
ROUND(48, a, b, c, d, e, f, g, h)
|
||||
ROUND(49, h, a, b, c, d, e, f, g)
|
||||
ROUND(50, g, h, a, b, c, d, e, f)
|
||||
ROUND(51, f, g, h, a, b, c, d, e)
|
||||
ROUND(52, e, f, g, h, a, b, c, d)
|
||||
ROUND(53, d, e, f, g, h, a, b, c)
|
||||
ROUND(54, c, d, e, f, g, h, a, b)
|
||||
ROUND(55, b, c, d, e, f, g, h, a)
|
||||
|
||||
ROUND(56, a, b, c, d, e, f, g, h)
|
||||
ROUND(57, h, a, b, c, d, e, f, g)
|
||||
ROUND(58, g, h, a, b, c, d, e, f)
|
||||
ROUND(59, f, g, h, a, b, c, d, e)
|
||||
ROUND(60, e, f, g, h, a, b, c, d)
|
||||
ROUND(61, d, e, f, g, h, a, b, c)
|
||||
ROUND(62, c, d, e, f, g, h, a, b)
|
||||
ROUND(63, b, c, d, e, f, g, h, a)
|
||||
SHA256_UNROLLED_ROUNDS;
|
||||
#endif
|
||||
|
||||
H[0] += a;
|
||||
|
|
@ -383,6 +503,7 @@ SHA256_Compress(SHA256Context *ctx)
|
|||
H[7] += h;
|
||||
}
|
||||
#undef ROUND
|
||||
#endif /* !USE_PPC_CRYPTO */
|
||||
}
|
||||
|
||||
#undef s0
|
||||
|
|
@ -393,6 +514,13 @@ SHA256_Compress(SHA256Context *ctx)
|
|||
void
|
||||
SHA256_Update(SHA256Context *ctx, const unsigned char *input,
|
||||
unsigned int inputLen)
|
||||
{
|
||||
ctx->update(ctx, input, inputLen);
|
||||
}
|
||||
|
||||
static void
|
||||
SHA256_Update_Generic(SHA256Context *ctx, const unsigned char *input,
|
||||
unsigned int inputLen)
|
||||
{
|
||||
unsigned int inBuf = ctx->sizeLo & 0x3f;
|
||||
if (!inputLen)
|
||||
|
|
@ -411,7 +539,7 @@ SHA256_Update(SHA256Context *ctx, const unsigned char *input,
|
|||
input += todo;
|
||||
inputLen -= todo;
|
||||
if (inBuf + todo == SHA256_BLOCK_LENGTH)
|
||||
SHA256_Compress(ctx);
|
||||
SHA256_Compress_Generic(ctx);
|
||||
}
|
||||
|
||||
/* if enough data to fill one or more whole buffers, process them. */
|
||||
|
|
@ -419,7 +547,7 @@ SHA256_Update(SHA256Context *ctx, const unsigned char *input,
|
|||
memcpy(B, input, SHA256_BLOCK_LENGTH);
|
||||
input += SHA256_BLOCK_LENGTH;
|
||||
inputLen -= SHA256_BLOCK_LENGTH;
|
||||
SHA256_Compress(ctx);
|
||||
SHA256_Compress_Generic(ctx);
|
||||
}
|
||||
/* if data left over, fill it into buffer */
|
||||
if (inputLen)
|
||||
|
|
@ -437,7 +565,7 @@ SHA256_End(SHA256Context *ctx, unsigned char *digest,
|
|||
hi = (ctx->sizeHi << 3) | (ctx->sizeLo >> 29);
|
||||
lo = (ctx->sizeLo << 3);
|
||||
|
||||
SHA256_Update(ctx, pad, padLen);
|
||||
ctx->update(ctx, pad, padLen);
|
||||
|
||||
#if defined(IS_LITTLE_ENDIAN)
|
||||
W[14] = SHA_HTONL(hi);
|
||||
|
|
@ -446,7 +574,7 @@ SHA256_End(SHA256Context *ctx, unsigned char *digest,
|
|||
W[14] = hi;
|
||||
W[15] = lo;
|
||||
#endif
|
||||
SHA256_Compress(ctx);
|
||||
ctx->compress(ctx);
|
||||
|
||||
/* now output the answer */
|
||||
#if defined(IS_LITTLE_ENDIAN)
|
||||
|
|
@ -568,15 +696,32 @@ SHA224_DestroyContext(SHA224Context *ctx, PRBool freeit)
|
|||
void
|
||||
SHA224_Begin(SHA224Context *ctx)
|
||||
{
|
||||
PRBool use_hw_sha2;
|
||||
|
||||
memset(ctx, 0, sizeof *ctx);
|
||||
memcpy(H, H224, sizeof H224);
|
||||
|
||||
#if defined(USE_HW_SHA2) && defined(IS_LITTLE_ENDIAN)
|
||||
/* arm's implementation is tested on little endian only */
|
||||
use_hw_sha2 = arm_sha2_support() || (sha_support() && ssse3_support() && sse4_1_support());
|
||||
#else
|
||||
use_hw_sha2 = PR_FALSE;
|
||||
#endif
|
||||
|
||||
if (use_hw_sha2) {
|
||||
ctx->compress = SHA256_Compress_Native;
|
||||
ctx->update = SHA256_Update_Native;
|
||||
} else {
|
||||
ctx->compress = SHA256_Compress_Generic;
|
||||
ctx->update = SHA256_Update_Generic;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SHA224_Update(SHA224Context *ctx, const unsigned char *input,
|
||||
unsigned int inputLen)
|
||||
{
|
||||
SHA256_Update(ctx, input, inputLen);
|
||||
ctx->update(ctx, input, inputLen);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -691,6 +836,11 @@ SHA224_Clone(SHA224Context *dest, SHA224Context *src)
|
|||
|
||||
#endif
|
||||
|
||||
#if defined(USE_PPC_CRYPTO)
|
||||
void sha512_block_p8(void *ctx, const void *inp, size_t len);
|
||||
|
||||
#else /* USE_PPC_CRYPTO */
|
||||
|
||||
/* SHA-384 and SHA-512 constants, K512. */
|
||||
static const PRUint64 K512[80] = {
|
||||
#if PR_BYTES_PER_LONG == 8
|
||||
|
|
@ -778,6 +928,8 @@ static const PRUint64 K512[80] = {
|
|||
#endif
|
||||
};
|
||||
|
||||
#endif /* !USE_PPC_CRYPTO */
|
||||
|
||||
struct SHA512ContextStr {
|
||||
union {
|
||||
PRUint64 w[80]; /* message schedule, input buffer, plus 64 words */
|
||||
|
|
@ -932,6 +1084,10 @@ SHA512_Begin(SHA512Context *ctx)
|
|||
static void
|
||||
SHA512_Compress(SHA512Context *ctx)
|
||||
{
|
||||
#if defined(USE_PPC_CRYPTO)
|
||||
sha512_block_p8(&H[0], &W[0], 1);
|
||||
#else /* USE_PPC_CRYPTO */
|
||||
|
||||
#if defined(IS_LITTLE_ENDIAN)
|
||||
{
|
||||
BYTESWAP8(W[0]);
|
||||
|
|
@ -1174,6 +1330,8 @@ SHA512_Compress(SHA512Context *ctx)
|
|||
ADDTO(g, H[6]);
|
||||
ADDTO(h, H[7]);
|
||||
}
|
||||
|
||||
#endif /* !USE_PPC_CRYPTO */
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include "blapi.h"
|
||||
#include "sha_fast.h"
|
||||
#include "prerror.h"
|
||||
#include "secerr.h"
|
||||
|
||||
#ifdef TRACING_SSL
|
||||
#include "ssl.h"
|
||||
|
|
@ -28,6 +29,28 @@ static void shaCompress(volatile SHA_HW_t *X, const PRUint32 *datain);
|
|||
|
||||
#define SHA_MIX(n, a, b, c) XW(n) = SHA_ROTL(XW(a) ^ XW(b) ^ XW(c) ^ XW(n), 1)
|
||||
|
||||
void SHA1_Compress_Native(SHA1Context *ctx);
|
||||
void SHA1_Update_Native(SHA1Context *ctx, const unsigned char *dataIn, unsigned int len);
|
||||
|
||||
static void SHA1_Compress_Generic(SHA1Context *ctx);
|
||||
static void SHA1_Update_Generic(SHA1Context *ctx, const unsigned char *dataIn, unsigned int len);
|
||||
|
||||
#ifndef USE_HW_SHA1
|
||||
void
|
||||
SHA1_Compress_Native(SHA1Context *ctx)
|
||||
{
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
PORT_Assert(0);
|
||||
}
|
||||
|
||||
void
|
||||
SHA1_Update_Native(SHA1Context *ctx, const unsigned char *dataIn, unsigned int len)
|
||||
{
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
PORT_Assert(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* SHA: initialize context
|
||||
*/
|
||||
|
|
@ -43,6 +66,18 @@ SHA1_Begin(SHA1Context *ctx)
|
|||
ctx->H[2] = 0x98badcfeL;
|
||||
ctx->H[3] = 0x10325476L;
|
||||
ctx->H[4] = 0xc3d2e1f0L;
|
||||
|
||||
#if defined(USE_HW_SHA1) && defined(IS_LITTLE_ENDIAN)
|
||||
/* arm's implementation is tested on little endian only */
|
||||
if (arm_sha1_support()) {
|
||||
ctx->compress = SHA1_Compress_Native;
|
||||
ctx->update = SHA1_Update_Native;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
ctx->compress = SHA1_Compress_Generic;
|
||||
ctx->update = SHA1_Update_Generic;
|
||||
}
|
||||
}
|
||||
|
||||
/* Explanation of H array and index values:
|
||||
|
|
@ -88,6 +123,12 @@ SHA1_Begin(SHA1Context *ctx)
|
|||
*/
|
||||
void
|
||||
SHA1_Update(SHA1Context *ctx, const unsigned char *dataIn, unsigned int len)
|
||||
{
|
||||
ctx->update(ctx, dataIn, len);
|
||||
}
|
||||
|
||||
static void
|
||||
SHA1_Update_Generic(SHA1Context *ctx, const unsigned char *dataIn, unsigned int len)
|
||||
{
|
||||
register unsigned int lenB;
|
||||
register unsigned int togo;
|
||||
|
|
@ -166,7 +207,7 @@ SHA1_End(SHA1Context *ctx, unsigned char *hashout,
|
|||
size <<= 3;
|
||||
ctx->W[14] = SHA_HTONL((PRUint32)(size >> 32));
|
||||
ctx->W[15] = SHA_HTONL((PRUint32)size);
|
||||
shaCompress(&ctx->H[H2X], ctx->W);
|
||||
ctx->compress(ctx);
|
||||
|
||||
/*
|
||||
* Output hash
|
||||
|
|
@ -460,6 +501,12 @@ shaCompress(volatile SHA_HW_t *X, const PRUint32 *inbuf)
|
|||
XH(4) += E;
|
||||
}
|
||||
|
||||
static void
|
||||
SHA1_Compress_Generic(SHA1Context *ctx)
|
||||
{
|
||||
shaCompress(&ctx->H[H2X], ctx->u.w);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
** Code below this line added to make SHA code support BLAPI interface
|
||||
*/
|
||||
|
|
@ -491,7 +538,7 @@ SHA1_HashBuf(unsigned char *dest, const unsigned char *src, PRUint32 src_length)
|
|||
unsigned int outLen;
|
||||
|
||||
SHA1_Begin(&ctx);
|
||||
SHA1_Update(&ctx, src, src_length);
|
||||
ctx.update(&ctx, src, src_length);
|
||||
SHA1_End(&ctx, dest, &outLen, SHA1_LENGTH);
|
||||
memset(&ctx, 0, sizeof ctx);
|
||||
return SECSuccess;
|
||||
|
|
|
|||
|
|
@ -10,13 +10,19 @@
|
|||
|
||||
#define SHA1_INPUT_LEN 64
|
||||
|
||||
#if defined(IS_64) && !defined(__sparc)
|
||||
#if defined(IS_64) && !defined(__sparc) && !defined(__aarch64__)
|
||||
typedef PRUint64 SHA_HW_t;
|
||||
#define SHA1_USING_64_BIT 1
|
||||
#else
|
||||
typedef PRUint32 SHA_HW_t;
|
||||
#endif
|
||||
|
||||
struct SHA1ContextStr;
|
||||
|
||||
typedef void (*sha1_compress_t)(struct SHA1ContextStr *);
|
||||
typedef void (*sha1_update_t)(struct SHA1ContextStr *, const unsigned char *,
|
||||
unsigned int);
|
||||
|
||||
struct SHA1ContextStr {
|
||||
union {
|
||||
PRUint32 w[16]; /* input buffer */
|
||||
|
|
@ -24,6 +30,8 @@ struct SHA1ContextStr {
|
|||
} u;
|
||||
PRUint64 size; /* count of hashed bytes. */
|
||||
SHA_HW_t H[22]; /* 5 state variables, 16 tmp values, 1 extra */
|
||||
sha1_compress_t compress;
|
||||
sha1_update_t update;
|
||||
};
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
|
@ -135,7 +143,7 @@ swap4b(PRUint32 value)
|
|||
|
||||
#define SHA_BYTESWAP(x) x = SHA_HTONL(x)
|
||||
|
||||
#define SHA_STORE(n) ((PRUint32*)hashout)[n] = SHA_HTONL(ctx->H[n])
|
||||
#define SHA_STORE(n) ((PRUint32 *)hashout)[n] = SHA_HTONL(ctx->H[n])
|
||||
#if defined(HAVE_UNALIGNED_ACCESS)
|
||||
#define SHA_STORE_RESULT \
|
||||
SHA_STORE(0); \
|
||||
|
|
|
|||
|
|
@ -8,7 +8,19 @@
|
|||
#define SGN_SUFFIX ".chk"
|
||||
#define NSS_SIGN_CHK_MAGIC1 0xf1
|
||||
#define NSS_SIGN_CHK_MAGIC2 0xc5
|
||||
#define NSS_SIGN_CHK_MAJOR_VERSION 0x01
|
||||
#define NSS_SIGN_CHK_MINOR_VERSION 0x02
|
||||
/* new hmac based signatures */
|
||||
#define NSS_SIGN_CHK_MAJOR_VERSION 0x02
|
||||
#define NSS_SIGN_CHK_MINOR_VERSION 0x01
|
||||
#define NSS_SIGN_CHK_TYPE_FLAGS 0xff000000
|
||||
#define NSS_SIGN_CHK_FLAG_HMAC 0x80000000
|
||||
|
||||
typedef struct NSSSignChkHeaderStr NSSSignChkHeader;
|
||||
struct NSSSignChkHeaderStr {
|
||||
unsigned char magic1;
|
||||
unsigned char magic2;
|
||||
unsigned char majorVersion;
|
||||
unsigned char minorVersion;
|
||||
unsigned char offset[4];
|
||||
unsigned char type[4];
|
||||
};
|
||||
#endif /* _SHSIGN_H_ */
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@
|
|||
#include "hasht.h"
|
||||
#include "pqg.h"
|
||||
#include "blapii.h"
|
||||
#include "secitem.h"
|
||||
#include "pkcs11t.h"
|
||||
|
||||
#ifndef NSS_FIPS_DISABLED
|
||||
|
||||
|
|
@ -286,10 +288,10 @@ readItem(PRFileDesc *fd, SECItem *item)
|
|||
return SECSuccess;
|
||||
}
|
||||
|
||||
static PRBool blapi_SHVerifyFile(const char *shName, PRBool self);
|
||||
static PRBool blapi_SHVerifyFile(const char *shName, PRBool self, PRBool rerun);
|
||||
|
||||
static PRBool
|
||||
blapi_SHVerify(const char *name, PRFuncPtr addr, PRBool self)
|
||||
blapi_SHVerify(const char *name, PRFuncPtr addr, PRBool self, PRBool rerun)
|
||||
{
|
||||
PRBool result = PR_FALSE; /* if anything goes wrong,
|
||||
* the signature does not verify */
|
||||
|
|
@ -298,7 +300,7 @@ blapi_SHVerify(const char *name, PRFuncPtr addr, PRBool self)
|
|||
if (!shName) {
|
||||
goto loser;
|
||||
}
|
||||
result = blapi_SHVerifyFile(shName, self);
|
||||
result = blapi_SHVerifyFile(shName, self, rerun);
|
||||
|
||||
loser:
|
||||
if (shName != NULL) {
|
||||
|
|
@ -311,45 +313,150 @@ loser:
|
|||
PRBool
|
||||
BLAPI_SHVerify(const char *name, PRFuncPtr addr)
|
||||
{
|
||||
return blapi_SHVerify(name, addr, PR_FALSE);
|
||||
PRBool rerun = PR_FALSE;
|
||||
if (name && *name == BLAPI_FIPS_RERUN_FLAG) {
|
||||
name++;
|
||||
rerun = PR_TRUE;
|
||||
}
|
||||
return blapi_SHVerify(name, addr, PR_FALSE, rerun);
|
||||
}
|
||||
|
||||
PRBool
|
||||
BLAPI_SHVerifyFile(const char *shName)
|
||||
{
|
||||
return blapi_SHVerifyFile(shName, PR_FALSE);
|
||||
PRBool rerun = PR_FALSE;
|
||||
if (shName && *shName == BLAPI_FIPS_RERUN_FLAG) {
|
||||
shName++;
|
||||
rerun = PR_TRUE;
|
||||
}
|
||||
return blapi_SHVerifyFile(shName, PR_FALSE, rerun);
|
||||
}
|
||||
|
||||
#ifndef NSS_STRICT_INTEGRITY
|
||||
/* This allows checks with old shlibsign .chk files. If NSS_STRICT_INTEGRITY
|
||||
* is set, we don't accept DSA */
|
||||
static PRBool
|
||||
blapi_SHVerifyDSACheck(PRFileDesc *shFD, const SECHashObject *hashObj,
|
||||
DSAPublicKey *key, const SECItem *signature)
|
||||
{
|
||||
void *hashcx = NULL;
|
||||
SECItem hash;
|
||||
int bytesRead;
|
||||
unsigned char hashBuf[HASH_LENGTH_MAX];
|
||||
unsigned char buf[4096];
|
||||
SECStatus rv;
|
||||
|
||||
hash.type = siBuffer;
|
||||
hash.data = hashBuf;
|
||||
hash.len = sizeof(hashBuf);
|
||||
|
||||
/* hash our library file */
|
||||
hashcx = hashObj->create();
|
||||
if (hashcx == NULL) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
hashObj->begin(hashcx);
|
||||
|
||||
while ((bytesRead = PR_Read(shFD, buf, sizeof(buf))) > 0) {
|
||||
hashObj->update(hashcx, buf, bytesRead);
|
||||
}
|
||||
hashObj->end(hashcx, hash.data, &hash.len, hash.len);
|
||||
hashObj->destroy(hashcx, PR_TRUE);
|
||||
|
||||
/* verify the hash against the check file */
|
||||
rv = DSA_VerifyDigest(key, signature, &hash);
|
||||
PORT_Memset(hashBuf, 0, sizeof hashBuf);
|
||||
return (rv == SECSuccess) ? PR_TRUE : PR_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NSS_STRICT_INTEGRITY
|
||||
/* don't allow MD2, MD5, SHA1 or SHA224 as your integrity hash */
|
||||
static PRBool
|
||||
blapi_HashAllowed(SECHashObject *hashObj)
|
||||
{
|
||||
switch (hashObj->type) {
|
||||
case HASH_AlgSHA256:
|
||||
case HASH_AlgSHA384:
|
||||
case HASH_AlgSHA512:
|
||||
return PR_TRUE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static PRBool
|
||||
blapi_SHVerifyHMACCheck(PRFileDesc *shFD, const SECHashObject *hashObj,
|
||||
const SECItem *key, const SECItem *signature)
|
||||
{
|
||||
HMACContext *hmaccx = NULL;
|
||||
SECItem hash;
|
||||
int bytesRead;
|
||||
unsigned char hashBuf[HASH_LENGTH_MAX];
|
||||
unsigned char buf[4096];
|
||||
SECStatus rv;
|
||||
PRBool result = PR_FALSE;
|
||||
|
||||
#ifdef NSS_STRICT_INTEGRITY
|
||||
if (!blapi_HashAllowed(hashObj)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
hash.type = siBuffer;
|
||||
hash.data = hashBuf;
|
||||
hash.len = hashObj->length;
|
||||
|
||||
/* create an hmac for the library file */
|
||||
hmaccx = HMAC_Create(hashObj, key->data, key->len, PR_TRUE);
|
||||
if (hmaccx == NULL) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
HMAC_Begin(hmaccx);
|
||||
|
||||
while ((bytesRead = PR_Read(shFD, buf, sizeof(buf))) > 0) {
|
||||
HMAC_Update(hmaccx, buf, bytesRead);
|
||||
}
|
||||
rv = HMAC_Finish(hmaccx, hash.data, &hash.len, hash.len);
|
||||
|
||||
HMAC_Destroy(hmaccx, PR_TRUE);
|
||||
|
||||
/* verify the hmac against the check file */
|
||||
if (rv == SECSuccess) {
|
||||
result = SECITEM_ItemsAreEqual(signature, &hash);
|
||||
}
|
||||
PORT_Memset(hashBuf, 0, sizeof hashBuf);
|
||||
return result;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
blapi_SHVerifyFile(const char *shName, PRBool self)
|
||||
blapi_SHVerifyFile(const char *shName, PRBool self, PRBool rerun)
|
||||
{
|
||||
char *checkName = NULL;
|
||||
PRFileDesc *checkFD = NULL;
|
||||
PRFileDesc *shFD = NULL;
|
||||
void *hashcx = NULL;
|
||||
const SECHashObject *hashObj = NULL;
|
||||
SECItem signature = { 0, NULL, 0 };
|
||||
SECItem hash;
|
||||
int bytesRead, offset;
|
||||
int bytesRead, offset, type;
|
||||
SECStatus rv;
|
||||
DSAPublicKey key;
|
||||
int count;
|
||||
SECItem hmacKey = { 0, NULL, 0 };
|
||||
#ifdef FREEBL_USE_PRELINK
|
||||
int pid = 0;
|
||||
#endif
|
||||
|
||||
PRBool result = PR_FALSE; /* if anything goes wrong,
|
||||
* the signature does not verify */
|
||||
unsigned char buf[4096];
|
||||
unsigned char hashBuf[HASH_LENGTH_MAX];
|
||||
* the signature does not verify */
|
||||
NSSSignChkHeader header;
|
||||
#ifndef NSS_STRICT_INTEGRITY
|
||||
DSAPublicKey key;
|
||||
|
||||
PORT_Memset(&key, 0, sizeof(key));
|
||||
hash.data = hashBuf;
|
||||
hash.len = sizeof(hashBuf);
|
||||
#endif
|
||||
|
||||
/* If our integrity check was never ran or failed, fail any other
|
||||
* integrity checks to prevent any token going into FIPS mode. */
|
||||
if (!self && (BL_FIPSEntryOK(PR_FALSE) != SECSuccess)) {
|
||||
if (!self && (BL_FIPSEntryOK(PR_FALSE, rerun) != SECSuccess)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -374,57 +481,82 @@ blapi_SHVerifyFile(const char *shName, PRBool self)
|
|||
}
|
||||
|
||||
/* read and Verify the headerthe header */
|
||||
bytesRead = PR_Read(checkFD, buf, 12);
|
||||
if (bytesRead != 12) {
|
||||
bytesRead = PR_Read(checkFD, &header, sizeof(header));
|
||||
if (bytesRead != sizeof(header)) {
|
||||
goto loser;
|
||||
}
|
||||
if ((buf[0] != NSS_SIGN_CHK_MAGIC1) || (buf[1] != NSS_SIGN_CHK_MAGIC2)) {
|
||||
if ((header.magic1 != NSS_SIGN_CHK_MAGIC1) ||
|
||||
(header.magic2 != NSS_SIGN_CHK_MAGIC2)) {
|
||||
goto loser;
|
||||
}
|
||||
if ((buf[2] != NSS_SIGN_CHK_MAJOR_VERSION) ||
|
||||
(buf[3] < NSS_SIGN_CHK_MINOR_VERSION)) {
|
||||
/* we've bumped the version number so that newly signed .check
|
||||
* files will fail nicely on old version of nss */
|
||||
if (header.majorVersion > NSS_SIGN_CHK_MAJOR_VERSION) {
|
||||
goto loser;
|
||||
}
|
||||
#ifdef notdef
|
||||
if (decodeInt(&buf[8]) != CKK_DSA) {
|
||||
if (header.minorVersion < NSS_SIGN_CHK_MINOR_VERSION) {
|
||||
goto loser;
|
||||
}
|
||||
#endif
|
||||
type = decodeInt(header.type);
|
||||
|
||||
/* seek past any future header extensions */
|
||||
offset = decodeInt(&buf[4]);
|
||||
offset = decodeInt(header.offset);
|
||||
if (PR_Seek(checkFD, offset, PR_SEEK_SET) < 0) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* read the key */
|
||||
rv = readItem(checkFD, &key.params.prime);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
rv = readItem(checkFD, &key.params.subPrime);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
rv = readItem(checkFD, &key.params.base);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
rv = readItem(checkFD, &key.publicValue);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
/* read the siganture */
|
||||
rv = readItem(checkFD, &signature);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
switch (type) {
|
||||
case CKK_DSA:
|
||||
#ifdef NSS_STRICT_INTEGRITY
|
||||
goto loser;
|
||||
#else
|
||||
/* accept old dsa check files if NSS_STRICT_INTEGRITY is not set*/
|
||||
/* read the key */
|
||||
rv = readItem(checkFD, &key.params.prime);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
rv = readItem(checkFD, &key.params.subPrime);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
rv = readItem(checkFD, &key.params.base);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
rv = readItem(checkFD, &key.publicValue);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
/* read the signature */
|
||||
rv = readItem(checkFD, &signature);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
hashObj = HASH_GetRawHashObject(PQG_GetHashType(&key.params));
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
if ((type & NSS_SIGN_CHK_TYPE_FLAGS) != NSS_SIGN_CHK_FLAG_HMAC) {
|
||||
goto loser;
|
||||
}
|
||||
/* read the HMAC Key */
|
||||
rv = readItem(checkFD, &hmacKey);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
/* read the siganture */
|
||||
rv = readItem(checkFD, &signature);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
hashObj = HASH_GetRawHashObject(type & ~NSS_SIGN_CHK_TYPE_FLAGS);
|
||||
}
|
||||
|
||||
/* done with the check file */
|
||||
PR_Close(checkFD);
|
||||
checkFD = NULL;
|
||||
|
||||
hashObj = HASH_GetRawHashObject(PQG_GetHashType(&key.params));
|
||||
if (hashObj == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
|
@ -443,18 +575,20 @@ blapi_SHVerifyFile(const char *shName, PRBool self)
|
|||
goto loser;
|
||||
}
|
||||
|
||||
/* hash our library file with SHA1 */
|
||||
hashcx = hashObj->create();
|
||||
if (hashcx == NULL) {
|
||||
goto loser;
|
||||
switch (type) {
|
||||
case CKK_DSA:
|
||||
#ifndef NSS_STRICT_INTEGRITY
|
||||
result = blapi_SHVerifyDSACheck(shFD, hashObj, &key, &signature);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
if ((type & NSS_SIGN_CHK_TYPE_FLAGS) != NSS_SIGN_CHK_FLAG_HMAC) {
|
||||
break;
|
||||
}
|
||||
result = blapi_SHVerifyHMACCheck(shFD, hashObj, &hmacKey, &signature);
|
||||
break;
|
||||
}
|
||||
hashObj->begin(hashcx);
|
||||
|
||||
count = 0;
|
||||
while ((bytesRead = PR_Read(shFD, buf, sizeof(buf))) > 0) {
|
||||
hashObj->update(hashcx, buf, bytesRead);
|
||||
count += bytesRead;
|
||||
}
|
||||
#ifdef FREEBL_USE_PRELINK
|
||||
bl_CloseUnPrelink(shFD, pid);
|
||||
#else
|
||||
|
|
@ -462,38 +596,8 @@ blapi_SHVerifyFile(const char *shName, PRBool self)
|
|||
#endif
|
||||
shFD = NULL;
|
||||
|
||||
hashObj->end(hashcx, hash.data, &hash.len, hash.len);
|
||||
|
||||
/* verify the hash against the check file */
|
||||
if (DSA_VerifyDigest(&key, &signature, &hash) == SECSuccess) {
|
||||
result = PR_TRUE;
|
||||
}
|
||||
#ifdef DEBUG_SHVERIFY
|
||||
{
|
||||
int i, j;
|
||||
fprintf(stderr, "File %s: %d bytes\n", shName, count);
|
||||
fprintf(stderr, " hash: %d bytes\n", hash.len);
|
||||
#define STEP 10
|
||||
for (i = 0; i < hash.len; i += STEP) {
|
||||
fprintf(stderr, " ");
|
||||
for (j = 0; j < STEP && (i + j) < hash.len; j++) {
|
||||
fprintf(stderr, " %02x", hash.data[i + j]);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
fprintf(stderr, " signature: %d bytes\n", signature.len);
|
||||
for (i = 0; i < signature.len; i += STEP) {
|
||||
fprintf(stderr, " ");
|
||||
for (j = 0; j < STEP && (i + j) < signature.len; j++) {
|
||||
fprintf(stderr, " %02x", signature.data[i + j]);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
fprintf(stderr, "Verified : %s\n", result ? "TRUE" : "FALSE");
|
||||
}
|
||||
#endif /* DEBUG_SHVERIFY */
|
||||
|
||||
loser:
|
||||
PORT_Memset(&header, 0, sizeof header);
|
||||
if (checkName != NULL) {
|
||||
PORT_Free(checkName);
|
||||
}
|
||||
|
|
@ -503,27 +607,26 @@ loser:
|
|||
if (shFD != NULL) {
|
||||
PR_Close(shFD);
|
||||
}
|
||||
if (hashcx != NULL) {
|
||||
if (hashObj) {
|
||||
hashObj->destroy(hashcx, PR_TRUE);
|
||||
}
|
||||
if (hmacKey.data != NULL) {
|
||||
SECITEM_ZfreeItem(&hmacKey, PR_FALSE);
|
||||
}
|
||||
if (signature.data != NULL) {
|
||||
PORT_Free(signature.data);
|
||||
SECITEM_ZfreeItem(&signature, PR_FALSE);
|
||||
}
|
||||
#ifndef NSS_STRICT_INTEGRITY
|
||||
if (key.params.prime.data != NULL) {
|
||||
PORT_Free(key.params.prime.data);
|
||||
SECITEM_ZfreeItem(&key.params.prime, PR_FALSE);
|
||||
}
|
||||
if (key.params.subPrime.data != NULL) {
|
||||
PORT_Free(key.params.subPrime.data);
|
||||
SECITEM_ZfreeItem(&key.params.subPrime, PR_FALSE);
|
||||
}
|
||||
if (key.params.base.data != NULL) {
|
||||
PORT_Free(key.params.base.data);
|
||||
SECITEM_ZfreeItem(&key.params.base, PR_FALSE);
|
||||
}
|
||||
if (key.publicValue.data != NULL) {
|
||||
PORT_Free(key.publicValue.data);
|
||||
SECITEM_ZfreeItem(&key.publicValue, PR_FALSE);
|
||||
}
|
||||
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -532,12 +635,12 @@ BLAPI_VerifySelf(const char *name)
|
|||
{
|
||||
if (name == NULL) {
|
||||
/*
|
||||
* If name is NULL, freebl is statically linked into softoken.
|
||||
* softoken will call BLAPI_SHVerify next to verify itself.
|
||||
*/
|
||||
* If name is NULL, freebl is statically linked into softoken.
|
||||
* softoken will call BLAPI_SHVerify next to verify itself.
|
||||
*/
|
||||
return PR_TRUE;
|
||||
}
|
||||
return blapi_SHVerify(name, (PRFuncPtr)decodeInt, PR_TRUE);
|
||||
return blapi_SHVerify(name, (PRFuncPtr)decodeInt, PR_TRUE, PR_FALSE);
|
||||
}
|
||||
|
||||
#else /* NSS_FIPS_DISABLED */
|
||||
|
|
|
|||
|
|
@ -86,6 +86,10 @@
|
|||
if (ptr_##fn) { \
|
||||
return ptr_##fn(a1, a2, a3, a4); \
|
||||
}
|
||||
#define STUB_SAFE_CALL5(fn, a1, a2, a3, a4, a5) \
|
||||
if (ptr_##fn) { \
|
||||
return ptr_##fn(a1, a2, a3, a4, a5); \
|
||||
}
|
||||
#define STUB_SAFE_CALL6(fn, a1, a2, a3, a4, a5, a6) \
|
||||
if (ptr_##fn) { \
|
||||
return ptr_##fn(a1, a2, a3, a4, a5, a6); \
|
||||
|
|
@ -142,11 +146,8 @@ STUB_DECLARE(int, PORT_GetError_Util, (void));
|
|||
STUB_DECLARE(PLArenaPool *, PORT_NewArena_Util, (unsigned long chunksize));
|
||||
STUB_DECLARE(void, PORT_SetError_Util, (int value));
|
||||
STUB_DECLARE(void *, PORT_ZAlloc_Util, (size_t len));
|
||||
STUB_DECLARE(void *, PORT_ZAllocAligned_Util, (size_t bytes, size_t alignment,
|
||||
void **mem));
|
||||
STUB_DECLARE(void *, PORT_ZAllocAlignedOffset_Util, (size_t bytes,
|
||||
size_t alignment,
|
||||
size_t offset));
|
||||
STUB_DECLARE(void *, PORT_ZAllocAligned_Util, (size_t bytes, size_t alignment, void **mem));
|
||||
STUB_DECLARE(void *, PORT_ZAllocAlignedOffset_Util, (size_t bytes, size_t alignment, size_t offset));
|
||||
STUB_DECLARE(void, PORT_ZFree_Util, (void *ptr, size_t len));
|
||||
|
||||
STUB_DECLARE(void, PR_Assert, (const char *s, const char *file, PRIntn ln));
|
||||
|
|
@ -156,36 +157,31 @@ STUB_DECLARE(PRStatus, PR_Close, (PRFileDesc * fd));
|
|||
STUB_DECLARE(void, PR_DestroyLock, (PRLock * lock));
|
||||
STUB_DECLARE(void, PR_DestroyCondVar, (PRCondVar * cvar));
|
||||
STUB_DECLARE(void, PR_Free, (void *ptr));
|
||||
STUB_DECLARE(char *, PR_GetLibraryFilePathname, (const char *name,
|
||||
PRFuncPtr addr));
|
||||
STUB_DECLARE(char *, PR_GetLibraryFilePathname, (const char *name, PRFuncPtr addr));
|
||||
STUB_DECLARE(PRFileDesc *, PR_ImportPipe, (PROsfd osfd));
|
||||
STUB_DECLARE(void, PR_Lock, (PRLock * lock));
|
||||
STUB_DECLARE(PRCondVar *, PR_NewCondVar, (PRLock * lock));
|
||||
STUB_DECLARE(PRLock *, PR_NewLock, (void));
|
||||
STUB_DECLARE(PRStatus, PR_NotifyCondVar, (PRCondVar * cvar));
|
||||
STUB_DECLARE(PRStatus, PR_NotifyAllCondVar, (PRCondVar * cvar));
|
||||
STUB_DECLARE(PRFileDesc *, PR_Open, (const char *name, PRIntn flags,
|
||||
PRIntn mode));
|
||||
STUB_DECLARE(PRFileDesc *, PR_Open, (const char *name, PRIntn flags, PRIntn mode));
|
||||
STUB_DECLARE(PRInt32, PR_Read, (PRFileDesc * fd, void *buf, PRInt32 amount));
|
||||
STUB_DECLARE(PROffset32, PR_Seek, (PRFileDesc * fd, PROffset32 offset,
|
||||
PRSeekWhence whence));
|
||||
STUB_DECLARE(PROffset32, PR_Seek, (PRFileDesc * fd, PROffset32 offset, PRSeekWhence whence));
|
||||
STUB_DECLARE(PRStatus, PR_Sleep, (PRIntervalTime ticks));
|
||||
STUB_DECLARE(PRStatus, PR_Unlock, (PRLock * lock));
|
||||
STUB_DECLARE(PRStatus, PR_WaitCondVar, (PRCondVar * cvar,
|
||||
PRIntervalTime timeout));
|
||||
STUB_DECLARE(PRStatus, PR_WaitCondVar, (PRCondVar * cvar, PRIntervalTime timeout));
|
||||
STUB_DECLARE(char *, PR_GetEnvSecure, (const char *));
|
||||
|
||||
STUB_DECLARE(SECItem *, SECITEM_AllocItem_Util, (PLArenaPool * arena,
|
||||
SECItem *item, unsigned int len));
|
||||
STUB_DECLARE(SECComparison, SECITEM_CompareItem_Util, (const SECItem *a,
|
||||
const SECItem *b));
|
||||
STUB_DECLARE(SECStatus, SECITEM_CopyItem_Util, (PLArenaPool * arena,
|
||||
SECItem *to, const SECItem *from));
|
||||
STUB_DECLARE(SECItem *, SECITEM_AllocItem_Util, (PLArenaPool * arena, SECItem *item, unsigned int len));
|
||||
STUB_DECLARE(SECComparison, SECITEM_CompareItem_Util, (const SECItem *a, const SECItem *b));
|
||||
STUB_DECLARE(PRBool, SECITEM_ItemsAreEqual_Util, (const SECItem *a, const SECItem *b));
|
||||
STUB_DECLARE(SECStatus, SECITEM_CopyItem_Util, (PLArenaPool * arena, SECItem *to, const SECItem *from));
|
||||
STUB_DECLARE(void, SECITEM_FreeItem_Util, (SECItem * zap, PRBool freeit));
|
||||
STUB_DECLARE(void, SECITEM_ZfreeItem_Util, (SECItem * zap, PRBool freeit));
|
||||
STUB_DECLARE(SECOidTag, SECOID_FindOIDTag_Util, (const SECItem *oid));
|
||||
STUB_DECLARE(int, NSS_SecureMemcmp, (const void *a, const void *b, size_t n));
|
||||
STUB_DECLARE(unsigned int, NSS_SecureMemcmpZero, (const void *mem, size_t n));
|
||||
STUB_DECLARE(void, NSS_SecureSelect, (void *dest, const void *src0, const void *src1, size_t n, unsigned char b));
|
||||
|
||||
#define PORT_ZNew_stub(type) (type *)PORT_ZAlloc_stub(sizeof(type))
|
||||
#define PORT_New_stub(type) (type *)PORT_Alloc_stub(sizeof(type))
|
||||
|
|
@ -294,6 +290,13 @@ PR_Free_stub(void *ptr)
|
|||
return free(ptr);
|
||||
}
|
||||
|
||||
/* we have defensive returns after abort(), which is marked noreturn on some
|
||||
* platforms, making the compiler legitimately complain. */
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunreachable-code-return"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* arenas
|
||||
*
|
||||
|
|
@ -576,8 +579,11 @@ extern char *
|
|||
PR_GetEnvSecure_stub(const char *var)
|
||||
{
|
||||
STUB_SAFE_CALL1(PR_GetEnvSecure, var);
|
||||
abort();
|
||||
return NULL;
|
||||
#ifdef __USE_GNU
|
||||
return secure_getenv(var);
|
||||
#else
|
||||
return getenv(var);
|
||||
#endif
|
||||
}
|
||||
|
||||
extern void
|
||||
|
|
@ -625,6 +631,30 @@ SECITEM_CompareItem_stub(const SECItem *a, const SECItem *b)
|
|||
return SECEqual;
|
||||
}
|
||||
|
||||
extern PRBool
|
||||
SECITEM_ItemsAreEqual_stub(const SECItem *a, const SECItem *b)
|
||||
{
|
||||
STUB_SAFE_CALL2(SECITEM_ItemsAreEqual_Util, a, b);
|
||||
/* two nulls are equal */
|
||||
if (!a && !b) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
/* only one NULL is not equal */
|
||||
if (!a || !b) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
/* we know both secitems have been set, now make sure the lengths
|
||||
* are equal */
|
||||
if (a->len != b->len) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
/* lengths are equal, safe to verify the data */
|
||||
if (PORT_Memcmp(a->data, b->data, b->len) != 0) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
extern SECStatus
|
||||
SECITEM_CopyItem_stub(PLArenaPool *arena, SECItem *to, const SECItem *from)
|
||||
{
|
||||
|
|
@ -641,11 +671,24 @@ SECOID_FindOIDTag_stub(const SECItem *oid)
|
|||
return SEC_OID_UNKNOWN;
|
||||
}
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
extern void
|
||||
SECITEM_ZfreeItem_stub(SECItem *zap, PRBool freeit)
|
||||
{
|
||||
STUB_SAFE_CALL2(SECITEM_ZfreeItem_Util, zap, freeit);
|
||||
abort();
|
||||
if (zap) {
|
||||
if (zap->data) {
|
||||
PORT_Memset(zap->data, 0, zap->len);
|
||||
PORT_Free_stub(zap->data);
|
||||
}
|
||||
PORT_Memset(zap, 0, sizeof(SECItem));
|
||||
if (freeit) {
|
||||
PORT_Free_stub(zap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern int
|
||||
|
|
@ -662,6 +705,13 @@ NSS_SecureMemcmpZero_stub(const void *mem, size_t n)
|
|||
abort();
|
||||
}
|
||||
|
||||
extern void
|
||||
NSS_SecureSelect_stub(void *dest, const void *src0, const void *src1, size_t n, unsigned char b)
|
||||
{
|
||||
STUB_SAFE_CALL5(NSS_SecureSelect, dest, src0, src1, n, b);
|
||||
abort();
|
||||
}
|
||||
|
||||
#ifdef FREEBL_NO_WEAK
|
||||
|
||||
static const char *nsprLibName = SHLIB_PREFIX "nspr4." SHLIB_SUFFIX;
|
||||
|
|
@ -715,6 +765,7 @@ freebl_InitNSSUtil(void *lib)
|
|||
STUB_FETCH_FUNCTION(SECOID_FindOIDTag_Util);
|
||||
STUB_FETCH_FUNCTION(NSS_SecureMemcmp);
|
||||
STUB_FETCH_FUNCTION(NSS_SecureMemcmpZero);
|
||||
STUB_FETCH_FUNCTION(NSS_SecureSelect);
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,12 +35,14 @@
|
|||
|
||||
#define SECITEM_AllocItem SECITEM_AllocItem_stub
|
||||
#define SECITEM_CompareItem SECITEM_CompareItem_stub
|
||||
#define SECITEM_ItemsAreEqual SECITEM_ItemsAreEqual_stub
|
||||
#define SECITEM_CopyItem SECITEM_CopyItem_stub
|
||||
#define SECITEM_FreeItem SECITEM_FreeItem_stub
|
||||
#define SECITEM_ZfreeItem SECITEM_ZfreeItem_stub
|
||||
#define SECOID_FindOIDTag SECOID_FindOIDTag_stub
|
||||
#define NSS_SecureMemcmp NSS_SecureMemcmp_stub
|
||||
#define NSS_SecureMemcmpZero NSS_SecureMemcmpZero_stub
|
||||
#define NSS_SecureSelect NSS_SecureSelect_stub
|
||||
|
||||
#define PR_Assert PR_Assert_stub
|
||||
#define PR_Access PR_Access_stub
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@
|
|||
|
||||
#include "seccomon.h"
|
||||
|
||||
#if (defined(XP_UNIX) || defined(XP_BEOS)) && defined(SEED_ONLY_DEV_URANDOM)
|
||||
#if defined(XP_UNIX) && defined(SEED_ONLY_DEV_URANDOM)
|
||||
#include "unix_urandom.c"
|
||||
#elif defined(XP_UNIX) || defined(XP_BEOS)
|
||||
#elif defined(XP_UNIX)
|
||||
#include "unix_rand.c"
|
||||
#endif
|
||||
#ifdef XP_WIN
|
||||
|
|
|
|||
|
|
@ -287,49 +287,6 @@ GiveSystemInfo(void)
|
|||
}
|
||||
#endif /* HPUX */
|
||||
|
||||
#if defined(OSF1)
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysinfo.h>
|
||||
#include <sys/systeminfo.h>
|
||||
#include <c_asm.h>
|
||||
|
||||
static void
|
||||
GiveSystemInfo(void)
|
||||
{
|
||||
char buf[BUFSIZ];
|
||||
int rv;
|
||||
int off = 0;
|
||||
|
||||
rv = sysinfo(SI_MACHINE, buf, sizeof(buf));
|
||||
if (rv > 0) {
|
||||
RNG_RandomUpdate(buf, rv);
|
||||
}
|
||||
rv = sysinfo(SI_RELEASE, buf, sizeof(buf));
|
||||
if (rv > 0) {
|
||||
RNG_RandomUpdate(buf, rv);
|
||||
}
|
||||
rv = sysinfo(SI_HW_SERIAL, buf, sizeof(buf));
|
||||
if (rv > 0) {
|
||||
RNG_RandomUpdate(buf, rv);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Use the "get the cycle counter" instruction on the alpha.
|
||||
* The low 32 bits completely turn over in less than a minute.
|
||||
* The high 32 bits are some non-counter gunk that changes sometimes.
|
||||
*/
|
||||
static size_t
|
||||
GetHighResClock(void *buf, size_t maxbytes)
|
||||
{
|
||||
unsigned long t;
|
||||
|
||||
t = asm("rpcc %v0");
|
||||
return CopyLowBits(buf, maxbytes, &t, sizeof(t));
|
||||
}
|
||||
|
||||
#endif /* Alpha */
|
||||
|
||||
#if defined(_IBMR2)
|
||||
static size_t
|
||||
GetHighResClock(void *buf, size_t maxbytes)
|
||||
|
|
@ -586,39 +543,6 @@ GiveSystemInfo(void)
|
|||
}
|
||||
#endif /* sinix */
|
||||
|
||||
#ifdef BEOS
|
||||
#include <be/kernel/OS.h>
|
||||
|
||||
static size_t
|
||||
GetHighResClock(void *buf, size_t maxbytes)
|
||||
{
|
||||
bigtime_t bigtime; /* Actually a int64 */
|
||||
|
||||
bigtime = real_time_clock_usecs();
|
||||
return CopyLowBits(buf, maxbytes, &bigtime, sizeof(bigtime));
|
||||
}
|
||||
|
||||
static void
|
||||
GiveSystemInfo(void)
|
||||
{
|
||||
system_info *info = NULL;
|
||||
PRInt32 val;
|
||||
get_system_info(info);
|
||||
if (info) {
|
||||
val = info->boot_time;
|
||||
RNG_RandomUpdate(&val, sizeof(val));
|
||||
val = info->used_pages;
|
||||
RNG_RandomUpdate(&val, sizeof(val));
|
||||
val = info->used_ports;
|
||||
RNG_RandomUpdate(&val, sizeof(val));
|
||||
val = info->used_threads;
|
||||
RNG_RandomUpdate(&val, sizeof(val));
|
||||
val = info->used_teams;
|
||||
RNG_RandomUpdate(&val, sizeof(val));
|
||||
}
|
||||
}
|
||||
#endif /* BEOS */
|
||||
|
||||
#if defined(nec_ews)
|
||||
#include <sys/systeminfo.h>
|
||||
|
||||
|
|
@ -692,16 +616,6 @@ RNG_SystemInfoForRNG(void)
|
|||
#else
|
||||
extern char **environ;
|
||||
#endif
|
||||
#ifdef BEOS
|
||||
static const char *const files[] = {
|
||||
"/boot/var/swap",
|
||||
"/boot/var/log/syslog",
|
||||
"/boot/var/tmp",
|
||||
"/boot/home/config/settings",
|
||||
"/boot/home",
|
||||
0
|
||||
};
|
||||
#else
|
||||
static const char *const files[] = {
|
||||
"/etc/passwd",
|
||||
"/etc/utmp",
|
||||
|
|
@ -710,7 +624,6 @@ RNG_SystemInfoForRNG(void)
|
|||
"/usr/tmp",
|
||||
0
|
||||
};
|
||||
#endif
|
||||
|
||||
GiveSystemInfo();
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ RNG_SystemInfoForRNG(void)
|
|||
return;
|
||||
}
|
||||
RNG_RandomUpdate(bytes, numBytes);
|
||||
PORT_Memset(bytes, 0, sizeof bytes);
|
||||
}
|
||||
|
||||
size_t
|
||||
|
|
|
|||
|
|
@ -1,255 +0,0 @@
|
|||
/* Copyright 2016-2018 INRIA and Microsoft Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* This file was auto-generated by KreMLin! */
|
||||
|
||||
#include "FStar.h"
|
||||
|
||||
static uint64_t
|
||||
FStar_UInt128_constant_time_carry(uint64_t a, uint64_t b)
|
||||
{
|
||||
return (a ^ ((a ^ b) | ((a - b) ^ b))) >> (uint32_t)63U;
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
FStar_UInt128_carry(uint64_t a, uint64_t b)
|
||||
{
|
||||
return FStar_UInt128_constant_time_carry(a, b);
|
||||
}
|
||||
|
||||
FStar_UInt128_uint128
|
||||
FStar_UInt128_add(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
|
||||
{
|
||||
return (
|
||||
(FStar_UInt128_uint128){
|
||||
.low = a.low + b.low,
|
||||
.high = a.high + b.high + FStar_UInt128_carry(a.low + b.low, b.low) });
|
||||
}
|
||||
|
||||
FStar_UInt128_uint128
|
||||
FStar_UInt128_add_mod(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
|
||||
{
|
||||
return (
|
||||
(FStar_UInt128_uint128){
|
||||
.low = a.low + b.low,
|
||||
.high = a.high + b.high + FStar_UInt128_carry(a.low + b.low, b.low) });
|
||||
}
|
||||
|
||||
FStar_UInt128_uint128
|
||||
FStar_UInt128_sub(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
|
||||
{
|
||||
return (
|
||||
(FStar_UInt128_uint128){
|
||||
.low = a.low - b.low,
|
||||
.high = a.high - b.high - FStar_UInt128_carry(a.low, a.low - b.low) });
|
||||
}
|
||||
|
||||
static FStar_UInt128_uint128
|
||||
FStar_UInt128_sub_mod_impl(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
|
||||
{
|
||||
return (
|
||||
(FStar_UInt128_uint128){
|
||||
.low = a.low - b.low,
|
||||
.high = a.high - b.high - FStar_UInt128_carry(a.low, a.low - b.low) });
|
||||
}
|
||||
|
||||
FStar_UInt128_uint128
|
||||
FStar_UInt128_sub_mod(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
|
||||
{
|
||||
return FStar_UInt128_sub_mod_impl(a, b);
|
||||
}
|
||||
|
||||
FStar_UInt128_uint128
|
||||
FStar_UInt128_logand(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
|
||||
{
|
||||
return ((FStar_UInt128_uint128){.low = a.low & b.low, .high = a.high & b.high });
|
||||
}
|
||||
|
||||
FStar_UInt128_uint128
|
||||
FStar_UInt128_logxor(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
|
||||
{
|
||||
return ((FStar_UInt128_uint128){.low = a.low ^ b.low, .high = a.high ^ b.high });
|
||||
}
|
||||
|
||||
FStar_UInt128_uint128
|
||||
FStar_UInt128_logor(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
|
||||
{
|
||||
return ((FStar_UInt128_uint128){.low = a.low | b.low, .high = a.high | b.high });
|
||||
}
|
||||
|
||||
FStar_UInt128_uint128
|
||||
FStar_UInt128_lognot(FStar_UInt128_uint128 a)
|
||||
{
|
||||
return ((FStar_UInt128_uint128){.low = ~a.low, .high = ~a.high });
|
||||
}
|
||||
|
||||
static uint32_t FStar_UInt128_u32_64 = (uint32_t)64U;
|
||||
|
||||
static uint64_t
|
||||
FStar_UInt128_add_u64_shift_left(uint64_t hi, uint64_t lo, uint32_t s)
|
||||
{
|
||||
return (hi << s) + (lo >> (FStar_UInt128_u32_64 - s));
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
FStar_UInt128_add_u64_shift_left_respec(uint64_t hi, uint64_t lo, uint32_t s)
|
||||
{
|
||||
return FStar_UInt128_add_u64_shift_left(hi, lo, s);
|
||||
}
|
||||
|
||||
static FStar_UInt128_uint128
|
||||
FStar_UInt128_shift_left_small(FStar_UInt128_uint128 a, uint32_t s)
|
||||
{
|
||||
if (s == (uint32_t)0U)
|
||||
return a;
|
||||
else
|
||||
return (
|
||||
(FStar_UInt128_uint128){
|
||||
.low = a.low << s,
|
||||
.high = FStar_UInt128_add_u64_shift_left_respec(a.high, a.low, s) });
|
||||
}
|
||||
|
||||
static FStar_UInt128_uint128
|
||||
FStar_UInt128_shift_left_large(FStar_UInt128_uint128 a, uint32_t s)
|
||||
{
|
||||
return ((FStar_UInt128_uint128){.low = (uint64_t)0U, .high = a.low << (s - FStar_UInt128_u32_64) });
|
||||
}
|
||||
|
||||
FStar_UInt128_uint128
|
||||
FStar_UInt128_shift_left(FStar_UInt128_uint128 a, uint32_t s)
|
||||
{
|
||||
if (s < FStar_UInt128_u32_64)
|
||||
return FStar_UInt128_shift_left_small(a, s);
|
||||
else
|
||||
return FStar_UInt128_shift_left_large(a, s);
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
FStar_UInt128_add_u64_shift_right(uint64_t hi, uint64_t lo, uint32_t s)
|
||||
{
|
||||
return (lo >> s) + (hi << (FStar_UInt128_u32_64 - s));
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
FStar_UInt128_add_u64_shift_right_respec(uint64_t hi, uint64_t lo, uint32_t s)
|
||||
{
|
||||
return FStar_UInt128_add_u64_shift_right(hi, lo, s);
|
||||
}
|
||||
|
||||
static FStar_UInt128_uint128
|
||||
FStar_UInt128_shift_right_small(FStar_UInt128_uint128 a, uint32_t s)
|
||||
{
|
||||
if (s == (uint32_t)0U)
|
||||
return a;
|
||||
else
|
||||
return (
|
||||
(FStar_UInt128_uint128){
|
||||
.low = FStar_UInt128_add_u64_shift_right_respec(a.high, a.low, s),
|
||||
.high = a.high >> s });
|
||||
}
|
||||
|
||||
static FStar_UInt128_uint128
|
||||
FStar_UInt128_shift_right_large(FStar_UInt128_uint128 a, uint32_t s)
|
||||
{
|
||||
return ((FStar_UInt128_uint128){.low = a.high >> (s - FStar_UInt128_u32_64), .high = (uint64_t)0U });
|
||||
}
|
||||
|
||||
FStar_UInt128_uint128
|
||||
FStar_UInt128_shift_right(FStar_UInt128_uint128 a, uint32_t s)
|
||||
{
|
||||
if (s < FStar_UInt128_u32_64)
|
||||
return FStar_UInt128_shift_right_small(a, s);
|
||||
else
|
||||
return FStar_UInt128_shift_right_large(a, s);
|
||||
}
|
||||
|
||||
FStar_UInt128_uint128
|
||||
FStar_UInt128_eq_mask(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
|
||||
{
|
||||
return (
|
||||
(FStar_UInt128_uint128){
|
||||
.low = FStar_UInt64_eq_mask(a.low, b.low) & FStar_UInt64_eq_mask(a.high, b.high),
|
||||
.high = FStar_UInt64_eq_mask(a.low, b.low) & FStar_UInt64_eq_mask(a.high, b.high) });
|
||||
}
|
||||
|
||||
FStar_UInt128_uint128
|
||||
FStar_UInt128_gte_mask(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
|
||||
{
|
||||
return (
|
||||
(FStar_UInt128_uint128){
|
||||
.low = (FStar_UInt64_gte_mask(a.high, b.high) & ~FStar_UInt64_eq_mask(a.high, b.high)) | (FStar_UInt64_eq_mask(a.high, b.high) & FStar_UInt64_gte_mask(a.low, b.low)),
|
||||
.high = (FStar_UInt64_gte_mask(a.high, b.high) & ~FStar_UInt64_eq_mask(a.high, b.high)) | (FStar_UInt64_eq_mask(a.high, b.high) & FStar_UInt64_gte_mask(a.low, b.low)) });
|
||||
}
|
||||
|
||||
FStar_UInt128_uint128
|
||||
FStar_UInt128_uint64_to_uint128(uint64_t a)
|
||||
{
|
||||
return ((FStar_UInt128_uint128){.low = a, .high = (uint64_t)0U });
|
||||
}
|
||||
|
||||
uint64_t
|
||||
FStar_UInt128_uint128_to_uint64(FStar_UInt128_uint128 a)
|
||||
{
|
||||
return a.low;
|
||||
}
|
||||
|
||||
static uint64_t FStar_UInt128_u64_l32_mask = (uint64_t)0xffffffffU;
|
||||
|
||||
static uint64_t
|
||||
FStar_UInt128_u64_mod_32(uint64_t a)
|
||||
{
|
||||
return a & FStar_UInt128_u64_l32_mask;
|
||||
}
|
||||
|
||||
static uint32_t FStar_UInt128_u32_32 = (uint32_t)32U;
|
||||
|
||||
static K___uint64_t_uint64_t_uint64_t_uint64_t
|
||||
FStar_UInt128_mul_wide_impl_t_(uint64_t x, uint64_t y)
|
||||
{
|
||||
return (
|
||||
(K___uint64_t_uint64_t_uint64_t_uint64_t){
|
||||
.fst = FStar_UInt128_u64_mod_32(x),
|
||||
.snd = FStar_UInt128_u64_mod_32(FStar_UInt128_u64_mod_32(x) * FStar_UInt128_u64_mod_32(y)),
|
||||
.thd = x >> FStar_UInt128_u32_32,
|
||||
.f3 = (x >> FStar_UInt128_u32_32) * FStar_UInt128_u64_mod_32(y) + (FStar_UInt128_u64_mod_32(x) * FStar_UInt128_u64_mod_32(y) >> FStar_UInt128_u32_32) });
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
FStar_UInt128_u32_combine_(uint64_t hi, uint64_t lo)
|
||||
{
|
||||
return lo + (hi << FStar_UInt128_u32_32);
|
||||
}
|
||||
|
||||
static FStar_UInt128_uint128
|
||||
FStar_UInt128_mul_wide_impl(uint64_t x, uint64_t y)
|
||||
{
|
||||
K___uint64_t_uint64_t_uint64_t_uint64_t scrut = FStar_UInt128_mul_wide_impl_t_(x, y);
|
||||
uint64_t u1 = scrut.fst;
|
||||
uint64_t w3 = scrut.snd;
|
||||
uint64_t x_ = scrut.thd;
|
||||
uint64_t t_ = scrut.f3;
|
||||
return (
|
||||
(FStar_UInt128_uint128){
|
||||
.low = FStar_UInt128_u32_combine_(u1 * (y >> FStar_UInt128_u32_32) + FStar_UInt128_u64_mod_32(t_),
|
||||
w3),
|
||||
.high = x_ * (y >> FStar_UInt128_u32_32) + (t_ >> FStar_UInt128_u32_32) +
|
||||
((u1 * (y >> FStar_UInt128_u32_32) + FStar_UInt128_u64_mod_32(t_)) >> FStar_UInt128_u32_32) });
|
||||
}
|
||||
|
||||
FStar_UInt128_uint128
|
||||
FStar_UInt128_mul_wide(uint64_t x, uint64_t y)
|
||||
{
|
||||
return FStar_UInt128_mul_wide_impl(x, y);
|
||||
}
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
/* Copyright 2016-2018 INRIA and Microsoft Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* This file was auto-generated by KreMLin! */
|
||||
#ifndef __FStar_H
|
||||
#define __FStar_H
|
||||
|
||||
#include "kremlib_base.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint64_t low;
|
||||
uint64_t high;
|
||||
} FStar_UInt128_uint128;
|
||||
|
||||
typedef FStar_UInt128_uint128 FStar_UInt128_t;
|
||||
|
||||
extern void FStar_UInt128_constant_time_carry_ok(uint64_t x0, uint64_t x1);
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_add(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_add_mod(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_sub(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_sub_mod(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_logand(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_logxor(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_logor(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_lognot(FStar_UInt128_uint128 a);
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_shift_left(FStar_UInt128_uint128 a, uint32_t s);
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_shift_right(FStar_UInt128_uint128 a, uint32_t s);
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_eq_mask(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_gte_mask(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_uint64_to_uint128(uint64_t a);
|
||||
|
||||
uint64_t FStar_UInt128_uint128_to_uint64(FStar_UInt128_uint128 a);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint64_t fst;
|
||||
uint64_t snd;
|
||||
uint64_t thd;
|
||||
uint64_t f3;
|
||||
} K___uint64_t_uint64_t_uint64_t_uint64_t;
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_mul_wide(uint64_t x, uint64_t y);
|
||||
#endif
|
||||
678
security/nss/lib/freebl/verified/Hacl_Bignum25519_51.h
Normal file
678
security/nss/lib/freebl/verified/Hacl_Bignum25519_51.h
Normal file
|
|
@ -0,0 +1,678 @@
|
|||
/* MIT License
|
||||
*
|
||||
* Copyright (c) 2016-2020 INRIA, CMU and Microsoft Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __Hacl_Bignum25519_51_H
|
||||
#define __Hacl_Bignum25519_51_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include "krml/internal/types.h"
|
||||
#include "krml/lowstar_endianness.h"
|
||||
#include "krml/internal/target.h"
|
||||
|
||||
#include "Hacl_Krmllib.h"
|
||||
|
||||
static inline void
|
||||
Hacl_Impl_Curve25519_Field51_fadd(uint64_t *out, uint64_t *f1, uint64_t *f2)
|
||||
{
|
||||
uint64_t f10 = f1[0U];
|
||||
uint64_t f20 = f2[0U];
|
||||
uint64_t f11 = f1[1U];
|
||||
uint64_t f21 = f2[1U];
|
||||
uint64_t f12 = f1[2U];
|
||||
uint64_t f22 = f2[2U];
|
||||
uint64_t f13 = f1[3U];
|
||||
uint64_t f23 = f2[3U];
|
||||
uint64_t f14 = f1[4U];
|
||||
uint64_t f24 = f2[4U];
|
||||
out[0U] = f10 + f20;
|
||||
out[1U] = f11 + f21;
|
||||
out[2U] = f12 + f22;
|
||||
out[3U] = f13 + f23;
|
||||
out[4U] = f14 + f24;
|
||||
}
|
||||
|
||||
static inline void
|
||||
Hacl_Impl_Curve25519_Field51_fsub(uint64_t *out, uint64_t *f1, uint64_t *f2)
|
||||
{
|
||||
uint64_t f10 = f1[0U];
|
||||
uint64_t f20 = f2[0U];
|
||||
uint64_t f11 = f1[1U];
|
||||
uint64_t f21 = f2[1U];
|
||||
uint64_t f12 = f1[2U];
|
||||
uint64_t f22 = f2[2U];
|
||||
uint64_t f13 = f1[3U];
|
||||
uint64_t f23 = f2[3U];
|
||||
uint64_t f14 = f1[4U];
|
||||
uint64_t f24 = f2[4U];
|
||||
out[0U] = f10 + (uint64_t)0x3fffffffffff68U - f20;
|
||||
out[1U] = f11 + (uint64_t)0x3ffffffffffff8U - f21;
|
||||
out[2U] = f12 + (uint64_t)0x3ffffffffffff8U - f22;
|
||||
out[3U] = f13 + (uint64_t)0x3ffffffffffff8U - f23;
|
||||
out[4U] = f14 + (uint64_t)0x3ffffffffffff8U - f24;
|
||||
}
|
||||
|
||||
static inline void
|
||||
Hacl_Impl_Curve25519_Field51_fmul(
|
||||
uint64_t *out,
|
||||
uint64_t *f1,
|
||||
uint64_t *f2,
|
||||
FStar_UInt128_uint128 *uu___)
|
||||
{
|
||||
uint64_t f10 = f1[0U];
|
||||
uint64_t f11 = f1[1U];
|
||||
uint64_t f12 = f1[2U];
|
||||
uint64_t f13 = f1[3U];
|
||||
uint64_t f14 = f1[4U];
|
||||
uint64_t f20 = f2[0U];
|
||||
uint64_t f21 = f2[1U];
|
||||
uint64_t f22 = f2[2U];
|
||||
uint64_t f23 = f2[3U];
|
||||
uint64_t f24 = f2[4U];
|
||||
uint64_t tmp1 = f21 * (uint64_t)19U;
|
||||
uint64_t tmp2 = f22 * (uint64_t)19U;
|
||||
uint64_t tmp3 = f23 * (uint64_t)19U;
|
||||
uint64_t tmp4 = f24 * (uint64_t)19U;
|
||||
FStar_UInt128_uint128 o00 = FStar_UInt128_mul_wide(f10, f20);
|
||||
FStar_UInt128_uint128 o10 = FStar_UInt128_mul_wide(f10, f21);
|
||||
FStar_UInt128_uint128 o20 = FStar_UInt128_mul_wide(f10, f22);
|
||||
FStar_UInt128_uint128 o30 = FStar_UInt128_mul_wide(f10, f23);
|
||||
FStar_UInt128_uint128 o40 = FStar_UInt128_mul_wide(f10, f24);
|
||||
FStar_UInt128_uint128 o01 = FStar_UInt128_add(o00, FStar_UInt128_mul_wide(f11, tmp4));
|
||||
FStar_UInt128_uint128 o11 = FStar_UInt128_add(o10, FStar_UInt128_mul_wide(f11, f20));
|
||||
FStar_UInt128_uint128 o21 = FStar_UInt128_add(o20, FStar_UInt128_mul_wide(f11, f21));
|
||||
FStar_UInt128_uint128 o31 = FStar_UInt128_add(o30, FStar_UInt128_mul_wide(f11, f22));
|
||||
FStar_UInt128_uint128 o41 = FStar_UInt128_add(o40, FStar_UInt128_mul_wide(f11, f23));
|
||||
FStar_UInt128_uint128 o02 = FStar_UInt128_add(o01, FStar_UInt128_mul_wide(f12, tmp3));
|
||||
FStar_UInt128_uint128 o12 = FStar_UInt128_add(o11, FStar_UInt128_mul_wide(f12, tmp4));
|
||||
FStar_UInt128_uint128 o22 = FStar_UInt128_add(o21, FStar_UInt128_mul_wide(f12, f20));
|
||||
FStar_UInt128_uint128 o32 = FStar_UInt128_add(o31, FStar_UInt128_mul_wide(f12, f21));
|
||||
FStar_UInt128_uint128 o42 = FStar_UInt128_add(o41, FStar_UInt128_mul_wide(f12, f22));
|
||||
FStar_UInt128_uint128 o03 = FStar_UInt128_add(o02, FStar_UInt128_mul_wide(f13, tmp2));
|
||||
FStar_UInt128_uint128 o13 = FStar_UInt128_add(o12, FStar_UInt128_mul_wide(f13, tmp3));
|
||||
FStar_UInt128_uint128 o23 = FStar_UInt128_add(o22, FStar_UInt128_mul_wide(f13, tmp4));
|
||||
FStar_UInt128_uint128 o33 = FStar_UInt128_add(o32, FStar_UInt128_mul_wide(f13, f20));
|
||||
FStar_UInt128_uint128 o43 = FStar_UInt128_add(o42, FStar_UInt128_mul_wide(f13, f21));
|
||||
FStar_UInt128_uint128 o04 = FStar_UInt128_add(o03, FStar_UInt128_mul_wide(f14, tmp1));
|
||||
FStar_UInt128_uint128 o14 = FStar_UInt128_add(o13, FStar_UInt128_mul_wide(f14, tmp2));
|
||||
FStar_UInt128_uint128 o24 = FStar_UInt128_add(o23, FStar_UInt128_mul_wide(f14, tmp3));
|
||||
FStar_UInt128_uint128 o34 = FStar_UInt128_add(o33, FStar_UInt128_mul_wide(f14, tmp4));
|
||||
FStar_UInt128_uint128 o44 = FStar_UInt128_add(o43, FStar_UInt128_mul_wide(f14, f20));
|
||||
FStar_UInt128_uint128 tmp_w0 = o04;
|
||||
FStar_UInt128_uint128 tmp_w1 = o14;
|
||||
FStar_UInt128_uint128 tmp_w2 = o24;
|
||||
FStar_UInt128_uint128 tmp_w3 = o34;
|
||||
FStar_UInt128_uint128 tmp_w4 = o44;
|
||||
FStar_UInt128_uint128
|
||||
l_ = FStar_UInt128_add(tmp_w0, FStar_UInt128_uint64_to_uint128((uint64_t)0U));
|
||||
uint64_t tmp01 = FStar_UInt128_uint128_to_uint64(l_) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c0 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_, (uint32_t)51U));
|
||||
FStar_UInt128_uint128 l_0 = FStar_UInt128_add(tmp_w1, FStar_UInt128_uint64_to_uint128(c0));
|
||||
uint64_t tmp11 = FStar_UInt128_uint128_to_uint64(l_0) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c1 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_0, (uint32_t)51U));
|
||||
FStar_UInt128_uint128 l_1 = FStar_UInt128_add(tmp_w2, FStar_UInt128_uint64_to_uint128(c1));
|
||||
uint64_t tmp21 = FStar_UInt128_uint128_to_uint64(l_1) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c2 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_1, (uint32_t)51U));
|
||||
FStar_UInt128_uint128 l_2 = FStar_UInt128_add(tmp_w3, FStar_UInt128_uint64_to_uint128(c2));
|
||||
uint64_t tmp31 = FStar_UInt128_uint128_to_uint64(l_2) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c3 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_2, (uint32_t)51U));
|
||||
FStar_UInt128_uint128 l_3 = FStar_UInt128_add(tmp_w4, FStar_UInt128_uint64_to_uint128(c3));
|
||||
uint64_t tmp41 = FStar_UInt128_uint128_to_uint64(l_3) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c4 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_3, (uint32_t)51U));
|
||||
uint64_t l_4 = tmp01 + c4 * (uint64_t)19U;
|
||||
uint64_t tmp0_ = l_4 & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c5 = l_4 >> (uint32_t)51U;
|
||||
uint64_t o0 = tmp0_;
|
||||
uint64_t o1 = tmp11 + c5;
|
||||
uint64_t o2 = tmp21;
|
||||
uint64_t o3 = tmp31;
|
||||
uint64_t o4 = tmp41;
|
||||
out[0U] = o0;
|
||||
out[1U] = o1;
|
||||
out[2U] = o2;
|
||||
out[3U] = o3;
|
||||
out[4U] = o4;
|
||||
}
|
||||
|
||||
static inline void
|
||||
Hacl_Impl_Curve25519_Field51_fmul2(
|
||||
uint64_t *out,
|
||||
uint64_t *f1,
|
||||
uint64_t *f2,
|
||||
FStar_UInt128_uint128 *uu___)
|
||||
{
|
||||
uint64_t f10 = f1[0U];
|
||||
uint64_t f11 = f1[1U];
|
||||
uint64_t f12 = f1[2U];
|
||||
uint64_t f13 = f1[3U];
|
||||
uint64_t f14 = f1[4U];
|
||||
uint64_t f20 = f2[0U];
|
||||
uint64_t f21 = f2[1U];
|
||||
uint64_t f22 = f2[2U];
|
||||
uint64_t f23 = f2[3U];
|
||||
uint64_t f24 = f2[4U];
|
||||
uint64_t f30 = f1[5U];
|
||||
uint64_t f31 = f1[6U];
|
||||
uint64_t f32 = f1[7U];
|
||||
uint64_t f33 = f1[8U];
|
||||
uint64_t f34 = f1[9U];
|
||||
uint64_t f40 = f2[5U];
|
||||
uint64_t f41 = f2[6U];
|
||||
uint64_t f42 = f2[7U];
|
||||
uint64_t f43 = f2[8U];
|
||||
uint64_t f44 = f2[9U];
|
||||
uint64_t tmp11 = f21 * (uint64_t)19U;
|
||||
uint64_t tmp12 = f22 * (uint64_t)19U;
|
||||
uint64_t tmp13 = f23 * (uint64_t)19U;
|
||||
uint64_t tmp14 = f24 * (uint64_t)19U;
|
||||
uint64_t tmp21 = f41 * (uint64_t)19U;
|
||||
uint64_t tmp22 = f42 * (uint64_t)19U;
|
||||
uint64_t tmp23 = f43 * (uint64_t)19U;
|
||||
uint64_t tmp24 = f44 * (uint64_t)19U;
|
||||
FStar_UInt128_uint128 o00 = FStar_UInt128_mul_wide(f10, f20);
|
||||
FStar_UInt128_uint128 o15 = FStar_UInt128_mul_wide(f10, f21);
|
||||
FStar_UInt128_uint128 o25 = FStar_UInt128_mul_wide(f10, f22);
|
||||
FStar_UInt128_uint128 o30 = FStar_UInt128_mul_wide(f10, f23);
|
||||
FStar_UInt128_uint128 o40 = FStar_UInt128_mul_wide(f10, f24);
|
||||
FStar_UInt128_uint128 o010 = FStar_UInt128_add(o00, FStar_UInt128_mul_wide(f11, tmp14));
|
||||
FStar_UInt128_uint128 o110 = FStar_UInt128_add(o15, FStar_UInt128_mul_wide(f11, f20));
|
||||
FStar_UInt128_uint128 o210 = FStar_UInt128_add(o25, FStar_UInt128_mul_wide(f11, f21));
|
||||
FStar_UInt128_uint128 o310 = FStar_UInt128_add(o30, FStar_UInt128_mul_wide(f11, f22));
|
||||
FStar_UInt128_uint128 o410 = FStar_UInt128_add(o40, FStar_UInt128_mul_wide(f11, f23));
|
||||
FStar_UInt128_uint128 o020 = FStar_UInt128_add(o010, FStar_UInt128_mul_wide(f12, tmp13));
|
||||
FStar_UInt128_uint128 o120 = FStar_UInt128_add(o110, FStar_UInt128_mul_wide(f12, tmp14));
|
||||
FStar_UInt128_uint128 o220 = FStar_UInt128_add(o210, FStar_UInt128_mul_wide(f12, f20));
|
||||
FStar_UInt128_uint128 o320 = FStar_UInt128_add(o310, FStar_UInt128_mul_wide(f12, f21));
|
||||
FStar_UInt128_uint128 o420 = FStar_UInt128_add(o410, FStar_UInt128_mul_wide(f12, f22));
|
||||
FStar_UInt128_uint128 o030 = FStar_UInt128_add(o020, FStar_UInt128_mul_wide(f13, tmp12));
|
||||
FStar_UInt128_uint128 o130 = FStar_UInt128_add(o120, FStar_UInt128_mul_wide(f13, tmp13));
|
||||
FStar_UInt128_uint128 o230 = FStar_UInt128_add(o220, FStar_UInt128_mul_wide(f13, tmp14));
|
||||
FStar_UInt128_uint128 o330 = FStar_UInt128_add(o320, FStar_UInt128_mul_wide(f13, f20));
|
||||
FStar_UInt128_uint128 o430 = FStar_UInt128_add(o420, FStar_UInt128_mul_wide(f13, f21));
|
||||
FStar_UInt128_uint128 o040 = FStar_UInt128_add(o030, FStar_UInt128_mul_wide(f14, tmp11));
|
||||
FStar_UInt128_uint128 o140 = FStar_UInt128_add(o130, FStar_UInt128_mul_wide(f14, tmp12));
|
||||
FStar_UInt128_uint128 o240 = FStar_UInt128_add(o230, FStar_UInt128_mul_wide(f14, tmp13));
|
||||
FStar_UInt128_uint128 o340 = FStar_UInt128_add(o330, FStar_UInt128_mul_wide(f14, tmp14));
|
||||
FStar_UInt128_uint128 o440 = FStar_UInt128_add(o430, FStar_UInt128_mul_wide(f14, f20));
|
||||
FStar_UInt128_uint128 tmp_w10 = o040;
|
||||
FStar_UInt128_uint128 tmp_w11 = o140;
|
||||
FStar_UInt128_uint128 tmp_w12 = o240;
|
||||
FStar_UInt128_uint128 tmp_w13 = o340;
|
||||
FStar_UInt128_uint128 tmp_w14 = o440;
|
||||
FStar_UInt128_uint128 o0 = FStar_UInt128_mul_wide(f30, f40);
|
||||
FStar_UInt128_uint128 o1 = FStar_UInt128_mul_wide(f30, f41);
|
||||
FStar_UInt128_uint128 o2 = FStar_UInt128_mul_wide(f30, f42);
|
||||
FStar_UInt128_uint128 o3 = FStar_UInt128_mul_wide(f30, f43);
|
||||
FStar_UInt128_uint128 o4 = FStar_UInt128_mul_wide(f30, f44);
|
||||
FStar_UInt128_uint128 o01 = FStar_UInt128_add(o0, FStar_UInt128_mul_wide(f31, tmp24));
|
||||
FStar_UInt128_uint128 o111 = FStar_UInt128_add(o1, FStar_UInt128_mul_wide(f31, f40));
|
||||
FStar_UInt128_uint128 o211 = FStar_UInt128_add(o2, FStar_UInt128_mul_wide(f31, f41));
|
||||
FStar_UInt128_uint128 o31 = FStar_UInt128_add(o3, FStar_UInt128_mul_wide(f31, f42));
|
||||
FStar_UInt128_uint128 o41 = FStar_UInt128_add(o4, FStar_UInt128_mul_wide(f31, f43));
|
||||
FStar_UInt128_uint128 o02 = FStar_UInt128_add(o01, FStar_UInt128_mul_wide(f32, tmp23));
|
||||
FStar_UInt128_uint128 o121 = FStar_UInt128_add(o111, FStar_UInt128_mul_wide(f32, tmp24));
|
||||
FStar_UInt128_uint128 o221 = FStar_UInt128_add(o211, FStar_UInt128_mul_wide(f32, f40));
|
||||
FStar_UInt128_uint128 o32 = FStar_UInt128_add(o31, FStar_UInt128_mul_wide(f32, f41));
|
||||
FStar_UInt128_uint128 o42 = FStar_UInt128_add(o41, FStar_UInt128_mul_wide(f32, f42));
|
||||
FStar_UInt128_uint128 o03 = FStar_UInt128_add(o02, FStar_UInt128_mul_wide(f33, tmp22));
|
||||
FStar_UInt128_uint128 o131 = FStar_UInt128_add(o121, FStar_UInt128_mul_wide(f33, tmp23));
|
||||
FStar_UInt128_uint128 o231 = FStar_UInt128_add(o221, FStar_UInt128_mul_wide(f33, tmp24));
|
||||
FStar_UInt128_uint128 o33 = FStar_UInt128_add(o32, FStar_UInt128_mul_wide(f33, f40));
|
||||
FStar_UInt128_uint128 o43 = FStar_UInt128_add(o42, FStar_UInt128_mul_wide(f33, f41));
|
||||
FStar_UInt128_uint128 o04 = FStar_UInt128_add(o03, FStar_UInt128_mul_wide(f34, tmp21));
|
||||
FStar_UInt128_uint128 o141 = FStar_UInt128_add(o131, FStar_UInt128_mul_wide(f34, tmp22));
|
||||
FStar_UInt128_uint128 o241 = FStar_UInt128_add(o231, FStar_UInt128_mul_wide(f34, tmp23));
|
||||
FStar_UInt128_uint128 o34 = FStar_UInt128_add(o33, FStar_UInt128_mul_wide(f34, tmp24));
|
||||
FStar_UInt128_uint128 o44 = FStar_UInt128_add(o43, FStar_UInt128_mul_wide(f34, f40));
|
||||
FStar_UInt128_uint128 tmp_w20 = o04;
|
||||
FStar_UInt128_uint128 tmp_w21 = o141;
|
||||
FStar_UInt128_uint128 tmp_w22 = o241;
|
||||
FStar_UInt128_uint128 tmp_w23 = o34;
|
||||
FStar_UInt128_uint128 tmp_w24 = o44;
|
||||
FStar_UInt128_uint128
|
||||
l_ = FStar_UInt128_add(tmp_w10, FStar_UInt128_uint64_to_uint128((uint64_t)0U));
|
||||
uint64_t tmp00 = FStar_UInt128_uint128_to_uint64(l_) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c00 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_, (uint32_t)51U));
|
||||
FStar_UInt128_uint128 l_0 = FStar_UInt128_add(tmp_w11, FStar_UInt128_uint64_to_uint128(c00));
|
||||
uint64_t tmp10 = FStar_UInt128_uint128_to_uint64(l_0) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c10 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_0, (uint32_t)51U));
|
||||
FStar_UInt128_uint128 l_1 = FStar_UInt128_add(tmp_w12, FStar_UInt128_uint64_to_uint128(c10));
|
||||
uint64_t tmp20 = FStar_UInt128_uint128_to_uint64(l_1) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c20 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_1, (uint32_t)51U));
|
||||
FStar_UInt128_uint128 l_2 = FStar_UInt128_add(tmp_w13, FStar_UInt128_uint64_to_uint128(c20));
|
||||
uint64_t tmp30 = FStar_UInt128_uint128_to_uint64(l_2) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c30 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_2, (uint32_t)51U));
|
||||
FStar_UInt128_uint128 l_3 = FStar_UInt128_add(tmp_w14, FStar_UInt128_uint64_to_uint128(c30));
|
||||
uint64_t tmp40 = FStar_UInt128_uint128_to_uint64(l_3) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c40 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_3, (uint32_t)51U));
|
||||
uint64_t l_4 = tmp00 + c40 * (uint64_t)19U;
|
||||
uint64_t tmp0_ = l_4 & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c50 = l_4 >> (uint32_t)51U;
|
||||
uint64_t o100 = tmp0_;
|
||||
uint64_t o112 = tmp10 + c50;
|
||||
uint64_t o122 = tmp20;
|
||||
uint64_t o132 = tmp30;
|
||||
uint64_t o142 = tmp40;
|
||||
FStar_UInt128_uint128
|
||||
l_5 = FStar_UInt128_add(tmp_w20, FStar_UInt128_uint64_to_uint128((uint64_t)0U));
|
||||
uint64_t tmp0 = FStar_UInt128_uint128_to_uint64(l_5) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c0 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_5, (uint32_t)51U));
|
||||
FStar_UInt128_uint128 l_6 = FStar_UInt128_add(tmp_w21, FStar_UInt128_uint64_to_uint128(c0));
|
||||
uint64_t tmp1 = FStar_UInt128_uint128_to_uint64(l_6) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c1 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_6, (uint32_t)51U));
|
||||
FStar_UInt128_uint128 l_7 = FStar_UInt128_add(tmp_w22, FStar_UInt128_uint64_to_uint128(c1));
|
||||
uint64_t tmp2 = FStar_UInt128_uint128_to_uint64(l_7) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c2 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_7, (uint32_t)51U));
|
||||
FStar_UInt128_uint128 l_8 = FStar_UInt128_add(tmp_w23, FStar_UInt128_uint64_to_uint128(c2));
|
||||
uint64_t tmp3 = FStar_UInt128_uint128_to_uint64(l_8) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c3 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_8, (uint32_t)51U));
|
||||
FStar_UInt128_uint128 l_9 = FStar_UInt128_add(tmp_w24, FStar_UInt128_uint64_to_uint128(c3));
|
||||
uint64_t tmp4 = FStar_UInt128_uint128_to_uint64(l_9) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c4 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_9, (uint32_t)51U));
|
||||
uint64_t l_10 = tmp0 + c4 * (uint64_t)19U;
|
||||
uint64_t tmp0_0 = l_10 & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c5 = l_10 >> (uint32_t)51U;
|
||||
uint64_t o200 = tmp0_0;
|
||||
uint64_t o212 = tmp1 + c5;
|
||||
uint64_t o222 = tmp2;
|
||||
uint64_t o232 = tmp3;
|
||||
uint64_t o242 = tmp4;
|
||||
uint64_t o10 = o100;
|
||||
uint64_t o11 = o112;
|
||||
uint64_t o12 = o122;
|
||||
uint64_t o13 = o132;
|
||||
uint64_t o14 = o142;
|
||||
uint64_t o20 = o200;
|
||||
uint64_t o21 = o212;
|
||||
uint64_t o22 = o222;
|
||||
uint64_t o23 = o232;
|
||||
uint64_t o24 = o242;
|
||||
out[0U] = o10;
|
||||
out[1U] = o11;
|
||||
out[2U] = o12;
|
||||
out[3U] = o13;
|
||||
out[4U] = o14;
|
||||
out[5U] = o20;
|
||||
out[6U] = o21;
|
||||
out[7U] = o22;
|
||||
out[8U] = o23;
|
||||
out[9U] = o24;
|
||||
}
|
||||
|
||||
static inline void
|
||||
Hacl_Impl_Curve25519_Field51_fmul1(uint64_t *out, uint64_t *f1, uint64_t f2)
|
||||
{
|
||||
uint64_t f10 = f1[0U];
|
||||
uint64_t f11 = f1[1U];
|
||||
uint64_t f12 = f1[2U];
|
||||
uint64_t f13 = f1[3U];
|
||||
uint64_t f14 = f1[4U];
|
||||
FStar_UInt128_uint128 tmp_w0 = FStar_UInt128_mul_wide(f2, f10);
|
||||
FStar_UInt128_uint128 tmp_w1 = FStar_UInt128_mul_wide(f2, f11);
|
||||
FStar_UInt128_uint128 tmp_w2 = FStar_UInt128_mul_wide(f2, f12);
|
||||
FStar_UInt128_uint128 tmp_w3 = FStar_UInt128_mul_wide(f2, f13);
|
||||
FStar_UInt128_uint128 tmp_w4 = FStar_UInt128_mul_wide(f2, f14);
|
||||
FStar_UInt128_uint128
|
||||
l_ = FStar_UInt128_add(tmp_w0, FStar_UInt128_uint64_to_uint128((uint64_t)0U));
|
||||
uint64_t tmp0 = FStar_UInt128_uint128_to_uint64(l_) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c0 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_, (uint32_t)51U));
|
||||
FStar_UInt128_uint128 l_0 = FStar_UInt128_add(tmp_w1, FStar_UInt128_uint64_to_uint128(c0));
|
||||
uint64_t tmp1 = FStar_UInt128_uint128_to_uint64(l_0) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c1 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_0, (uint32_t)51U));
|
||||
FStar_UInt128_uint128 l_1 = FStar_UInt128_add(tmp_w2, FStar_UInt128_uint64_to_uint128(c1));
|
||||
uint64_t tmp2 = FStar_UInt128_uint128_to_uint64(l_1) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c2 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_1, (uint32_t)51U));
|
||||
FStar_UInt128_uint128 l_2 = FStar_UInt128_add(tmp_w3, FStar_UInt128_uint64_to_uint128(c2));
|
||||
uint64_t tmp3 = FStar_UInt128_uint128_to_uint64(l_2) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c3 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_2, (uint32_t)51U));
|
||||
FStar_UInt128_uint128 l_3 = FStar_UInt128_add(tmp_w4, FStar_UInt128_uint64_to_uint128(c3));
|
||||
uint64_t tmp4 = FStar_UInt128_uint128_to_uint64(l_3) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c4 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_3, (uint32_t)51U));
|
||||
uint64_t l_4 = tmp0 + c4 * (uint64_t)19U;
|
||||
uint64_t tmp0_ = l_4 & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c5 = l_4 >> (uint32_t)51U;
|
||||
uint64_t o0 = tmp0_;
|
||||
uint64_t o1 = tmp1 + c5;
|
||||
uint64_t o2 = tmp2;
|
||||
uint64_t o3 = tmp3;
|
||||
uint64_t o4 = tmp4;
|
||||
out[0U] = o0;
|
||||
out[1U] = o1;
|
||||
out[2U] = o2;
|
||||
out[3U] = o3;
|
||||
out[4U] = o4;
|
||||
}
|
||||
|
||||
static inline void
|
||||
Hacl_Impl_Curve25519_Field51_fsqr(uint64_t *out, uint64_t *f, FStar_UInt128_uint128 *uu___)
|
||||
{
|
||||
uint64_t f0 = f[0U];
|
||||
uint64_t f1 = f[1U];
|
||||
uint64_t f2 = f[2U];
|
||||
uint64_t f3 = f[3U];
|
||||
uint64_t f4 = f[4U];
|
||||
uint64_t d0 = (uint64_t)2U * f0;
|
||||
uint64_t d1 = (uint64_t)2U * f1;
|
||||
uint64_t d2 = (uint64_t)38U * f2;
|
||||
uint64_t d3 = (uint64_t)19U * f3;
|
||||
uint64_t d419 = (uint64_t)19U * f4;
|
||||
uint64_t d4 = (uint64_t)2U * d419;
|
||||
FStar_UInt128_uint128
|
||||
s0 =
|
||||
FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_mul_wide(f0, f0),
|
||||
FStar_UInt128_mul_wide(d4, f1)),
|
||||
FStar_UInt128_mul_wide(d2, f3));
|
||||
FStar_UInt128_uint128
|
||||
s1 =
|
||||
FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_mul_wide(d0, f1),
|
||||
FStar_UInt128_mul_wide(d4, f2)),
|
||||
FStar_UInt128_mul_wide(d3, f3));
|
||||
FStar_UInt128_uint128
|
||||
s2 =
|
||||
FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_mul_wide(d0, f2),
|
||||
FStar_UInt128_mul_wide(f1, f1)),
|
||||
FStar_UInt128_mul_wide(d4, f3));
|
||||
FStar_UInt128_uint128
|
||||
s3 =
|
||||
FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_mul_wide(d0, f3),
|
||||
FStar_UInt128_mul_wide(d1, f2)),
|
||||
FStar_UInt128_mul_wide(f4, d419));
|
||||
FStar_UInt128_uint128
|
||||
s4 =
|
||||
FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_mul_wide(d0, f4),
|
||||
FStar_UInt128_mul_wide(d1, f3)),
|
||||
FStar_UInt128_mul_wide(f2, f2));
|
||||
FStar_UInt128_uint128 o00 = s0;
|
||||
FStar_UInt128_uint128 o10 = s1;
|
||||
FStar_UInt128_uint128 o20 = s2;
|
||||
FStar_UInt128_uint128 o30 = s3;
|
||||
FStar_UInt128_uint128 o40 = s4;
|
||||
FStar_UInt128_uint128
|
||||
l_ = FStar_UInt128_add(o00, FStar_UInt128_uint64_to_uint128((uint64_t)0U));
|
||||
uint64_t tmp0 = FStar_UInt128_uint128_to_uint64(l_) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c0 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_, (uint32_t)51U));
|
||||
FStar_UInt128_uint128 l_0 = FStar_UInt128_add(o10, FStar_UInt128_uint64_to_uint128(c0));
|
||||
uint64_t tmp1 = FStar_UInt128_uint128_to_uint64(l_0) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c1 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_0, (uint32_t)51U));
|
||||
FStar_UInt128_uint128 l_1 = FStar_UInt128_add(o20, FStar_UInt128_uint64_to_uint128(c1));
|
||||
uint64_t tmp2 = FStar_UInt128_uint128_to_uint64(l_1) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c2 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_1, (uint32_t)51U));
|
||||
FStar_UInt128_uint128 l_2 = FStar_UInt128_add(o30, FStar_UInt128_uint64_to_uint128(c2));
|
||||
uint64_t tmp3 = FStar_UInt128_uint128_to_uint64(l_2) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c3 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_2, (uint32_t)51U));
|
||||
FStar_UInt128_uint128 l_3 = FStar_UInt128_add(o40, FStar_UInt128_uint64_to_uint128(c3));
|
||||
uint64_t tmp4 = FStar_UInt128_uint128_to_uint64(l_3) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c4 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_3, (uint32_t)51U));
|
||||
uint64_t l_4 = tmp0 + c4 * (uint64_t)19U;
|
||||
uint64_t tmp0_ = l_4 & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c5 = l_4 >> (uint32_t)51U;
|
||||
uint64_t o0 = tmp0_;
|
||||
uint64_t o1 = tmp1 + c5;
|
||||
uint64_t o2 = tmp2;
|
||||
uint64_t o3 = tmp3;
|
||||
uint64_t o4 = tmp4;
|
||||
out[0U] = o0;
|
||||
out[1U] = o1;
|
||||
out[2U] = o2;
|
||||
out[3U] = o3;
|
||||
out[4U] = o4;
|
||||
}
|
||||
|
||||
static inline void
|
||||
Hacl_Impl_Curve25519_Field51_fsqr2(uint64_t *out, uint64_t *f, FStar_UInt128_uint128 *uu___)
|
||||
{
|
||||
uint64_t f10 = f[0U];
|
||||
uint64_t f11 = f[1U];
|
||||
uint64_t f12 = f[2U];
|
||||
uint64_t f13 = f[3U];
|
||||
uint64_t f14 = f[4U];
|
||||
uint64_t f20 = f[5U];
|
||||
uint64_t f21 = f[6U];
|
||||
uint64_t f22 = f[7U];
|
||||
uint64_t f23 = f[8U];
|
||||
uint64_t f24 = f[9U];
|
||||
uint64_t d00 = (uint64_t)2U * f10;
|
||||
uint64_t d10 = (uint64_t)2U * f11;
|
||||
uint64_t d20 = (uint64_t)38U * f12;
|
||||
uint64_t d30 = (uint64_t)19U * f13;
|
||||
uint64_t d4190 = (uint64_t)19U * f14;
|
||||
uint64_t d40 = (uint64_t)2U * d4190;
|
||||
FStar_UInt128_uint128
|
||||
s00 =
|
||||
FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_mul_wide(f10, f10),
|
||||
FStar_UInt128_mul_wide(d40, f11)),
|
||||
FStar_UInt128_mul_wide(d20, f13));
|
||||
FStar_UInt128_uint128
|
||||
s10 =
|
||||
FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_mul_wide(d00, f11),
|
||||
FStar_UInt128_mul_wide(d40, f12)),
|
||||
FStar_UInt128_mul_wide(d30, f13));
|
||||
FStar_UInt128_uint128
|
||||
s20 =
|
||||
FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_mul_wide(d00, f12),
|
||||
FStar_UInt128_mul_wide(f11, f11)),
|
||||
FStar_UInt128_mul_wide(d40, f13));
|
||||
FStar_UInt128_uint128
|
||||
s30 =
|
||||
FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_mul_wide(d00, f13),
|
||||
FStar_UInt128_mul_wide(d10, f12)),
|
||||
FStar_UInt128_mul_wide(f14, d4190));
|
||||
FStar_UInt128_uint128
|
||||
s40 =
|
||||
FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_mul_wide(d00, f14),
|
||||
FStar_UInt128_mul_wide(d10, f13)),
|
||||
FStar_UInt128_mul_wide(f12, f12));
|
||||
FStar_UInt128_uint128 o100 = s00;
|
||||
FStar_UInt128_uint128 o110 = s10;
|
||||
FStar_UInt128_uint128 o120 = s20;
|
||||
FStar_UInt128_uint128 o130 = s30;
|
||||
FStar_UInt128_uint128 o140 = s40;
|
||||
uint64_t d0 = (uint64_t)2U * f20;
|
||||
uint64_t d1 = (uint64_t)2U * f21;
|
||||
uint64_t d2 = (uint64_t)38U * f22;
|
||||
uint64_t d3 = (uint64_t)19U * f23;
|
||||
uint64_t d419 = (uint64_t)19U * f24;
|
||||
uint64_t d4 = (uint64_t)2U * d419;
|
||||
FStar_UInt128_uint128
|
||||
s0 =
|
||||
FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_mul_wide(f20, f20),
|
||||
FStar_UInt128_mul_wide(d4, f21)),
|
||||
FStar_UInt128_mul_wide(d2, f23));
|
||||
FStar_UInt128_uint128
|
||||
s1 =
|
||||
FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_mul_wide(d0, f21),
|
||||
FStar_UInt128_mul_wide(d4, f22)),
|
||||
FStar_UInt128_mul_wide(d3, f23));
|
||||
FStar_UInt128_uint128
|
||||
s2 =
|
||||
FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_mul_wide(d0, f22),
|
||||
FStar_UInt128_mul_wide(f21, f21)),
|
||||
FStar_UInt128_mul_wide(d4, f23));
|
||||
FStar_UInt128_uint128
|
||||
s3 =
|
||||
FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_mul_wide(d0, f23),
|
||||
FStar_UInt128_mul_wide(d1, f22)),
|
||||
FStar_UInt128_mul_wide(f24, d419));
|
||||
FStar_UInt128_uint128
|
||||
s4 =
|
||||
FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_mul_wide(d0, f24),
|
||||
FStar_UInt128_mul_wide(d1, f23)),
|
||||
FStar_UInt128_mul_wide(f22, f22));
|
||||
FStar_UInt128_uint128 o200 = s0;
|
||||
FStar_UInt128_uint128 o210 = s1;
|
||||
FStar_UInt128_uint128 o220 = s2;
|
||||
FStar_UInt128_uint128 o230 = s3;
|
||||
FStar_UInt128_uint128 o240 = s4;
|
||||
FStar_UInt128_uint128
|
||||
l_ = FStar_UInt128_add(o100, FStar_UInt128_uint64_to_uint128((uint64_t)0U));
|
||||
uint64_t tmp00 = FStar_UInt128_uint128_to_uint64(l_) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c00 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_, (uint32_t)51U));
|
||||
FStar_UInt128_uint128 l_0 = FStar_UInt128_add(o110, FStar_UInt128_uint64_to_uint128(c00));
|
||||
uint64_t tmp10 = FStar_UInt128_uint128_to_uint64(l_0) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c10 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_0, (uint32_t)51U));
|
||||
FStar_UInt128_uint128 l_1 = FStar_UInt128_add(o120, FStar_UInt128_uint64_to_uint128(c10));
|
||||
uint64_t tmp20 = FStar_UInt128_uint128_to_uint64(l_1) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c20 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_1, (uint32_t)51U));
|
||||
FStar_UInt128_uint128 l_2 = FStar_UInt128_add(o130, FStar_UInt128_uint64_to_uint128(c20));
|
||||
uint64_t tmp30 = FStar_UInt128_uint128_to_uint64(l_2) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c30 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_2, (uint32_t)51U));
|
||||
FStar_UInt128_uint128 l_3 = FStar_UInt128_add(o140, FStar_UInt128_uint64_to_uint128(c30));
|
||||
uint64_t tmp40 = FStar_UInt128_uint128_to_uint64(l_3) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c40 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_3, (uint32_t)51U));
|
||||
uint64_t l_4 = tmp00 + c40 * (uint64_t)19U;
|
||||
uint64_t tmp0_ = l_4 & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c50 = l_4 >> (uint32_t)51U;
|
||||
uint64_t o101 = tmp0_;
|
||||
uint64_t o111 = tmp10 + c50;
|
||||
uint64_t o121 = tmp20;
|
||||
uint64_t o131 = tmp30;
|
||||
uint64_t o141 = tmp40;
|
||||
FStar_UInt128_uint128
|
||||
l_5 = FStar_UInt128_add(o200, FStar_UInt128_uint64_to_uint128((uint64_t)0U));
|
||||
uint64_t tmp0 = FStar_UInt128_uint128_to_uint64(l_5) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c0 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_5, (uint32_t)51U));
|
||||
FStar_UInt128_uint128 l_6 = FStar_UInt128_add(o210, FStar_UInt128_uint64_to_uint128(c0));
|
||||
uint64_t tmp1 = FStar_UInt128_uint128_to_uint64(l_6) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c1 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_6, (uint32_t)51U));
|
||||
FStar_UInt128_uint128 l_7 = FStar_UInt128_add(o220, FStar_UInt128_uint64_to_uint128(c1));
|
||||
uint64_t tmp2 = FStar_UInt128_uint128_to_uint64(l_7) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c2 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_7, (uint32_t)51U));
|
||||
FStar_UInt128_uint128 l_8 = FStar_UInt128_add(o230, FStar_UInt128_uint64_to_uint128(c2));
|
||||
uint64_t tmp3 = FStar_UInt128_uint128_to_uint64(l_8) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c3 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_8, (uint32_t)51U));
|
||||
FStar_UInt128_uint128 l_9 = FStar_UInt128_add(o240, FStar_UInt128_uint64_to_uint128(c3));
|
||||
uint64_t tmp4 = FStar_UInt128_uint128_to_uint64(l_9) & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c4 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(l_9, (uint32_t)51U));
|
||||
uint64_t l_10 = tmp0 + c4 * (uint64_t)19U;
|
||||
uint64_t tmp0_0 = l_10 & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c5 = l_10 >> (uint32_t)51U;
|
||||
uint64_t o201 = tmp0_0;
|
||||
uint64_t o211 = tmp1 + c5;
|
||||
uint64_t o221 = tmp2;
|
||||
uint64_t o231 = tmp3;
|
||||
uint64_t o241 = tmp4;
|
||||
uint64_t o10 = o101;
|
||||
uint64_t o11 = o111;
|
||||
uint64_t o12 = o121;
|
||||
uint64_t o13 = o131;
|
||||
uint64_t o14 = o141;
|
||||
uint64_t o20 = o201;
|
||||
uint64_t o21 = o211;
|
||||
uint64_t o22 = o221;
|
||||
uint64_t o23 = o231;
|
||||
uint64_t o24 = o241;
|
||||
out[0U] = o10;
|
||||
out[1U] = o11;
|
||||
out[2U] = o12;
|
||||
out[3U] = o13;
|
||||
out[4U] = o14;
|
||||
out[5U] = o20;
|
||||
out[6U] = o21;
|
||||
out[7U] = o22;
|
||||
out[8U] = o23;
|
||||
out[9U] = o24;
|
||||
}
|
||||
|
||||
static inline void
|
||||
Hacl_Impl_Curve25519_Field51_store_felem(uint64_t *u64s, uint64_t *f)
|
||||
{
|
||||
uint64_t f0 = f[0U];
|
||||
uint64_t f1 = f[1U];
|
||||
uint64_t f2 = f[2U];
|
||||
uint64_t f3 = f[3U];
|
||||
uint64_t f4 = f[4U];
|
||||
uint64_t l_ = f0 + (uint64_t)0U;
|
||||
uint64_t tmp0 = l_ & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c0 = l_ >> (uint32_t)51U;
|
||||
uint64_t l_0 = f1 + c0;
|
||||
uint64_t tmp1 = l_0 & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c1 = l_0 >> (uint32_t)51U;
|
||||
uint64_t l_1 = f2 + c1;
|
||||
uint64_t tmp2 = l_1 & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c2 = l_1 >> (uint32_t)51U;
|
||||
uint64_t l_2 = f3 + c2;
|
||||
uint64_t tmp3 = l_2 & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c3 = l_2 >> (uint32_t)51U;
|
||||
uint64_t l_3 = f4 + c3;
|
||||
uint64_t tmp4 = l_3 & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c4 = l_3 >> (uint32_t)51U;
|
||||
uint64_t l_4 = tmp0 + c4 * (uint64_t)19U;
|
||||
uint64_t tmp0_ = l_4 & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t c5 = l_4 >> (uint32_t)51U;
|
||||
uint64_t f01 = tmp0_;
|
||||
uint64_t f11 = tmp1 + c5;
|
||||
uint64_t f21 = tmp2;
|
||||
uint64_t f31 = tmp3;
|
||||
uint64_t f41 = tmp4;
|
||||
uint64_t m0 = FStar_UInt64_gte_mask(f01, (uint64_t)0x7ffffffffffedU);
|
||||
uint64_t m1 = FStar_UInt64_eq_mask(f11, (uint64_t)0x7ffffffffffffU);
|
||||
uint64_t m2 = FStar_UInt64_eq_mask(f21, (uint64_t)0x7ffffffffffffU);
|
||||
uint64_t m3 = FStar_UInt64_eq_mask(f31, (uint64_t)0x7ffffffffffffU);
|
||||
uint64_t m4 = FStar_UInt64_eq_mask(f41, (uint64_t)0x7ffffffffffffU);
|
||||
uint64_t mask = (((m0 & m1) & m2) & m3) & m4;
|
||||
uint64_t f0_ = f01 - (mask & (uint64_t)0x7ffffffffffedU);
|
||||
uint64_t f1_ = f11 - (mask & (uint64_t)0x7ffffffffffffU);
|
||||
uint64_t f2_ = f21 - (mask & (uint64_t)0x7ffffffffffffU);
|
||||
uint64_t f3_ = f31 - (mask & (uint64_t)0x7ffffffffffffU);
|
||||
uint64_t f4_ = f41 - (mask & (uint64_t)0x7ffffffffffffU);
|
||||
uint64_t f02 = f0_;
|
||||
uint64_t f12 = f1_;
|
||||
uint64_t f22 = f2_;
|
||||
uint64_t f32 = f3_;
|
||||
uint64_t f42 = f4_;
|
||||
uint64_t o00 = f02 | f12 << (uint32_t)51U;
|
||||
uint64_t o10 = f12 >> (uint32_t)13U | f22 << (uint32_t)38U;
|
||||
uint64_t o20 = f22 >> (uint32_t)26U | f32 << (uint32_t)25U;
|
||||
uint64_t o30 = f32 >> (uint32_t)39U | f42 << (uint32_t)12U;
|
||||
uint64_t o0 = o00;
|
||||
uint64_t o1 = o10;
|
||||
uint64_t o2 = o20;
|
||||
uint64_t o3 = o30;
|
||||
u64s[0U] = o0;
|
||||
u64s[1U] = o1;
|
||||
u64s[2U] = o2;
|
||||
u64s[3U] = o3;
|
||||
}
|
||||
|
||||
static inline void
|
||||
Hacl_Impl_Curve25519_Field51_cswap2(uint64_t bit, uint64_t *p1, uint64_t *p2)
|
||||
{
|
||||
uint64_t mask = (uint64_t)0U - bit;
|
||||
KRML_MAYBE_FOR10(i,
|
||||
(uint32_t)0U,
|
||||
(uint32_t)10U,
|
||||
(uint32_t)1U,
|
||||
uint64_t dummy = mask & (p1[i] ^ p2[i]);
|
||||
p1[i] = p1[i] ^ dummy;
|
||||
p2[i] = p2[i] ^ dummy;);
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#define __Hacl_Bignum25519_51_H_DEFINED
|
||||
#endif
|
||||
|
|
@ -1,270 +1,226 @@
|
|||
/* Copyright 2016-2018 INRIA and Microsoft Corporation
|
||||
/* MIT License
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* Copyright (c) 2016-2020 INRIA, CMU and Microsoft Corporation
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "Hacl_Chacha20.h"
|
||||
#include "internal/Hacl_Chacha20.h"
|
||||
|
||||
static void
|
||||
Hacl_Lib_LoadStore32_uint32s_from_le_bytes(uint32_t *output, uint8_t *input, uint32_t len)
|
||||
const uint32_t
|
||||
Hacl_Impl_Chacha20_Vec_chacha20_constants[4U] = { (uint32_t)0x61707865U, (uint32_t)0x3320646eU, (uint32_t)0x79622d32U, (uint32_t)0x6b206574U };
|
||||
|
||||
static inline void
|
||||
quarter_round(uint32_t *st, uint32_t a, uint32_t b, uint32_t c, uint32_t d)
|
||||
{
|
||||
for (uint32_t i = (uint32_t)0U; i < len; i = i + (uint32_t)1U) {
|
||||
uint8_t *x0 = input + (uint32_t)4U * i;
|
||||
uint32_t inputi = load32_le(x0);
|
||||
output[i] = inputi;
|
||||
}
|
||||
uint32_t sta = st[a];
|
||||
uint32_t stb0 = st[b];
|
||||
uint32_t std0 = st[d];
|
||||
uint32_t sta10 = sta + stb0;
|
||||
uint32_t std10 = std0 ^ sta10;
|
||||
uint32_t std2 = std10 << (uint32_t)16U | std10 >> (uint32_t)16U;
|
||||
st[a] = sta10;
|
||||
st[d] = std2;
|
||||
uint32_t sta0 = st[c];
|
||||
uint32_t stb1 = st[d];
|
||||
uint32_t std3 = st[b];
|
||||
uint32_t sta11 = sta0 + stb1;
|
||||
uint32_t std11 = std3 ^ sta11;
|
||||
uint32_t std20 = std11 << (uint32_t)12U | std11 >> (uint32_t)20U;
|
||||
st[c] = sta11;
|
||||
st[b] = std20;
|
||||
uint32_t sta2 = st[a];
|
||||
uint32_t stb2 = st[b];
|
||||
uint32_t std4 = st[d];
|
||||
uint32_t sta12 = sta2 + stb2;
|
||||
uint32_t std12 = std4 ^ sta12;
|
||||
uint32_t std21 = std12 << (uint32_t)8U | std12 >> (uint32_t)24U;
|
||||
st[a] = sta12;
|
||||
st[d] = std21;
|
||||
uint32_t sta3 = st[c];
|
||||
uint32_t stb = st[d];
|
||||
uint32_t std = st[b];
|
||||
uint32_t sta1 = sta3 + stb;
|
||||
uint32_t std1 = std ^ sta1;
|
||||
uint32_t std22 = std1 << (uint32_t)7U | std1 >> (uint32_t)25U;
|
||||
st[c] = sta1;
|
||||
st[b] = std22;
|
||||
}
|
||||
|
||||
static inline void
|
||||
double_round(uint32_t *st)
|
||||
{
|
||||
quarter_round(st, (uint32_t)0U, (uint32_t)4U, (uint32_t)8U, (uint32_t)12U);
|
||||
quarter_round(st, (uint32_t)1U, (uint32_t)5U, (uint32_t)9U, (uint32_t)13U);
|
||||
quarter_round(st, (uint32_t)2U, (uint32_t)6U, (uint32_t)10U, (uint32_t)14U);
|
||||
quarter_round(st, (uint32_t)3U, (uint32_t)7U, (uint32_t)11U, (uint32_t)15U);
|
||||
quarter_round(st, (uint32_t)0U, (uint32_t)5U, (uint32_t)10U, (uint32_t)15U);
|
||||
quarter_round(st, (uint32_t)1U, (uint32_t)6U, (uint32_t)11U, (uint32_t)12U);
|
||||
quarter_round(st, (uint32_t)2U, (uint32_t)7U, (uint32_t)8U, (uint32_t)13U);
|
||||
quarter_round(st, (uint32_t)3U, (uint32_t)4U, (uint32_t)9U, (uint32_t)14U);
|
||||
}
|
||||
|
||||
static inline void
|
||||
rounds(uint32_t *st)
|
||||
{
|
||||
double_round(st);
|
||||
double_round(st);
|
||||
double_round(st);
|
||||
double_round(st);
|
||||
double_round(st);
|
||||
double_round(st);
|
||||
double_round(st);
|
||||
double_round(st);
|
||||
double_round(st);
|
||||
double_round(st);
|
||||
}
|
||||
|
||||
static inline void
|
||||
chacha20_core(uint32_t *k, uint32_t *ctx, uint32_t ctr)
|
||||
{
|
||||
memcpy(k, ctx, (uint32_t)16U * sizeof(uint32_t));
|
||||
uint32_t ctr_u32 = ctr;
|
||||
k[12U] = k[12U] + ctr_u32;
|
||||
rounds(k);
|
||||
KRML_MAYBE_FOR16(i,
|
||||
(uint32_t)0U,
|
||||
(uint32_t)16U,
|
||||
(uint32_t)1U,
|
||||
uint32_t *os = k;
|
||||
uint32_t x = k[i] + ctx[i];
|
||||
os[i] = x;);
|
||||
k[12U] = k[12U] + ctr_u32;
|
||||
}
|
||||
|
||||
static const uint32_t
|
||||
chacha20_constants[4U] = { (uint32_t)0x61707865U, (uint32_t)0x3320646eU, (uint32_t)0x79622d32U, (uint32_t)0x6b206574U };
|
||||
|
||||
void
|
||||
Hacl_Impl_Chacha20_chacha20_init(uint32_t *ctx, uint8_t *k, uint8_t *n, uint32_t ctr)
|
||||
{
|
||||
KRML_MAYBE_FOR4(i,
|
||||
(uint32_t)0U,
|
||||
(uint32_t)4U,
|
||||
(uint32_t)1U,
|
||||
uint32_t *os = ctx;
|
||||
uint32_t x = chacha20_constants[i];
|
||||
os[i] = x;);
|
||||
KRML_MAYBE_FOR8(i,
|
||||
(uint32_t)0U,
|
||||
(uint32_t)8U,
|
||||
(uint32_t)1U,
|
||||
uint32_t *os = ctx + (uint32_t)4U;
|
||||
uint8_t *bj = k + i * (uint32_t)4U;
|
||||
uint32_t u = load32_le(bj);
|
||||
uint32_t r = u;
|
||||
uint32_t x = r;
|
||||
os[i] = x;);
|
||||
ctx[12U] = ctr;
|
||||
KRML_MAYBE_FOR3(i,
|
||||
(uint32_t)0U,
|
||||
(uint32_t)3U,
|
||||
(uint32_t)1U,
|
||||
uint32_t *os = ctx + (uint32_t)13U;
|
||||
uint8_t *bj = n + i * (uint32_t)4U;
|
||||
uint32_t u = load32_le(bj);
|
||||
uint32_t r = u;
|
||||
uint32_t x = r;
|
||||
os[i] = x;);
|
||||
}
|
||||
|
||||
static void
|
||||
Hacl_Lib_LoadStore32_uint32s_to_le_bytes(uint8_t *output, uint32_t *input, uint32_t len)
|
||||
chacha20_encrypt_block(uint32_t *ctx, uint8_t *out, uint32_t incr, uint8_t *text)
|
||||
{
|
||||
for (uint32_t i = (uint32_t)0U; i < len; i = i + (uint32_t)1U) {
|
||||
uint32_t hd1 = input[i];
|
||||
uint8_t *x0 = output + (uint32_t)4U * i;
|
||||
store32_le(x0, hd1);
|
||||
}
|
||||
uint32_t k[16U] = { 0U };
|
||||
chacha20_core(k, ctx, incr);
|
||||
uint32_t bl[16U] = { 0U };
|
||||
KRML_MAYBE_FOR16(i,
|
||||
(uint32_t)0U,
|
||||
(uint32_t)16U,
|
||||
(uint32_t)1U,
|
||||
uint32_t *os = bl;
|
||||
uint8_t *bj = text + i * (uint32_t)4U;
|
||||
uint32_t u = load32_le(bj);
|
||||
uint32_t r = u;
|
||||
uint32_t x = r;
|
||||
os[i] = x;);
|
||||
KRML_MAYBE_FOR16(i,
|
||||
(uint32_t)0U,
|
||||
(uint32_t)16U,
|
||||
(uint32_t)1U,
|
||||
uint32_t *os = bl;
|
||||
uint32_t x = bl[i] ^ k[i];
|
||||
os[i] = x;);
|
||||
KRML_MAYBE_FOR16(i,
|
||||
(uint32_t)0U,
|
||||
(uint32_t)16U,
|
||||
(uint32_t)1U,
|
||||
store32_le(out + i * (uint32_t)4U, bl[i]););
|
||||
}
|
||||
|
||||
inline static uint32_t
|
||||
Hacl_Impl_Chacha20_rotate_left(uint32_t a, uint32_t s)
|
||||
static inline void
|
||||
chacha20_encrypt_last(uint32_t *ctx, uint32_t len, uint8_t *out, uint32_t incr, uint8_t *text)
|
||||
{
|
||||
return a << s | a >> ((uint32_t)32U - s);
|
||||
}
|
||||
|
||||
inline static void
|
||||
Hacl_Impl_Chacha20_quarter_round(uint32_t *st, uint32_t a, uint32_t b, uint32_t c, uint32_t d)
|
||||
{
|
||||
uint32_t sa = st[a];
|
||||
uint32_t sb0 = st[b];
|
||||
st[a] = sa + sb0;
|
||||
uint32_t sd = st[d];
|
||||
uint32_t sa10 = st[a];
|
||||
uint32_t sda = sd ^ sa10;
|
||||
st[d] = Hacl_Impl_Chacha20_rotate_left(sda, (uint32_t)16U);
|
||||
uint32_t sa0 = st[c];
|
||||
uint32_t sb1 = st[d];
|
||||
st[c] = sa0 + sb1;
|
||||
uint32_t sd0 = st[b];
|
||||
uint32_t sa11 = st[c];
|
||||
uint32_t sda0 = sd0 ^ sa11;
|
||||
st[b] = Hacl_Impl_Chacha20_rotate_left(sda0, (uint32_t)12U);
|
||||
uint32_t sa2 = st[a];
|
||||
uint32_t sb2 = st[b];
|
||||
st[a] = sa2 + sb2;
|
||||
uint32_t sd1 = st[d];
|
||||
uint32_t sa12 = st[a];
|
||||
uint32_t sda1 = sd1 ^ sa12;
|
||||
st[d] = Hacl_Impl_Chacha20_rotate_left(sda1, (uint32_t)8U);
|
||||
uint32_t sa3 = st[c];
|
||||
uint32_t sb = st[d];
|
||||
st[c] = sa3 + sb;
|
||||
uint32_t sd2 = st[b];
|
||||
uint32_t sa1 = st[c];
|
||||
uint32_t sda2 = sd2 ^ sa1;
|
||||
st[b] = Hacl_Impl_Chacha20_rotate_left(sda2, (uint32_t)7U);
|
||||
}
|
||||
|
||||
inline static void
|
||||
Hacl_Impl_Chacha20_double_round(uint32_t *st)
|
||||
{
|
||||
Hacl_Impl_Chacha20_quarter_round(st, (uint32_t)0U, (uint32_t)4U, (uint32_t)8U, (uint32_t)12U);
|
||||
Hacl_Impl_Chacha20_quarter_round(st, (uint32_t)1U, (uint32_t)5U, (uint32_t)9U, (uint32_t)13U);
|
||||
Hacl_Impl_Chacha20_quarter_round(st, (uint32_t)2U, (uint32_t)6U, (uint32_t)10U, (uint32_t)14U);
|
||||
Hacl_Impl_Chacha20_quarter_round(st, (uint32_t)3U, (uint32_t)7U, (uint32_t)11U, (uint32_t)15U);
|
||||
Hacl_Impl_Chacha20_quarter_round(st, (uint32_t)0U, (uint32_t)5U, (uint32_t)10U, (uint32_t)15U);
|
||||
Hacl_Impl_Chacha20_quarter_round(st, (uint32_t)1U, (uint32_t)6U, (uint32_t)11U, (uint32_t)12U);
|
||||
Hacl_Impl_Chacha20_quarter_round(st, (uint32_t)2U, (uint32_t)7U, (uint32_t)8U, (uint32_t)13U);
|
||||
Hacl_Impl_Chacha20_quarter_round(st, (uint32_t)3U, (uint32_t)4U, (uint32_t)9U, (uint32_t)14U);
|
||||
}
|
||||
|
||||
inline static void
|
||||
Hacl_Impl_Chacha20_rounds(uint32_t *st)
|
||||
{
|
||||
for (uint32_t i = (uint32_t)0U; i < (uint32_t)10U; i = i + (uint32_t)1U)
|
||||
Hacl_Impl_Chacha20_double_round(st);
|
||||
}
|
||||
|
||||
inline static void
|
||||
Hacl_Impl_Chacha20_sum_states(uint32_t *st, uint32_t *st_)
|
||||
{
|
||||
for (uint32_t i = (uint32_t)0U; i < (uint32_t)16U; i = i + (uint32_t)1U) {
|
||||
uint32_t xi = st[i];
|
||||
uint32_t yi = st_[i];
|
||||
st[i] = xi + yi;
|
||||
}
|
||||
}
|
||||
|
||||
inline static void
|
||||
Hacl_Impl_Chacha20_copy_state(uint32_t *st, uint32_t *st_)
|
||||
{
|
||||
memcpy(st, st_, (uint32_t)16U * sizeof st_[0U]);
|
||||
}
|
||||
|
||||
inline static void
|
||||
Hacl_Impl_Chacha20_chacha20_core(uint32_t *k, uint32_t *st, uint32_t ctr)
|
||||
{
|
||||
st[12U] = ctr;
|
||||
Hacl_Impl_Chacha20_copy_state(k, st);
|
||||
Hacl_Impl_Chacha20_rounds(k);
|
||||
Hacl_Impl_Chacha20_sum_states(k, st);
|
||||
}
|
||||
|
||||
inline static void
|
||||
Hacl_Impl_Chacha20_chacha20_block(uint8_t *stream_block, uint32_t *st, uint32_t ctr)
|
||||
{
|
||||
uint32_t st_[16U] = { 0U };
|
||||
Hacl_Impl_Chacha20_chacha20_core(st_, st, ctr);
|
||||
Hacl_Lib_LoadStore32_uint32s_to_le_bytes(stream_block, st_, (uint32_t)16U);
|
||||
}
|
||||
|
||||
inline static void
|
||||
Hacl_Impl_Chacha20_init(uint32_t *st, uint8_t *k, uint8_t *n1)
|
||||
{
|
||||
uint32_t *stcst = st;
|
||||
uint32_t *stk = st + (uint32_t)4U;
|
||||
uint32_t *stc = st + (uint32_t)12U;
|
||||
uint32_t *stn = st + (uint32_t)13U;
|
||||
stcst[0U] = (uint32_t)0x61707865U;
|
||||
stcst[1U] = (uint32_t)0x3320646eU;
|
||||
stcst[2U] = (uint32_t)0x79622d32U;
|
||||
stcst[3U] = (uint32_t)0x6b206574U;
|
||||
Hacl_Lib_LoadStore32_uint32s_from_le_bytes(stk, k, (uint32_t)8U);
|
||||
stc[0U] = (uint32_t)0U;
|
||||
Hacl_Lib_LoadStore32_uint32s_from_le_bytes(stn, n1, (uint32_t)3U);
|
||||
}
|
||||
|
||||
static void
|
||||
Hacl_Impl_Chacha20_update(uint8_t *output, uint8_t *plain, uint32_t *st, uint32_t ctr)
|
||||
{
|
||||
uint32_t b[48U] = { 0U };
|
||||
uint32_t *k = b;
|
||||
uint32_t *ib = b + (uint32_t)16U;
|
||||
uint32_t *ob = b + (uint32_t)32U;
|
||||
Hacl_Impl_Chacha20_chacha20_core(k, st, ctr);
|
||||
Hacl_Lib_LoadStore32_uint32s_from_le_bytes(ib, plain, (uint32_t)16U);
|
||||
for (uint32_t i = (uint32_t)0U; i < (uint32_t)16U; i = i + (uint32_t)1U) {
|
||||
uint32_t xi = ib[i];
|
||||
uint32_t yi = k[i];
|
||||
ob[i] = xi ^ yi;
|
||||
}
|
||||
Hacl_Lib_LoadStore32_uint32s_to_le_bytes(output, ob, (uint32_t)16U);
|
||||
}
|
||||
|
||||
static void
|
||||
Hacl_Impl_Chacha20_update_last(
|
||||
uint8_t *output,
|
||||
uint8_t *plain,
|
||||
uint32_t len,
|
||||
uint32_t *st,
|
||||
uint32_t ctr)
|
||||
{
|
||||
uint8_t block[64U] = { 0U };
|
||||
Hacl_Impl_Chacha20_chacha20_block(block, st, ctr);
|
||||
uint8_t *mask = block;
|
||||
for (uint32_t i = (uint32_t)0U; i < len; i = i + (uint32_t)1U) {
|
||||
uint8_t xi = plain[i];
|
||||
uint8_t yi = mask[i];
|
||||
output[i] = xi ^ yi;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
Hacl_Impl_Chacha20_chacha20_counter_mode_blocks(
|
||||
uint8_t *output,
|
||||
uint8_t *plain,
|
||||
uint32_t num_blocks,
|
||||
uint32_t *st,
|
||||
uint32_t ctr)
|
||||
{
|
||||
for (uint32_t i = (uint32_t)0U; i < num_blocks; i = i + (uint32_t)1U) {
|
||||
uint8_t *b = plain + (uint32_t)64U * i;
|
||||
uint8_t *o = output + (uint32_t)64U * i;
|
||||
Hacl_Impl_Chacha20_update(o, b, st, ctr + i);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
Hacl_Impl_Chacha20_chacha20_counter_mode(
|
||||
uint8_t *output,
|
||||
uint8_t *plain,
|
||||
uint32_t len,
|
||||
uint32_t *st,
|
||||
uint32_t ctr)
|
||||
{
|
||||
uint32_t blocks_len = len >> (uint32_t)6U;
|
||||
uint32_t part_len = len & (uint32_t)0x3fU;
|
||||
uint8_t *output_ = output;
|
||||
uint8_t *plain_ = plain;
|
||||
uint8_t *output__ = output + (uint32_t)64U * blocks_len;
|
||||
uint8_t *plain__ = plain + (uint32_t)64U * blocks_len;
|
||||
Hacl_Impl_Chacha20_chacha20_counter_mode_blocks(output_, plain_, blocks_len, st, ctr);
|
||||
if (part_len > (uint32_t)0U)
|
||||
Hacl_Impl_Chacha20_update_last(output__, plain__, part_len, st, ctr + blocks_len);
|
||||
}
|
||||
|
||||
static void
|
||||
Hacl_Impl_Chacha20_chacha20(
|
||||
uint8_t *output,
|
||||
uint8_t *plain,
|
||||
uint32_t len,
|
||||
uint8_t *k,
|
||||
uint8_t *n1,
|
||||
uint32_t ctr)
|
||||
{
|
||||
uint32_t buf[16U] = { 0U };
|
||||
uint32_t *st = buf;
|
||||
Hacl_Impl_Chacha20_init(st, k, n1);
|
||||
Hacl_Impl_Chacha20_chacha20_counter_mode(output, plain, len, st, ctr);
|
||||
uint8_t plain[64U] = { 0U };
|
||||
memcpy(plain, text, len * sizeof(uint8_t));
|
||||
chacha20_encrypt_block(ctx, plain, incr, plain);
|
||||
memcpy(out, plain, len * sizeof(uint8_t));
|
||||
}
|
||||
|
||||
void
|
||||
Hacl_Chacha20_chacha20_key_block(uint8_t *block, uint8_t *k, uint8_t *n1, uint32_t ctr)
|
||||
Hacl_Impl_Chacha20_chacha20_update(uint32_t *ctx, uint32_t len, uint8_t *out, uint8_t *text)
|
||||
{
|
||||
uint32_t buf[16U] = { 0U };
|
||||
uint32_t *st = buf;
|
||||
Hacl_Impl_Chacha20_init(st, k, n1);
|
||||
Hacl_Impl_Chacha20_chacha20_block(block, st, ctr);
|
||||
uint32_t rem = len % (uint32_t)64U;
|
||||
uint32_t nb = len / (uint32_t)64U;
|
||||
uint32_t rem1 = len % (uint32_t)64U;
|
||||
for (uint32_t i = (uint32_t)0U; i < nb; i++) {
|
||||
chacha20_encrypt_block(ctx, out + i * (uint32_t)64U, i, text + i * (uint32_t)64U);
|
||||
}
|
||||
if (rem1 > (uint32_t)0U) {
|
||||
chacha20_encrypt_last(ctx, rem, out + nb * (uint32_t)64U, nb, text + nb * (uint32_t)64U);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
This function implements Chacha20
|
||||
|
||||
val chacha20 :
|
||||
output:uint8_p ->
|
||||
plain:uint8_p{ disjoint output plain } ->
|
||||
len:uint32_t{ v len = length output /\ v len = length plain } ->
|
||||
key:uint8_p{ length key = 32 } ->
|
||||
nonce:uint8_p{ length nonce = 12 } ->
|
||||
ctr:uint32_t{ v ctr + length plain / 64 < pow2 32 } ->
|
||||
Stack unit
|
||||
(requires
|
||||
fun h -> live h output /\ live h plain /\ live h nonce /\ live h key)
|
||||
(ensures
|
||||
fun h0 _ h1 ->
|
||||
live h1 output /\ live h0 plain /\ modifies_1 output h0 h1 /\
|
||||
live h0 nonce /\
|
||||
live h0 key /\
|
||||
h1.[ output ] ==
|
||||
chacha20_encrypt_bytes h0.[ key ] h0.[ nonce ] (v ctr) h0.[ plain ])
|
||||
*/
|
||||
void
|
||||
Hacl_Chacha20_chacha20(
|
||||
uint8_t *output,
|
||||
uint8_t *plain,
|
||||
Hacl_Chacha20_chacha20_encrypt(
|
||||
uint32_t len,
|
||||
uint8_t *k,
|
||||
uint8_t *n1,
|
||||
uint8_t *out,
|
||||
uint8_t *text,
|
||||
uint8_t *key,
|
||||
uint8_t *n,
|
||||
uint32_t ctr)
|
||||
{
|
||||
Hacl_Impl_Chacha20_chacha20(output, plain, len, k, n1, ctr);
|
||||
uint32_t ctx[16U] = { 0U };
|
||||
Hacl_Impl_Chacha20_chacha20_init(ctx, key, n, ctr);
|
||||
Hacl_Impl_Chacha20_chacha20_update(ctx, len, out, text);
|
||||
}
|
||||
|
||||
void
|
||||
Hacl_Chacha20_chacha20_decrypt(
|
||||
uint32_t len,
|
||||
uint8_t *out,
|
||||
uint8_t *cipher,
|
||||
uint8_t *key,
|
||||
uint8_t *n,
|
||||
uint32_t ctr)
|
||||
{
|
||||
uint32_t ctx[16U] = { 0U };
|
||||
Hacl_Impl_Chacha20_chacha20_init(ctx, key, n, ctr);
|
||||
Hacl_Impl_Chacha20_chacha20_update(ctx, len, out, cipher);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,81 +1,61 @@
|
|||
/* Copyright 2016-2018 INRIA and Microsoft Corporation
|
||||
/* MIT License
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* Copyright (c) 2016-2020 INRIA, CMU and Microsoft Corporation
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "kremlib.h"
|
||||
#ifndef __Hacl_Chacha20_H
|
||||
#define __Hacl_Chacha20_H
|
||||
|
||||
typedef uint32_t Hacl_Impl_Xor_Lemmas_u32;
|
||||
|
||||
typedef uint8_t Hacl_Impl_Xor_Lemmas_u8;
|
||||
|
||||
typedef uint8_t *Hacl_Lib_LoadStore32_uint8_p;
|
||||
|
||||
typedef uint32_t Hacl_Impl_Chacha20_u32;
|
||||
|
||||
typedef uint32_t Hacl_Impl_Chacha20_h32;
|
||||
|
||||
typedef uint8_t *Hacl_Impl_Chacha20_uint8_p;
|
||||
|
||||
typedef uint32_t *Hacl_Impl_Chacha20_state;
|
||||
|
||||
typedef uint32_t Hacl_Impl_Chacha20_idx;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *k;
|
||||
void *n;
|
||||
} Hacl_Impl_Chacha20_log_t_;
|
||||
|
||||
typedef void *Hacl_Impl_Chacha20_log_t;
|
||||
|
||||
typedef uint32_t Hacl_Lib_Create_h32;
|
||||
|
||||
typedef uint8_t *Hacl_Chacha20_uint8_p;
|
||||
|
||||
typedef uint32_t Hacl_Chacha20_uint32_t;
|
||||
|
||||
void Hacl_Chacha20_chacha20_key_block(uint8_t *block, uint8_t *k, uint8_t *n1, uint32_t ctr);
|
||||
|
||||
/*
|
||||
This function implements Chacha20
|
||||
|
||||
val chacha20 :
|
||||
output:uint8_p ->
|
||||
plain:uint8_p{ disjoint output plain } ->
|
||||
len:uint32_t{ v len = length output /\ v len = length plain } ->
|
||||
key:uint8_p{ length key = 32 } ->
|
||||
nonce:uint8_p{ length nonce = 12 } ->
|
||||
ctr:uint32_t{ v ctr + length plain / 64 < pow2 32 } ->
|
||||
Stack unit
|
||||
(requires
|
||||
fun h -> live h output /\ live h plain /\ live h nonce /\ live h key)
|
||||
(ensures
|
||||
fun h0 _ h1 ->
|
||||
live h1 output /\ live h0 plain /\ modifies_1 output h0 h1 /\
|
||||
live h0 nonce /\
|
||||
live h0 key /\
|
||||
h1.[ output ] ==
|
||||
chacha20_encrypt_bytes h0.[ key ] h0.[ nonce ] (v ctr) h0.[ plain ])
|
||||
*/
|
||||
void
|
||||
Hacl_Chacha20_chacha20(
|
||||
uint8_t *output,
|
||||
uint8_t *plain,
|
||||
uint32_t len,
|
||||
uint8_t *k,
|
||||
uint8_t *n1,
|
||||
uint32_t ctr);
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include "krml/internal/types.h"
|
||||
#include "krml/lowstar_endianness.h"
|
||||
#include "krml/internal/target.h"
|
||||
|
||||
#include "Hacl_Krmllib.h"
|
||||
|
||||
void
|
||||
Hacl_Chacha20_chacha20_encrypt(
|
||||
uint32_t len,
|
||||
uint8_t *out,
|
||||
uint8_t *text,
|
||||
uint8_t *key,
|
||||
uint8_t *n,
|
||||
uint32_t ctr);
|
||||
|
||||
void
|
||||
Hacl_Chacha20_chacha20_decrypt(
|
||||
uint32_t len,
|
||||
uint8_t *out,
|
||||
uint8_t *cipher,
|
||||
uint8_t *key,
|
||||
uint8_t *n,
|
||||
uint32_t ctr);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#define __Hacl_Chacha20_H_DEFINED
|
||||
#endif
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue