adding RSA-OAEP
This commit is contained in:
parent
f947a91725
commit
997bf1010d
|
@ -0,0 +1,25 @@
|
|||
# Makefile for the AVR-Crypto-Lib project
|
||||
#
|
||||
# This file is part of the AVR-Crypto-Lib.
|
||||
# Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
SHELL = sh
|
||||
|
||||
include Makefile_sys_conf.inc
|
||||
include Makefile_en21_conf.inc
|
||||
include Makefile_main.inc
|
||||
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
MCU_TARGET = atmega128
|
||||
F_CPU = 14745600
|
||||
OPTIMIZE = -Os # -Os
|
||||
EXTRALINK = xram.o
|
||||
DEFS = -D$(call uc, $(MCU_TARGET)) -DF_CPU=$(F_CPU)
|
||||
BOARD_NAME = ethernut2.1
|
||||
|
||||
override CFLAGS_A = -MMD -MF$(DEP_DIR)$(patsubst %.o,%.d,$(notdir $(1))) $(DEBUG) $(WARNING) -std=$(CSTD) $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS)
|
||||
override CFLAGS = -MMD -MF$(DEP_DIR)$(patsubst %.o,%.d,$(notdir $@)) $(DEBUG) $(WARNING) -std=$(CSTD) $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS)
|
||||
|
||||
override LDFLAGS = -gdwarf-2 -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x807fff -Wl,-Map,#
|
||||
override ASFLAGS = -mmcu=$(MCU_TARGET) -Wa,--gdwarf-2
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
# Makefile for the AVR-Crypto-Lib project
|
||||
#
|
||||
# This file is part of the AVR-Crypto-Lib.
|
||||
# Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
SHELL = sh
|
||||
|
||||
include Makefile_sys_conf.inc
|
||||
include Makefile_m644_conf.inc
|
||||
include Makefile_main.inc
|
||||
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
MCU_TARGET = atmega644
|
||||
F_CPU = 20000000
|
||||
OPTIMIZE = -Os # -Os
|
||||
EXTRALINK =
|
||||
DEFS = -D$(call uc, $(MCU_TARGET)) -DF_CPU=$(F_CPU)
|
||||
BOARD_NAME = pollin_eval_m644
|
||||
|
||||
override CFLAGS_A = -MMD -MF$(DEP_DIR)$(patsubst %.o,%.d,$(notdir $(1))) $(DEBUG) $(WARNING) -std=$(CSTD) $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS)
|
||||
override CFLAGS = -MMD -MF$(DEP_DIR)$(patsubst %.o,%.d,$(notdir $@)) $(DEBUG) $(WARNING) -std=$(CSTD) $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS)
|
||||
|
||||
override LDFLAGS = -gdwarf-2 -Wl,-Map,
|
||||
override ASFLAGS = -mmcu=$(MCU_TARGET) -Wa,--gdwarf-2
|
||||
|
||||
PROGRAMMER = avr911
|
||||
PROG_PORT = /dev/ttyUSB1
|
||||
DEFS = -D$(call uc, $(MCU_TARGET)) -DF_CPU=$(F_CPU)
|
||||
FLASHCMD = avrdude -p $(MCU_TARGET) -P $(PROG_PORT) -c $(PROGRAMMER) -U flash:w:# no space at the end
|
||||
#FLASHCMD = avrdude -p $(MCU_TARGET) -c usbasp -U flash:w:# no space at the end
|
||||
RESETCMD = avrdude -p $(MCU_TARGET) -P $(PROG_PORT) -c $(PROGRAMMER)
|
|
@ -0,0 +1,396 @@
|
|||
# Makefile for the AVR-Crypto-Lib project
|
||||
#
|
||||
# This file is part of the AVR-Crypto-Lib.
|
||||
# Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
BLOCK_CIPHERS :=
|
||||
STREAM_CIPHERS :=
|
||||
HASHES :=
|
||||
MACS :=
|
||||
PRNGS :=
|
||||
ENCODINGS :=
|
||||
SIGNATURE :=
|
||||
PK_CIPHERS :=
|
||||
AUX :=
|
||||
|
||||
|
||||
# we use the gnu make standard library
|
||||
include gmsl
|
||||
|
||||
GLOBAL_INCDIR := ./ $(TESTSRC_DIR)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# inclusion of make stubs
|
||||
include mkfiles/0*.mk
|
||||
include mkfiles/*.mk
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
ALGORITHMS = $(BLOCK_CIPHERS) $(STREAM_CIPHERS) $(HASHES) $(PRNGS) $(MACS) \
|
||||
$(ENCODINGS) $(SIGNATURE) $(PK_CIPHERS) $(AUX)
|
||||
ALGORITHMS_OBJ = $(patsubst %,%_OBJ, $(ALGORITHMS))
|
||||
ALGORITHMS_TESTBIN = $(patsubst %,%_TESTBIN, $(ALGORITHMS))
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# define binary object in $(BIN_DIR)$(ALGO)/<obj>
|
||||
define Assert_Template
|
||||
$(1) = $(2)
|
||||
endef
|
||||
|
||||
$(foreach a, $(ALGORITHMS), $(eval $(call Assert_Template, \
|
||||
$(a)_BINOBJ, \
|
||||
$(addprefix $(BIN_DIR)$(call lc,$(a))/,$($(a)_OBJ)) \
|
||||
)))
|
||||
|
||||
$(foreach a, $(ALGORITHMS), $(eval $(call Assert_Template, \
|
||||
$(a)_TESTBINOBJ, \
|
||||
$(addprefix $(BIN_DIR)$(call lc,$(a))/$(TEST_DIR),$($(a)_TESTBIN)) \
|
||||
)))
|
||||
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
define TargetSource_Template
|
||||
$(1): $(2)
|
||||
@mkdir -p $(dir $(1)) $(DEP_DIR)
|
||||
@echo "[cc]: $(1) <-- $(2)"
|
||||
@$(CC) $(CFLAGS_A) $(addprefix -I./,$(3)) $(addprefix -D, $(4)) -c -o $(1) $(2)
|
||||
endef
|
||||
|
||||
|
||||
|
||||
define TargetSourceList_Template
|
||||
$(1): $(2)
|
||||
@mkdir -p $(dir $(1)) $(DEP_DIR)
|
||||
@echo "[cc]: $(1) <-- $(2)"
|
||||
@$(CC) $(CFLAGS_A) $(addprefix -I./,$(3)) $(addprefix -D, $(4)) $(LIST_OPT) -c -o /dev/null $(2) > $(1)
|
||||
endef
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Function: find_source_file
|
||||
# Arguments: 1: name of the binary file (.o extension) to search
|
||||
# 2: list of directorys to search for file
|
||||
# Returns: Returns paths to source file (mathing the pattern in
|
||||
# $(SOURCE_PATTERN)
|
||||
# ----------------------------------------------------------------------------
|
||||
SOURCE_PATTERN := %.S %.c
|
||||
find_source_file = $(firstword $(foreach d, $(2), \
|
||||
$(filter $(SOURCE_PATTERN), \
|
||||
$(wildcard $(d)$(notdir $(patsubst %.o,%,$1)).*) \
|
||||
) \
|
||||
) )
|
||||
|
||||
|
||||
$(foreach a, $(ALGORITHMS), \
|
||||
$(foreach b, $($(a)_OBJ), \
|
||||
$(eval $(call TargetSource_Template, \
|
||||
$(BIN_DIR)$(call lc, $(a))/$(b), \
|
||||
$(call find_source_file, $(b), $($(a)_DIR) $($(a)_INCDIR) $(GLOBAL_INCDIR) ),\
|
||||
$($(a)_DIR) $($(a)_INCDIR) $(GLOBAL_INCDIR), \
|
||||
$($(a)_DEF), \
|
||||
)) \
|
||||
) \
|
||||
)
|
||||
|
||||
$(foreach a, $(ALGORITHMS), \
|
||||
$(foreach b, $($(a)_TESTBIN), \
|
||||
$(eval $(call TargetSource_Template, \
|
||||
$(BIN_DIR)$(call lc, $(a))/$(TEST_DIR)$(b), \
|
||||
$(call find_source_file, $(b), $($(a)_DIR) $($(a)_INCDIR) $(GLOBAL_INCDIR) ),\
|
||||
$($(a)_DIR) $($(a)_INCDIR) $(GLOBAL_INCDIR), \
|
||||
$($(a)_DEF) \
|
||||
)) \
|
||||
) \
|
||||
)
|
||||
|
||||
|
||||
$(foreach a, $(ALGORITHMS), \
|
||||
$(foreach b, $($(a)_OBJ), \
|
||||
$(eval $(call TargetSourceList_Template, \
|
||||
$(LIST_DIR)$(call lc, $(a))/$(patsubst %.o,%.s,$(b)), \
|
||||
$(call find_source_file, $(b), $($(a)_DIR) $($(a)_INCDIR) $(GLOBAL_INCDIR) ),\
|
||||
$($(a)_DIR) $($(a)_INCDIR) $(GLOBAL_INCDIR), \
|
||||
$($(a)_DEF), \
|
||||
)) \
|
||||
) \
|
||||
)
|
||||
|
||||
EXTRALINK_BINOBJ = $(patsubst %, $(BIN_DIR)%, $(EXTRALINK))
|
||||
|
||||
$(foreach a, $(EXTRALINK), \
|
||||
$(eval $(call TargetSource_Template, \
|
||||
$(BIN_DIR)$(a), \
|
||||
$(call find_source_file, $(a), $(GLOBAL_INCDIR) ),\
|
||||
$($(a)_DIR) $($(a)_INCDIR) $(GLOBAL_INCDIR), \
|
||||
$($(a)_DEF), \
|
||||
)) \
|
||||
)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
define MainTestElf_Template
|
||||
$(1): $(2) $(3) $(4)
|
||||
@mkdir -p $(dir $(1))
|
||||
@echo "[ld]: $(1)"
|
||||
@$(CC) $(CFLAGS_A) $(LDFLAGS)$(patsubst %.elf,%.map,$(1)) -o \
|
||||
$(1) \
|
||||
$(2) $(3) $(EXTRALINK_BINOBJ)\
|
||||
$(LIBS)
|
||||
endef
|
||||
|
||||
$(foreach a, $(ALGORITHMS), \
|
||||
$(eval $(call MainTestElf_Template, \
|
||||
$(BIN_DIR)$(call lc, $(a))/$(TEST_DIR)main-$(call lc, $(a))-test.elf, \
|
||||
$($(a)_BINOBJ), \
|
||||
$($(a)_TESTBINOBJ), \
|
||||
$(EXTRALINK_BINOBJ) \
|
||||
)) \
|
||||
)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
all: $(foreach algo, $(ALGORITHMS), $($(algo)_BINOBJ))
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
define MakeDir_TEMPLATE
|
||||
$(1):
|
||||
@echo [mkdir] $(1)
|
||||
@mkdir -p $(1)
|
||||
endef
|
||||
|
||||
$(foreach d, DEP_DIR BIN_DIR TESTSRC_DIR TESTLOG_DIR SPEEDLOG_DIR SIZE_DIR LIST_DIR STAT_DIR AUTOASM_DIR, $(eval $(call MakeDir_TEMPLATE, \
|
||||
$($(d)) \
|
||||
)))
|
||||
|
||||
$(foreach algo, $(ALGORITHMS), $(eval $(call MakeDir__TEMPLATE, \
|
||||
$(BIN_DIR)$(call lc, $(algo))/$(TEST_DIR) \
|
||||
)))
|
||||
|
||||
define TestBin_TEMPLATE
|
||||
$(1)_TESTBIN: $(2)
|
||||
endef
|
||||
|
||||
$(foreach algo, $(ALGORITHMS), $(eval $(call TestBin_TEMPLATE, \
|
||||
$(algo), \
|
||||
$(BIN_DIR)$(call lc, $(algo))/$(TEST_DIR)main-$(call lc, $(algo))-test.elf \
|
||||
)))
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
define Listing_TEMPLATE
|
||||
$(1)_LIST: $(2)
|
||||
endef
|
||||
|
||||
$(foreach algo, $(ALGORITHMS), $(eval $(call Listing_TEMPLATE, \
|
||||
$(algo), \
|
||||
$(foreach obj,$($(algo)_OBJ), $(LIST_DIR)$(call lc, $(algo))/$(obj:.o=.s)) \
|
||||
)))
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
%.hex: %.elf
|
||||
@echo "[objcopy]: $@"
|
||||
@$(OBJCOPY) -j .text -j .data -O ihex $< $@
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
define Flash_Template
|
||||
$(1)_FLASH: $(2)
|
||||
@echo "[flash]: $(2)"
|
||||
@$(FLASHCMD)$(call first,$(2))
|
||||
endef
|
||||
|
||||
$(foreach algo, $(ALGORITHMS), $(eval $(call Flash_Template, \
|
||||
$(algo), \
|
||||
$(BIN_DIR)$(call lc, $(algo))/$(TEST_DIR)main-$(call lc, $(algo))-test.hex \
|
||||
)))
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
define Speed_Template
|
||||
$(1)_SPEED: $(1)_FLASH
|
||||
@$(RUBY) $(SPEEDTOOL) -c $(SPEEDCMD) -t $(SPEEDLOG_DIR) -a $(call lc, $(1))
|
||||
endef
|
||||
|
||||
$(foreach algo, $(ALGORITHMS), $(eval $(call Speed_Template, \
|
||||
$(algo), $(algo) \
|
||||
)))
|
||||
|
||||
.PHONY: hash_speed
|
||||
hash_speed: $(foreach algo, $(HASHES), $(algo)_SPEED)
|
||||
|
||||
.PHONY: blockcipher_speed
|
||||
blockcipher_speed: $(foreach algo, $(BLOCK_CIPHERS), $(algo)_SPEED)
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
define Size_Template
|
||||
$(1)_SIZE: $(2)
|
||||
@echo "[size] $(1)"
|
||||
$(SIZE) $(2) > $(strip $(SIZE_DIR))$(strip $(call lc, $(1))).size
|
||||
endef
|
||||
|
||||
$(foreach algo, $(ALGORITHMS), $(eval $(call Size_Template, \
|
||||
$(strip $(algo)), $($(algo)_BINOBJ) \
|
||||
)))
|
||||
|
||||
.PHONY: hash_size
|
||||
hash_size: $(foreach algo, $(HASHES), $(algo)_SIZE)
|
||||
|
||||
.PHONY: blockcipher_size
|
||||
blockcipher_size: $(foreach algo, $(BLOCK_CIPHERS), $(algo)_SIZE)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
.PHONY: tests
|
||||
tests: $(foreach a, $(ALGORITHMS), $(a)_TESTBIN)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
define TestRun_Template
|
||||
$(1)_TESTRUN: $(1)_FLASH
|
||||
@echo "[reset]"
|
||||
@sleep 3
|
||||
@$(RESETCMD)
|
||||
@sleep 1
|
||||
@echo "[test]: $(1)"
|
||||
$(RUBY) $(GET_TEST) $(TESTPORT) $(TESTPORTBAUDR) 8 1 nessie $(TESTLOG_DIR)$(TESTPREFIX) $(2)
|
||||
endef
|
||||
|
||||
$(foreach algo, $(ALGORITHMS),$(eval $(call TestRun_Template, $(algo), $(call lc,$(algo)) )))
|
||||
|
||||
all_testrun: $(foreach algo, $(ALGORITHMS), $(algo)_TESTRUN)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
define Obj_Template
|
||||
$(1)_OBJ: $(2)
|
||||
endef
|
||||
|
||||
$(foreach algo, $(ALGORITHMS), \
|
||||
$(eval $(call Obj_Template, \
|
||||
$(algo), \
|
||||
$($(algo)_BINOBJ)\
|
||||
))\
|
||||
)
|
||||
|
||||
.PHONY: all
|
||||
all: cores
|
||||
|
||||
.PHONY: reset
|
||||
reset:
|
||||
$(RESETCMD)
|
||||
|
||||
.PHONY: cores
|
||||
cores: $(foreach algo, $(ALGORITHMS), $(algo)_OBJ)
|
||||
|
||||
.PHONY: blockchiphers
|
||||
blockciphers: $(foreach algo, $(BLOCK_CIPHERS), $(algo)_OBJ)
|
||||
|
||||
.PHONY: streamchiphers
|
||||
streamciphers: $(foreach algo, $(STREAM_CIPHERS), $(algo)_OBJ)
|
||||
|
||||
.PHONY: hashes
|
||||
hashes: $(foreach algo, $(HASHES), $(algo)_OBJ)
|
||||
|
||||
.PHONY: macs
|
||||
macs: $(foreach algo, $(MACS), $(algo)_OBJ)
|
||||
|
||||
.PHONY: prngs
|
||||
prngs: $(foreach algo, $(PRNGS), $(algo)_OBJ)
|
||||
|
||||
.PHONY: encodings
|
||||
encodings: $(foreach algo, $(ENCODINGS), $(algo)_OBJ)
|
||||
|
||||
.PHONY: aux
|
||||
aux: $(foreach algo, $(AUX), $(algo)_OBJ)
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
.PHONY: help
|
||||
help: info
|
||||
.PHONY: info
|
||||
info:
|
||||
@echo "infos on AVR-Crypto-lib:"
|
||||
@echo " block ciphers:"
|
||||
@echo " $(BLOCK_CIPHERS)"
|
||||
@echo " stream ciphers:"
|
||||
@echo " $(STREAM_CIPHERS)"
|
||||
@echo " hash functions:"
|
||||
@echo " $(HASHES)"
|
||||
@echo " MAC functions:"
|
||||
@echo " $(MACS)"
|
||||
@echo " PRNG functions:"
|
||||
@echo " $(PRNGS)"
|
||||
@echo " signature functions:"
|
||||
@echo " $(SIGNATURE)"
|
||||
@echo " public key ciphers:"
|
||||
@echo " $(PK_CIPHERS)"
|
||||
@echo " encodings:"
|
||||
@echo " $(ENCODINGS)"
|
||||
@echo " auxiliary functions:"
|
||||
@echo " $(AUX)"
|
||||
@echo " targets:"
|
||||
@echo " all - all algorithm cores"
|
||||
@echo " cores - all algorithm cores"
|
||||
@echo " listings - all algorithm core listings"
|
||||
@echo " tests - all algorithm test programs"
|
||||
@echo " stats - all algorithm size statistics"
|
||||
@echo " blockciphers - all blockcipher cores"
|
||||
@echo " streamciphers - all streamcipher cores"
|
||||
@echo " hashes - all hash cores"
|
||||
@echo " macs - all MAC cores"
|
||||
@echo " prngs - all PRNG cores"
|
||||
@echo " all_testrun - testrun all algorithms"
|
||||
@echo " hash_size - measure size of all hash functions"
|
||||
@echo " hash_speed - measure performance of all hash functions"
|
||||
@echo " blockcipher_size - measure size of all blockciphers"
|
||||
@echo " blockcipher_speed - measure performance of all blockciphers"
|
||||
@echo " docu - build doxygen documentation"
|
||||
@echo " clean - remove a lot of builded files"
|
||||
@echo " depclean - also remove dependency files"
|
||||
@echo " *_TESTBIN - build test program"
|
||||
@echo " *_TESTRUN - run nessie test"
|
||||
@echo " *_OBJ - build algorithm core"
|
||||
@echo " *_FLASH - flash test program"
|
||||
@echo " *_LIST - build assembler listing"
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf $(BIN_DIR)*
|
||||
|
||||
.PHONY: depclean
|
||||
depclean: clean
|
||||
rm -f $(DEP_DIR)*.d
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# dependency inclusion
|
||||
#
|
||||
|
||||
DEPS := $(wildcard $(DEP_DIR)*.d)
|
||||
|
||||
ifneq ($(DEPS),)
|
||||
include $(DEPS)
|
||||
endif
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
DEBUG = -gdwarf-2
|
||||
WARNING = -pedantic -Wall -Werror -Wstrict-prototypes
|
||||
PROGRAMMER = jtagmkII
|
||||
PROG_PORT = usb
|
||||
FLASHCMD = avrdude -p $(MCU_TARGET) -P $(PROG_PORT) -c $(PROGRAMMER) -U flash:w:# no space at the end
|
||||
#FLASHCMD = avrdude -p $(MCU_TARGET) -c usbasp -U flash:w:# no space at the end
|
||||
#RESETCMD = avrdude -p $(MCU_TARGET) -P $(PROG_PORT) -c $(PROGRAMMER)
|
||||
RESETCMD = avarice -2 -R -j usb
|
||||
DEP_DIR = deps/$(BOARD_NAME)/#
|
||||
TEST_DIR = test/#
|
||||
BIN_DIR = bin/$(BOARD_NAME)/#
|
||||
TESTSRC_DIR = test_src/
|
||||
#uisp -dprog=bsd -dlpt=/dev/parport1 --upload if=$(PRG).hex
|
||||
ERASECMD =
|
||||
TESTPORT = /dev/ttyUSB0
|
||||
TESTPORTBAUDR = 115200
|
||||
TESTLOG_DIR = testlog/#
|
||||
TESTPREFIX = nessie-
|
||||
SPEEDTOOL = host/get_performance.rb
|
||||
SPEEDLOG_DIR = speed_log/$(BOARD_NAME)/#
|
||||
SPEEDPREFIX =
|
||||
SPEEDCMD = performance
|
||||
SIZE_DIR = size_log/$(BOARD_NAME)/#
|
||||
LIST_DIR = listings/$(BOARD_NAME)/#
|
||||
LIST_OPT = -Wa,-adhln -g
|
||||
STAT_DIR = stats/$(BOARD_NAME)/#
|
||||
AUTOASM_DIR = autoasm/$(BOARD_NAME)/#
|
||||
AUTOASM_OPT = -S
|
||||
CC = avr-gcc
|
||||
CSTD = c99
|
||||
|
||||
SIZESTAT_FILE = sizestats.txt
|
||||
|
||||
OBJCOPY = avr-objcopy
|
||||
OBJDUMP = avr-objdump
|
||||
SIZE = avr-size
|
||||
READELF = readelf
|
||||
RUBY = ruby
|
||||
GET_TEST = host/get_test.rb
|
||||
MAKE = make
|
||||
MAKE2GRAPH = ~/bin/make2graph.rb
|
||||
TWOPI = twopi
|
|
@ -2,6 +2,7 @@
|
|||
MCU_TARGET = atmega128
|
||||
F_CPU = 14745600
|
||||
OPTIMIZE = -Os # -Os
|
||||
EXTRALINK = xram.o
|
||||
DEBUG = -gdwarf-2
|
||||
WARNING = -pedantic -Wall -Werror -Wstrict-prototypes
|
||||
PROGRAMMER = jtagmkII
|
||||
|
@ -37,7 +38,7 @@ CSTD = c99
|
|||
override CFLAGS_A = -MMD -MF$(DEP_DIR)$(patsubst %.o,%.d,$(notdir $(1))) $(DEBUG) $(WARNING) -std=$(CSTD) $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS)
|
||||
override CFLAGS = -MMD -MF$(DEP_DIR)$(patsubst %.o,%.d,$(notdir $@)) $(DEBUG) $(WARNING) -std=$(CSTD) $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS)
|
||||
|
||||
override LDFLAGS = -gdwarf-2 -Wl,-Map,#
|
||||
override LDFLAGS = -gdwarf-2 -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x807fff -Wl,-Map,#
|
||||
override ASFLAGS = -mmcu=$(MCU_TARGET) -Wa,--gdwarf-2
|
||||
|
||||
SIZESTAT_FILE = sizestats.txt
|
||||
|
|
589
bigint/bigint.c
589
bigint/bigint.c
|
@ -1,6 +1,6 @@
|
|||
/* bigint.c */
|
||||
/*
|
||||
This file is part of the AVR-Crypto-Lib.
|
||||
This file is part of the ARM-Crypto-Lib.
|
||||
Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
@ -32,10 +32,14 @@
|
|||
|
||||
#include "bigint.h"
|
||||
#include <string.h>
|
||||
/*
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
#if DEBUG
|
||||
#include "cli.h"
|
||||
#include "bigint_io.h"
|
||||
*/
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||||
#endif
|
||||
|
@ -44,14 +48,14 @@
|
|||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
#endif
|
||||
|
||||
#define SET_FBS(a, v) do{(a)->info &=0xF8; (a)->info |= (v);}while(0)
|
||||
#define SET_FBS(a, v) do{(a)->info &=~BIGINT_FBS_MASK; (a)->info |= (v);}while(0)
|
||||
#define GET_FBS(a) ((a)->info&BIGINT_FBS_MASK)
|
||||
#define SET_NEG(a) (a)->info |= BIGINT_NEG_MASK
|
||||
#define SET_POS(a) (a)->info &= ~BIGINT_NEG_MASK
|
||||
#define XCHG(a,b) do{(a)^=(b); (b)^=(a); (a)^=(b);}while(0)
|
||||
#define XCHG_PTR(a,b) do{ a = (void*)(((uint16_t)(a)) ^ ((uint16_t)(b))); \
|
||||
b = (void*)(((uint16_t)(a)) ^ ((uint16_t)(b))); \
|
||||
a = (void*)(((uint16_t)(a)) ^ ((uint16_t)(b)));}while(0)
|
||||
#define XCHG_PTR(a,b) do{ a = (void*)(((bigint_ptr_int_t)(a)) ^ ((bigint_ptr_int_t)(b))); \
|
||||
b = (void*)(((bigint_ptr_int_t)(a)) ^ ((bigint_ptr_int_t)(b))); \
|
||||
a = (void*)(((bigint_ptr_int_t)(a)) ^ ((bigint_ptr_int_t)(b)));}while(0)
|
||||
|
||||
#define GET_SIGN(a) ((a)->info&BIGINT_NEG_MASK)
|
||||
|
||||
|
@ -64,10 +68,10 @@ void bigint_adjust(bigint_t* a){
|
|||
a->info=0;
|
||||
return;
|
||||
}
|
||||
uint8_t t;
|
||||
uint8_t i = 0x07;
|
||||
bigint_word_t t;
|
||||
uint8_t i = BIGINT_WORD_SIZE-1;
|
||||
t = a->wordv[a->length_B-1];
|
||||
while((t&0x80)==0 && i){
|
||||
while((t&(1L<<(BIGINT_WORD_SIZE-1)))==0 && i){
|
||||
t<<=1;
|
||||
i--;
|
||||
}
|
||||
|
@ -76,31 +80,81 @@ void bigint_adjust(bigint_t* a){
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
uint16_t bigint_length_b(bigint_t* a){
|
||||
if(!a->length_B || a->length_B==0){
|
||||
return 0;
|
||||
}
|
||||
return (a->length_B-1) * BIGINT_WORD_SIZE + GET_FBS(a);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
uint16_t bigint_length_B(bigint_t* a){
|
||||
return a->length_B * sizeof(bigint_word_t);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
uint32_t bigint_get_first_set_bit(bigint_t* a){
|
||||
if(a->length_B==0){
|
||||
return (uint32_t)(-1);
|
||||
}
|
||||
return (a->length_B-1)*sizeof(bigint_word_t)*8+GET_FBS(a);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
uint32_t bigint_get_last_set_bit(bigint_t* a){
|
||||
uint32_t r=0;
|
||||
uint8_t b=0;
|
||||
bigint_word_t x=1;
|
||||
if(a->length_B==0){
|
||||
return (uint32_t)(-1);
|
||||
}
|
||||
while(a->wordv[r]==0 && r<a->length_B){
|
||||
++r;
|
||||
}
|
||||
if(a->wordv[r] == 0){
|
||||
return (uint32_t)(-1);
|
||||
}
|
||||
while((x&a->wordv[r])==0){
|
||||
++b;
|
||||
x <<= 1;
|
||||
}
|
||||
return r*BIGINT_WORD_SIZE+b;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void bigint_copy(bigint_t* dest, const bigint_t* src){
|
||||
memcpy(dest->wordv, src->wordv, src->length_B*sizeof(bigint_word_t));
|
||||
dest->length_B = src->length_B;
|
||||
dest->info = src->info;
|
||||
memcpy(dest->wordv, src->wordv, src->length_B);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
/* this should be implemented in assembly */
|
||||
void bigint_add_u(bigint_t* dest, const bigint_t* a, const bigint_t* b){
|
||||
uint16_t t=0, i;
|
||||
uint16_t i;
|
||||
bigint_wordplus_t t=0LL;
|
||||
if(a->length_B < b->length_B){
|
||||
XCHG_PTR(a,b);
|
||||
}
|
||||
for(i=0; i<b->length_B; ++i){
|
||||
t = a->wordv[i] + b->wordv[i] + t;
|
||||
dest->wordv[i] = (uint8_t)t;
|
||||
t>>=8;
|
||||
// t = (bigint_wordplus_t)(a->wordv[i]) + (bigint_wordplus_t)(b->wordv[i]) + t;
|
||||
t += a->wordv[i];
|
||||
t += b->wordv[i];
|
||||
dest->wordv[i] = (bigint_word_t)t;
|
||||
t>>=BIGINT_WORD_SIZE;
|
||||
}
|
||||
for(; i<a->length_B; ++i){
|
||||
t = a->wordv[i] + t;
|
||||
dest->wordv[i] = (uint8_t)t;
|
||||
t>>=8;
|
||||
t += a->wordv[i];
|
||||
dest->wordv[i] = (bigint_word_t)t;
|
||||
t>>=BIGINT_WORD_SIZE;
|
||||
}
|
||||
dest->wordv[i++] = t;
|
||||
dest->wordv[i++] = (bigint_word_t)t;
|
||||
dest->length_B = i;
|
||||
bigint_adjust(dest);
|
||||
}
|
||||
|
@ -109,30 +163,54 @@ void bigint_add_u(bigint_t* dest, const bigint_t* a, const bigint_t* b){
|
|||
|
||||
/* this should be implemented in assembly */
|
||||
void bigint_add_scale_u(bigint_t* dest, const bigint_t* a, uint16_t scale){
|
||||
uint16_t i,j=0;
|
||||
uint16_t t=0;
|
||||
if(scale>dest->length_B)
|
||||
memset(dest->wordv+dest->length_B, 0, scale-dest->length_B);
|
||||
for(i=scale; i<a->length_B+scale; ++i,++j){
|
||||
t = a->wordv[j] + t;
|
||||
bigint_t x;
|
||||
#if BIGINT_WORD_SIZE == 8
|
||||
memset(dest->wordv + dest->length_B, 0, MAX(dest->length_B, a->length_B + scale) - dest->length_B);
|
||||
x.wordv = dest->wordv + scale;
|
||||
x.length_B = dest->length_B - scale;
|
||||
if((int16_t)x.length_B < 0)
|
||||
x.length_B = 0;
|
||||
x.info = dest->info;
|
||||
bigint_add_u(&x, &x, a);
|
||||
dest->length_B = x.length_B + scale;
|
||||
dest->info = 0;
|
||||
bigint_adjust(dest);
|
||||
#else
|
||||
#error unimplemented!
|
||||
#endif
|
||||
|
||||
|
||||
/* uint16_t i,j=0;
|
||||
uint16_t scale_w;
|
||||
bigint_word_t *dst;
|
||||
bigint_wordplus_t t=0;
|
||||
scale_w = (scale+sizeof(bigint_word_t)-1)/sizeof(bigint_word_t);
|
||||
if(scale>dest->length_B*sizeof(bigint_word_t)){
|
||||
memset(((uint8_t*)dest->wordv)+dest->length_B*sizeof(bigint_word_t), 0, scale-dest->length_B*sizeof(bigint_word_t));
|
||||
}
|
||||
// a->wordv = (const uint32_t*)(((uint8_t*)a->wordv)+(scale&3));
|
||||
dst = dest->wordv + (scale&(sizeof(bigint_word_t)-1));
|
||||
for(i=scale/sizeof(bigint_word_t); i<a->length_B+scale_w; ++i,++j){
|
||||
t += a->wordv[j];
|
||||
if(dest->length_B>i){
|
||||
t += dest->wordv[i];
|
||||
t += dst[i];
|
||||
}
|
||||
dest->wordv[i] = (uint8_t)t;
|
||||
t>>=8;
|
||||
dst[i] = (bigint_word_t)t;
|
||||
t>>=BIGINT_WORD_SIZE;
|
||||
}
|
||||
while(t){
|
||||
if(dest->length_B>i){
|
||||
t = dest->wordv[i] + t;
|
||||
t += dst[i];
|
||||
}
|
||||
dest->wordv[i] = (uint8_t)t;
|
||||
t>>=8;
|
||||
dst[i] = (bigint_word_t)t;
|
||||
t>>=BIGINT_WORD_SIZE;
|
||||
++i;
|
||||
}
|
||||
if(dest->length_B < i){
|
||||
dest->length_B = i;
|
||||
}
|
||||
bigint_adjust(dest);
|
||||
*/
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -141,60 +219,46 @@ void bigint_add_scale_u(bigint_t* dest, const bigint_t* a, uint16_t scale){
|
|||
void bigint_sub_u(bigint_t* dest, const bigint_t* a, const bigint_t* b){
|
||||
int8_t borrow=0;
|
||||
int8_t r;
|
||||
int16_t t;
|
||||
bigint_wordplus_signed_t t=0LL;
|
||||
uint16_t i, min, max;
|
||||
min = MIN(a->length_B, b->length_B);
|
||||
max = MAX(a->length_B, b->length_B);
|
||||
r = bigint_cmp_u(a,b);
|
||||
if(r==0){
|
||||
dest->length_B = 0;
|
||||
dest->wordv[0] = 0;
|
||||
bigint_adjust(dest);
|
||||
bigint_set_zero(dest);
|
||||
return;
|
||||
}
|
||||
if(b->length_B==0){
|
||||
dest->length_B = a->length_B;
|
||||
memcpy(dest->wordv, a->wordv, a->length_B);
|
||||
dest->info = a->info;
|
||||
bigint_copy(dest, a);
|
||||
SET_POS(dest);
|
||||
return;
|
||||
}
|
||||
if(a->length_B==0){
|
||||
dest->length_B = b->length_B;
|
||||
memcpy(dest->wordv, b->wordv, b->length_B);
|
||||
dest->info = b->info;
|
||||
SET_NEG(dest);
|
||||
return;
|
||||
bigint_copy(dest, b);
|
||||
SET_NEG(dest);
|
||||
return;
|
||||
}
|
||||
if(r<0){
|
||||
bigint_sub_u(dest, b, a);
|
||||
SET_NEG(dest);
|
||||
}else{
|
||||
for(i=0; i<min; ++i){
|
||||
t = a->wordv[i] - b->wordv[i] - borrow;
|
||||
if(t<0){
|
||||
borrow = 1;
|
||||
dest->wordv[i]=(uint8_t)t;
|
||||
}else{
|
||||
borrow = 0;
|
||||
dest->wordv[i]=(uint8_t)t;
|
||||
}
|
||||
}
|
||||
for(;i<max; ++i){
|
||||
t = a->wordv[i] - borrow;
|
||||
if(t<0){
|
||||
borrow = 1;
|
||||
dest->wordv[i]=(uint8_t)t;
|
||||
}else{
|
||||
borrow = 0;
|
||||
dest->wordv[i]=(uint8_t)t;
|
||||
}
|
||||
|
||||
}
|
||||
SET_POS(dest);
|
||||
dest->length_B = i;
|
||||
bigint_adjust(dest);
|
||||
return;
|
||||
}
|
||||
for(i=0; i<max; ++i){
|
||||
t = a->wordv[i];
|
||||
if(i<min){
|
||||
t -= b->wordv[i];
|
||||
}
|
||||
t -= borrow;
|
||||
dest->wordv[i]=(bigint_word_t)t;
|
||||
if(t<0){
|
||||
borrow = 1;
|
||||
}else{
|
||||
borrow = 0;
|
||||
}
|
||||
}
|
||||
SET_POS(dest);
|
||||
dest->length_B = i;
|
||||
bigint_adjust(dest);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -212,8 +276,8 @@ int8_t bigint_cmp_u(const bigint_t* a, const bigint_t* b){
|
|||
uint16_t i;
|
||||
i = a->length_B-1;
|
||||
do{
|
||||
if(a->wordv[i]!=b->wordv[i]){
|
||||
if(a->wordv[i]>b->wordv[i]){
|
||||
if(a->wordv[i] != b->wordv[i]){
|
||||
if(a->wordv[i] > b->wordv[i]){
|
||||
return 1;
|
||||
}else{
|
||||
return -1;
|
||||
|
@ -307,34 +371,35 @@ int8_t bigint_cmp_s(const bigint_t* a, const bigint_t* b){
|
|||
/******************************************************************************/
|
||||
|
||||
void bigint_shiftleft(bigint_t* a, uint16_t shift){
|
||||
uint16_t byteshift;
|
||||
uint16_t i;
|
||||
uint16_t byteshift, word_alloc;
|
||||
int16_t i;
|
||||
uint8_t bitshift;
|
||||
uint16_t t=0;
|
||||
byteshift = (shift+3)/8;
|
||||
bitshift = shift&7;
|
||||
memmove(a->wordv+byteshift, a->wordv, a->length_B);
|
||||
memset(a->wordv, 0, byteshift);
|
||||
if(bitshift!=0){
|
||||
if(bitshift<=4){ /* shift to the left */
|
||||
for(i=byteshift; i<a->length_B+byteshift; ++i){
|
||||
t |= (a->wordv[i])<<bitshift;
|
||||
a->wordv[i] = (uint8_t)t;
|
||||
t >>= 8;
|
||||
}
|
||||
a->wordv[i] = (uint8_t)t;
|
||||
byteshift++;
|
||||
}else{ /* shift to the right */
|
||||
for(i=a->length_B+byteshift-1; i>byteshift-1; --i){
|
||||
t |= (a->wordv[i])<<(bitshift);
|
||||
a->wordv[i] = (uint8_t)(t>>8);
|
||||
t <<= 8;
|
||||
}
|
||||
t |= (a->wordv[i])<<(bitshift);
|
||||
a->wordv[i] = (uint8_t)(t>>8);
|
||||
}
|
||||
bigint_word_t *p;
|
||||
bigint_wordplus_t t=0;
|
||||
if(shift==0){
|
||||
return;
|
||||
}
|
||||
a->length_B += byteshift;
|
||||
byteshift = shift/8;
|
||||
bitshift = shift&7;
|
||||
for(i=0;i<=byteshift/sizeof(bigint_word_t); ++i){
|
||||
a->wordv[a->length_B+i] = 0;
|
||||
}
|
||||
if(byteshift){
|
||||
memmove(((uint8_t*)a->wordv)+byteshift, a->wordv, a->length_B*sizeof(bigint_word_t));
|
||||
memset(a->wordv, 0, byteshift);
|
||||
}
|
||||
p = (bigint_word_t*)(((uint8_t*)a->wordv)+byteshift);
|
||||
word_alloc = a->length_B+(byteshift+sizeof(bigint_word_t)-1)/sizeof(bigint_word_t)+1;
|
||||
a->wordv[word_alloc-1]=0;
|
||||
if(bitshift!=0){
|
||||
for(i=0; i<a->length_B; ++i){
|
||||
t |= ((bigint_wordplus_t)p[i])<<bitshift;
|
||||
p[i] = (bigint_word_t)t;
|
||||
t >>= BIGINT_WORD_SIZE;
|
||||
}
|
||||
p[i] = (bigint_word_t)t;
|
||||
}
|
||||
a->length_B = word_alloc;
|
||||
bigint_adjust(a);
|
||||
}
|
||||
|
||||
|
@ -344,32 +409,33 @@ void bigint_shiftright(bigint_t* a, uint16_t shift){
|
|||
uint16_t byteshift;
|
||||
uint16_t i;
|
||||
uint8_t bitshift;
|
||||
uint16_t t=0;
|
||||
bigint_wordplus_t t=0;
|
||||
byteshift = shift/8;
|
||||
bitshift = shift&7;
|
||||
if(byteshift >= a->length_B){ /* we would shift out more than we have */
|
||||
if(byteshift >= a->length_B*sizeof(bigint_word_t)){ /* we would shift out more than we have */
|
||||
bigint_set_zero(a);
|
||||
return;
|
||||
}
|
||||
if(byteshift == a->length_B-1 && bitshift>GET_FBS(a)){
|
||||
if(byteshift == a->length_B*sizeof(bigint_word_t)-1 && bitshift>GET_FBS(a)){
|
||||
bigint_set_zero(a);
|
||||
return;
|
||||
}
|
||||
if(byteshift){
|
||||
memmove(a->wordv, a->wordv+byteshift, a->length_B-byteshift);
|
||||
memset(a->wordv+a->length_B-byteshift, 0, byteshift);
|
||||
memmove(a->wordv, (uint8_t*)a->wordv+byteshift, a->length_B-byteshift);
|
||||
memset((uint8_t*)a->wordv+a->length_B-byteshift, 0, byteshift);
|
||||
}
|
||||
byteshift /= sizeof(bigint_word_t);
|
||||
if(bitshift!=0){
|
||||
/* shift to the right */
|
||||
for(i=a->length_B-byteshift-1; i>0; --i){
|
||||
t |= (a->wordv[i])<<(8-bitshift);
|
||||
a->wordv[i] = (uint8_t)(t>>8);
|
||||
t <<= 8;
|
||||
t |= ((bigint_wordplus_t)(a->wordv[i]))<<(BIGINT_WORD_SIZE-bitshift);
|
||||
a->wordv[i] = (bigint_word_t)(t>>BIGINT_WORD_SIZE);
|
||||
t <<= BIGINT_WORD_SIZE;
|
||||
}
|
||||
t |= (a->wordv[0])<<(8-bitshift);
|
||||
a->wordv[0] = (uint8_t)(t>>8);
|
||||
t |= ((bigint_wordplus_t)(a->wordv[0]))<<(BIGINT_WORD_SIZE-bitshift);
|
||||
a->wordv[0] = (bigint_word_t)(t>>BIGINT_WORD_SIZE);
|
||||
}
|
||||
a->length_B -= byteshift;
|
||||
a->length_B -= ((shift/8)+sizeof(bigint_word_t)-1)/sizeof(bigint_word_t);
|
||||
bigint_adjust(a);
|
||||
}
|
||||
|
||||
|
@ -400,7 +466,7 @@ void bigint_mul_u(bigint_t* dest, const bigint_t* a, const bigint_t* b){
|
|||
}
|
||||
if(dest==a || dest==b){
|
||||
bigint_t d;
|
||||
uint8_t d_b[a->length_B+b->length_B];
|
||||
bigint_word_t d_b[a->length_B+b->length_B];
|
||||
d.wordv = d_b;
|
||||
bigint_mul_u(&d, a, b);
|
||||
bigint_copy(dest, &d);
|
||||
|
@ -410,78 +476,80 @@ void bigint_mul_u(bigint_t* dest, const bigint_t* a, const bigint_t* b){
|
|||
if(a->length_B!=1){
|
||||
XCHG_PTR(a,b);
|
||||
}
|
||||
uint16_t i, t=0;
|
||||
uint8_t x = a->wordv[0];
|
||||
for(i=0; i<b->length_B; ++i){
|
||||
t += b->wordv[i]*x;
|
||||
dest->wordv[i] = (uint8_t)t;
|
||||
t>>=8;
|
||||
bigint_wordplus_t t=0;
|
||||
uint16_t i;
|
||||
bigint_word_t x = a->wordv[0];
|
||||
for(i=0; i < b->length_B; ++i){
|
||||
t += ((bigint_wordplus_t)b->wordv[i])*((bigint_wordplus_t)x);
|
||||
dest->wordv[i] = (bigint_word_t)t;
|
||||
t>>=BIGINT_WORD_SIZE;
|
||||
}
|
||||
dest->wordv[i] = (uint8_t)t;
|
||||
dest->length_B=i+1;
|
||||
dest->wordv[i] = (bigint_word_t)t;
|
||||
dest->length_B = i+1;
|
||||
dest->info = 0;
|
||||
bigint_adjust(dest);
|
||||
return;
|
||||
}
|
||||
if(a->length_B<=4 && b->length_B<=4){
|
||||
if(a->length_B * sizeof(bigint_word_t) <= 4 && b->length_B * sizeof(bigint_word_t) <= 4){
|
||||
uint32_t p=0, q=0;
|
||||
uint64_t r;
|
||||
memcpy(&p, a->wordv, a->length_B);
|
||||
memcpy(&q, b->wordv, b->length_B);
|
||||
r = (uint64_t)p*(uint64_t)q;
|
||||
memcpy(dest->wordv, &r, a->length_B+b->length_B);
|
||||
dest->length_B = a->length_B+b->length_B;
|
||||
memcpy(&p, a->wordv, a->length_B*sizeof(bigint_word_t));
|
||||
memcpy(&q, b->wordv, b->length_B*sizeof(bigint_word_t));
|
||||
r = (uint64_t)p * (uint64_t)q;
|
||||
memcpy(dest->wordv, &r, (dest->length_B = a->length_B + b->length_B)*sizeof(bigint_word_t));
|
||||
bigint_adjust(dest);
|
||||
return;
|
||||
}
|
||||
bigint_set_zero(dest);
|
||||
/* split a in xh & xl; split b in yh & yl */
|
||||
uint16_t n;
|
||||
n=(MAX(a->length_B, b->length_B)+1)/2;
|
||||
const uint16_t n = (MAX(a->length_B, b->length_B)+1)/2;
|
||||
bigint_t xl, xh, yl, yh;
|
||||
xl.wordv = a->wordv;
|
||||
yl.wordv = b->wordv;
|
||||
if(a->length_B<=n){
|
||||
xh.info=0;
|
||||
xh.length_B = 0;
|
||||
bigint_set_zero(&xh);
|
||||
xl.length_B = a->length_B;
|
||||
xl.info = 0;
|
||||
xl.info = a->info;
|
||||
}else{
|
||||
xl.length_B=n;
|
||||
xl.info = 0;
|
||||
bigint_adjust(&xl);
|
||||
xh.wordv = a->wordv+n;
|
||||
xh.wordv = &(a->wordv[n]);
|
||||
xh.length_B = a->length_B-n;
|
||||
xh.info = 0;
|
||||
xh.info = a->info;
|
||||
}
|
||||
if(b->length_B<=n){
|
||||
yh.info=0;
|
||||
yh.length_B = 0;
|
||||
bigint_set_zero(&yh);
|
||||
yl.length_B = b->length_B;
|
||||
yl.info = b->info;
|
||||
}else{
|
||||
yl.length_B=n;
|
||||
yl.info = 0;
|
||||
bigint_adjust(&yl);
|
||||
yh.wordv = b->wordv+n;
|
||||
yh.wordv = &(b->wordv[n]);
|
||||
yh.length_B = b->length_B-n;
|
||||
yh.info = 0;
|
||||
yh.info = b->info;
|
||||
}
|
||||
/* now we have split up a and b */
|
||||
uint8_t tmp_b[2*n+2], m_b[2*(n+1)];
|
||||
/* remember we want to do:
|
||||
* x*y = (xh*yh)*b**2n + ((xh+xl)*(yh+yl) - xh*yh - xl*yl)*b**n + yh*yl
|
||||
* 5 9 2 4 3 7 5 6 1 8 1
|
||||
*/
|
||||
bigint_word_t tmp_b[2*n+2], m_b[2*(n+1)];
|
||||
bigint_t tmp, tmp2, m;
|
||||
tmp.wordv = tmp_b;
|
||||
tmp2.wordv = tmp_b+n+1;
|
||||
tmp2.wordv = &(tmp_b[n+1]);
|
||||
m.wordv = m_b;
|
||||
|
||||
bigint_mul_u(dest, &xl, &yl); /* dest <= xl*yl */
|
||||
bigint_add_u(&tmp2, &xh, &xl); /* tmp2 <= xh+xl */
|
||||
bigint_add_u(&tmp, &yh, &yl); /* tmp <= yh+yl */
|
||||
bigint_mul_u(&m, &tmp2, &tmp); /* m <= tmp2*tmp */
|
||||
bigint_mul_u(&tmp, &xh, &yh); /* h <= xh*yh */
|
||||
bigint_sub_u(&m, &m, dest); /* m <= m-dest */
|
||||
bigint_sub_u(&m, &m, &tmp); /* m <= m-h */
|
||||
bigint_add_scale_u(dest, &m, n);
|
||||
bigint_add_scale_u(dest, &tmp, 2*n);
|
||||
bigint_mul_u(dest, &xl, &yl); /* 1: dest <= xl*yl */
|
||||
bigint_add_u(&tmp2, &xh, &xl); /* 2: tmp2 <= xh+xl */
|
||||
bigint_add_u(&tmp, &yh, &yl); /* 3: tmp <= yh+yl */
|
||||
bigint_mul_u(&m, &tmp2, &tmp); /* 4: m <= tmp2*tmp */
|
||||
bigint_mul_u(&tmp, &xh, &yh); /* 5: h <= xh*yh */
|
||||
bigint_sub_u(&m, &m, dest); /* 6: m <= m-dest */
|
||||
bigint_sub_u(&m, &m, &tmp); /* 7: m <= m-h */
|
||||
bigint_add_scale_u(dest, &m, n*sizeof(bigint_word_t)); /* 8: dest <= dest+m**n*/
|
||||
bigint_add_scale_u(dest, &tmp, 2*n*sizeof(bigint_word_t)); /* 9: dest <= dest+tmp**(2*n) */
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -517,11 +585,11 @@ void bigint_mul_s(bigint_t* dest, const bigint_t* a, const bigint_t* b){
|
|||
/* square */
|
||||
/* (xh*b^n+xl)^2 = xh^2*b^2n + 2*xh*xl*b^n + xl^2 */
|
||||
void bigint_square(bigint_t* dest, const bigint_t* a){
|
||||
if(a->length_B<=4){
|
||||
if(a->length_B*sizeof(bigint_word_t)<=4){
|
||||
uint64_t r=0;
|
||||
memcpy(&r, a->wordv, a->length_B);
|
||||
memcpy(&r, a->wordv, a->length_B*sizeof(bigint_word_t));
|
||||
r = r*r;
|
||||
memcpy(dest->wordv, &r, 2*a->length_B);
|
||||
memcpy(dest->wordv, &r, 2*a->length_B*sizeof(bigint_word_t));
|
||||
SET_POS(dest);
|
||||
dest->length_B=2*a->length_B;
|
||||
bigint_adjust(dest);
|
||||
|
@ -529,7 +597,7 @@ void bigint_square(bigint_t* dest, const bigint_t* a){
|
|||
}
|
||||
if(dest==a){
|
||||
bigint_t d;
|
||||
uint8_t d_b[a->length_B*2];
|
||||
bigint_word_t d_b[a->length_B*2];
|
||||
d.wordv = d_b;
|
||||
bigint_square(&d, a);
|
||||
bigint_copy(dest, &d);
|
||||
|
@ -538,79 +606,115 @@ void bigint_square(bigint_t* dest, const bigint_t* a){
|
|||
uint16_t n;
|
||||
n=(a->length_B+1)/2;
|
||||
bigint_t xh, xl, tmp; /* x-high, x-low, temp */
|
||||
uint8_t buffer[2*n+1];
|
||||
bigint_word_t buffer[2*n+1];
|
||||
xl.wordv = a->wordv;
|
||||
xl.length_B = n;
|
||||
xh.wordv = a->wordv+n;
|
||||
xl.info = 0;
|
||||
xh.wordv = &(a->wordv[n]);
|
||||
xh.length_B = a->length_B-n;
|
||||
xh.info = 0;
|
||||
bigint_adjust(&xl);
|
||||
bigint_adjust(&xh);
|
||||
tmp.wordv = buffer;
|
||||
/* (xh * b**n + xl)**2 = xh**2 * b**2n + 2 * xh * xl * b**n + xl**2 */
|
||||
|
||||
// cli_putstr("\r\nDBG (a): xl: "); bigint_print_hex(&xl);
|
||||
// cli_putstr("\r\nDBG (b): xh: "); bigint_print_hex(&xh);
|
||||
bigint_square(dest, &xl);
|
||||
// cli_putstr("\r\nDBG (1): xl**2: "); bigint_print_hex(dest);
|
||||
bigint_square(&tmp, &xh);
|
||||
bigint_add_scale_u(dest, &tmp, 2*n);
|
||||
// cli_putstr("\r\nDBG (2): xh**2: "); bigint_print_hex(&tmp);
|
||||
bigint_add_scale_u(dest, &tmp, 2*n*sizeof(bigint_word_t));
|
||||
// cli_putstr("\r\nDBG (3): xl**2 + xh**2*n**2: "); bigint_print_hex(dest);
|
||||
bigint_mul_u(&tmp, &xl, &xh);
|
||||
// cli_putstr("\r\nDBG (4): xl*xh: "); bigint_print_hex(&tmp);
|
||||
bigint_shiftleft(&tmp, 1);
|
||||
bigint_add_scale_u(dest, &tmp, n);
|
||||
// cli_putstr("\r\nDBG (5): xl*xh*2: "); bigint_print_hex(&tmp);
|
||||
bigint_add_scale_u(dest, &tmp, n*sizeof(bigint_word_t));
|
||||
// cli_putstr("\r\nDBG (6): x**2: "); bigint_print_hex(dest);
|
||||
// cli_putstr("\r\n");
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void bigint_sub_u_bitscale(bigint_t* a, const bigint_t* b, uint16_t bitscale){
|
||||
bigint_t tmp;
|
||||
uint8_t tmp_b[b->length_B+1];
|
||||
uint16_t i,j,byteshift=bitscale/8;
|
||||
uint8_t borrow=0;
|
||||
int16_t t;
|
||||
bigint_t tmp, x;
|
||||
bigint_word_t tmp_b[b->length_B + 1];
|
||||
const uint16_t word_shift = bitscale / BIGINT_WORD_SIZE;
|
||||
|
||||
if(a->length_B < b->length_B+byteshift){
|
||||
if(a->length_B < b->length_B + word_shift){
|
||||
#if DEBUG
|
||||
cli_putstr("\r\nDBG: *bang*\r\n");
|
||||
#endif
|
||||
bigint_set_zero(a);
|
||||
return;
|
||||
}
|
||||
|
||||
tmp.wordv = tmp_b;
|
||||
bigint_copy(&tmp, b);
|
||||
bigint_shiftleft(&tmp, bitscale&7);
|
||||
bigint_shiftleft(&tmp, bitscale % BIGINT_WORD_SIZE);
|
||||
|
||||
for(j=0,i=byteshift; i<tmp.length_B+byteshift; ++i, ++j){
|
||||
t = a->wordv[i] - tmp.wordv[j] - borrow;
|
||||
a->wordv[i] = (uint8_t)t;
|
||||
if(t<0){
|
||||
borrow = 1;
|
||||
}else{
|
||||
borrow = 0;
|
||||
}
|
||||
}
|
||||
while(borrow){
|
||||
if(i+1 > a->length_B){
|
||||
bigint_set_zero(a);
|
||||
return;
|
||||
}
|
||||
a->wordv[i] -= borrow;
|
||||
if(a->wordv[i]!=0xff){
|
||||
borrow=0;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
x.info = a->info;
|
||||
x.wordv = &(a->wordv[word_shift]);
|
||||
x.length_B = a->length_B - word_shift;
|
||||
|
||||
bigint_sub_u(&x, &x, &tmp);
|
||||
bigint_adjust(a);
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void bigint_reduce(bigint_t* a, const bigint_t* r){
|
||||
// bigint_adjust(r);
|
||||
// bigint_adjust((bigint_t*)r);
|
||||
uint8_t rfbs = GET_FBS(r);
|
||||
|
||||
#if DEBUG
|
||||
cli_putstr("\r\nDBG: (a) = "); bigint_print_hex(a);
|
||||
#endif
|
||||
if(r->length_B==0 || a->length_B==0){
|
||||
return;
|
||||
}
|
||||
while(a->length_B > r->length_B){
|
||||
bigint_sub_u_bitscale(a, r, (a->length_B-r->length_B)*8+GET_FBS(a)-rfbs-1);
|
||||
if((r->length_B*sizeof(bigint_word_t)<=4) && (a->length_B*sizeof(bigint_word_t)<=4)){
|
||||
uint32_t p=0, q=0;
|
||||
memcpy(&p, a->wordv, a->length_B*sizeof(bigint_word_t));
|
||||
memcpy(&q, r->wordv, r->length_B*sizeof(bigint_word_t));
|
||||
p %= q;
|
||||
memcpy(a->wordv, &p, a->length_B*sizeof(bigint_word_t));
|
||||
bigint_adjust(a);
|
||||
// cli_putstr("\r\nDBG: (0) = "); bigint_print_hex(a);
|
||||
return;
|
||||
}
|
||||
while((GET_FBS(a) > rfbs+1) && (a->length_B == r->length_B)){
|
||||
bigint_sub_u_bitscale(a, r, GET_FBS(a)-rfbs-1);
|
||||
uint16_t shift;
|
||||
while(a->length_B > r->length_B){
|
||||
shift = (a->length_B - r->length_B) * 8 * sizeof(bigint_word_t) + GET_FBS(a) - rfbs - 1;
|
||||
/*
|
||||
if((a->wordv[a->length_B-1] & ((1LL<<GET_FBS(a)) - 1)) > r->wordv[r->length_B-1]){
|
||||
// cli_putc('~');
|
||||
cli_putstr("\r\n ~ [a] = ");
|
||||
cli_hexdump_rev(&a->wordv[a->length_B-1], 4);
|
||||
cli_putstr(" [r] = ");
|
||||
cli_hexdump_rev(&r->wordv[r->length_B-1], 4);
|
||||
shift += 1;
|
||||
}
|
||||
*/
|
||||
// cli_putstr("\r\nDBG: (p) shift = "); cli_hexdump_rev(&shift, 2);
|
||||
// cli_putstr(" a_len = "); cli_hexdump_rev(&a->length_B, 2);
|
||||
// cli_putstr(" r_len = "); cli_hexdump_rev(&r->length_B, 2);
|
||||
// uart_flush(0);
|
||||
bigint_sub_u_bitscale(a, r, shift);
|
||||
// cli_putstr("\r\nDBG: (1) = "); bigint_print_hex(a);
|
||||
}
|
||||
while((GET_FBS(a) > rfbs) && (a->length_B == r->length_B)){
|
||||
shift = GET_FBS(a)-rfbs-1;
|
||||
// cli_putstr("\r\nDBG: (q) shift = "); cli_hexdump_rev(&shift, 2);
|
||||
bigint_sub_u_bitscale(a, r, shift);
|
||||
// cli_putstr("\r\nDBG: (2) = "); bigint_print_hex(a);
|
||||
}
|
||||
while(bigint_cmp_u(a,r)>=0){
|
||||
bigint_sub_u(a,a,r);
|
||||
// cli_putstr("\r\nDBG: (3) = "); bigint_print_hex(a);
|
||||
}
|
||||
bigint_adjust(a);
|
||||
// cli_putstr("\r\nDBG: (a) = "); bigint_print_hex(a);
|
||||
// cli_putstr("\r\n");
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -623,71 +727,116 @@ void bigint_expmod_u(bigint_t* dest, const bigint_t* a, const bigint_t* exp, con
|
|||
}
|
||||
|
||||
bigint_t res, base;
|
||||
uint8_t base_b[MAX(a->length_B,r->length_B*2)], res_b[r->length_B*2];
|
||||
bigint_word_t t, base_b[MAX(a->length_B,r->length_B)], res_b[r->length_B*2];
|
||||
uint16_t i;
|
||||
uint8_t j, t;
|
||||
uint8_t j;
|
||||
// uint16_t *xaddr = &i;
|
||||
// cli_putstr("\r\npre-alloc (");
|
||||
// cli_hexdump_rev(&xaddr, 4);
|
||||
// cli_putstr(") ...");
|
||||
res.wordv = res_b;
|
||||
base.wordv = base_b;
|
||||
bigint_copy(&base, a);
|
||||
// cli_putstr("\r\npost-copy");
|
||||
bigint_reduce(&base, r);
|
||||
res.wordv[0]=1;
|
||||
res.length_B=1;
|
||||
res.info = 0;
|
||||
bigint_adjust(&res);
|
||||
for(i=0; i+1<exp->length_B; ++i){
|
||||
t=exp->wordv[i];
|
||||
for(j=0; j<8; ++j){
|
||||
if(t&1){
|
||||
bigint_mul_u(&res, &res, &base);
|
||||
bigint_reduce(&res, r);
|
||||
if(exp->length_B == 0){
|
||||
bigint_copy(dest, &res);
|
||||
return;
|
||||
}
|
||||
uint8_t flag = 0;
|
||||
t=exp->wordv[exp->length_B - 1];
|
||||
for(i=exp->length_B; i > 0; --i){
|
||||
t = exp->wordv[i - 1];
|
||||
for(j=BIGINT_WORD_SIZE; j > 0; --j){
|
||||
if(!flag){
|
||||
if(t & (1<<(BIGINT_WORD_SIZE-1))){
|
||||
flag = 1;
|
||||
}
|
||||
}
|
||||
bigint_square(&base, &base);
|
||||
bigint_reduce(&base, r);
|
||||
t>>=1;
|
||||
if(flag){
|
||||
bigint_square(&res, &res);
|
||||
bigint_reduce(&res, r);
|
||||
if(t & (1<<(BIGINT_WORD_SIZE-1))){
|
||||
bigint_mul_u(&res, &res, &base);
|
||||
bigint_reduce(&res, r);
|
||||
}
|
||||
}
|
||||
t<<=1;
|
||||
}
|
||||
}
|
||||
t=exp->wordv[i];
|
||||
while(t){
|
||||
if(t&1){
|
||||
bigint_mul_u(&res, &res, &base);
|
||||
bigint_reduce(&res, r);
|
||||
}
|
||||
bigint_square(&base, &base);
|
||||
bigint_reduce(&base, r);
|
||||
t>>=1;
|
||||
}
|
||||
|
||||
// cli_putc('+');
|
||||
SET_POS(&res);
|
||||
bigint_copy(dest, &res);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
#define cli_putstr(a)
|
||||
#define bigint_print_hex(a)
|
||||
#define cli_hexdump_rev(a,b)
|
||||
#define uart_flush(a)
|
||||
|
||||
/* gcd <-- gcd(x,y) a*x+b*y=gcd */
|
||||
void bigint_gcdext(bigint_t* gcd, bigint_t* a, bigint_t* b, const bigint_t* x, const bigint_t* y){
|
||||
bigint_t g, x_, y_, u, v, a_, b_, c_, d_;
|
||||
volatile uint16_t i=0;
|
||||
uint16_t i=0;
|
||||
if(x->length_B==0 || y->length_B==0){
|
||||
return;
|
||||
}
|
||||
if(x->length_B==1 && x->wordv[0]==1){
|
||||
gcd->length_B = 1;
|
||||
gcd->wordv[0] = 1;
|
||||
if(a){
|
||||
a->length_B = 1;
|
||||
a->wordv[0] = 1;
|
||||
SET_POS(a);
|
||||
bigint_adjust(a);
|
||||
}
|
||||
if(b){
|
||||
bigint_set_zero(b);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(y->length_B==1 && y->wordv[0]==1){
|
||||
gcd->length_B = 1;
|
||||
gcd->wordv[0] = 1;
|
||||
if(b){
|
||||
b->length_B = 1;
|
||||
b->wordv[0] = 1;
|
||||
SET_POS(b);
|
||||
bigint_adjust(b);
|
||||
}
|
||||
if(a){
|
||||
bigint_set_zero(a);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
while(x->wordv[i]==0 && y->wordv[i]==0){
|
||||
++i;
|
||||
}
|
||||
uint8_t g_b[i+2], x_b[x->length_B-i], y_b[y->length_B-i];
|
||||
uint8_t u_b[x->length_B-i], v_b[y->length_B-i];
|
||||
uint8_t a_b[y->length_B+2], c_b[y->length_B+2];
|
||||
uint8_t b_b[x->length_B+2], d_b[x->length_B+2];
|
||||
bigint_word_t g_b[i+2], x_b[x->length_B-i], y_b[y->length_B-i];
|
||||
bigint_word_t u_b[x->length_B-i], v_b[y->length_B-i];
|
||||
bigint_word_t a_b[y->length_B+2], c_b[y->length_B+2];
|
||||
bigint_word_t b_b[x->length_B+2], d_b[x->length_B+2];
|
||||
|
||||
g.wordv = g_b;
|
||||
x_.wordv = x_b;
|
||||
y_.wordv = y_b;
|
||||
memset(g_b, 0, i);
|
||||
memset(g_b, 0, i*sizeof(bigint_word_t));
|
||||
g_b[i]=1;
|
||||
g.length_B = i+1;
|
||||
g.info=0;
|
||||
x_.info = y_.info = 0;
|
||||
x_.length_B = x->length_B-i;
|
||||
y_.length_B = y->length_B-i;
|
||||
memcpy(x_.wordv, x->wordv+i, x_.length_B);
|
||||
memcpy(y_.wordv, y->wordv+i, y_.length_B);
|
||||
memcpy(x_.wordv, x->wordv+i, x_.length_B*sizeof(bigint_word_t));
|
||||
memcpy(y_.wordv, y->wordv+i, y_.length_B*sizeof(bigint_word_t));
|
||||
for(i=0; (x_.wordv[0]&(1<<i))==0 && (y_.wordv[0]&(1<<i))==0; ++i){
|
||||
}
|
||||
|
||||
|
@ -699,6 +848,7 @@ void bigint_gcdext(bigint_t* gcd, bigint_t* a, bigint_t* b, const bigint_t* x, c
|
|||
bigint_shiftright(&x_, i);
|
||||
bigint_shiftright(&y_, i);
|
||||
}
|
||||
|
||||
u.wordv = u_b;
|
||||
v.wordv = v_b;
|
||||
a_.wordv = a_b;
|
||||
|
@ -717,7 +867,9 @@ void bigint_gcdext(bigint_t* gcd, bigint_t* a, bigint_t* b, const bigint_t* x, c
|
|||
bigint_set_zero(&b_);
|
||||
bigint_set_zero(&c_);
|
||||
do{
|
||||
cli_putstr("\r\nDBG (gcdext) 0");
|
||||
while((u.wordv[0]&1)==0){
|
||||
cli_putstr("\r\nDBG (gcdext) 0.1");
|
||||
bigint_shiftright(&u, 1);
|
||||
if((a_.wordv[0]&1) || (b_.wordv[0]&1)){
|
||||
bigint_add_s(&a_, &a_, &y_);
|
||||
|
@ -727,6 +879,7 @@ void bigint_gcdext(bigint_t* gcd, bigint_t* a, bigint_t* b, const bigint_t* x, c
|
|||
bigint_shiftright(&b_, 1);
|
||||
}
|
||||
while((v.wordv[0]&1)==0){
|
||||
cli_putstr("\r\nDBG (gcdext) 0.2");
|
||||
bigint_shiftright(&v, 1);
|
||||
if((c_.wordv[0]&1) || (d_.wordv[0]&1)){
|
||||
bigint_add_s(&c_, &c_, &y_);
|
||||
|
@ -770,8 +923,8 @@ void bigint_inverse(bigint_t* dest, const bigint_t* a, const bigint_t* m){
|
|||
|
||||
void bigint_changeendianess(bigint_t* a){
|
||||
uint8_t t, *p, *q;
|
||||
p = a->wordv;
|
||||
q = p+a->length_B-1;
|
||||
p = (uint8_t*)(a->wordv);
|
||||
q = ((uint8_t*)p)+a->length_B*sizeof(bigint_word_t)-1;
|
||||
while(p<q){
|
||||
t = *p;
|
||||
*p = *q;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* bigint.h */
|
||||
/*
|
||||
This file is part of the AVR-Crypto-Lib.
|
||||
This file is part of the ARM-Crypto-Lib.
|
||||
Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
@ -30,18 +30,29 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#define BIGINT_FBS_MASK 0x07 /* the last three bits indicate which is the first bit set */
|
||||
typedef uint8_t bigint_word_t;
|
||||
typedef uint16_t bigint_wordplus_t;
|
||||
typedef int16_t bigint_wordplus_signed_t;
|
||||
typedef uint16_t bigint_ptr_int_t; /* this must be an integer of the size of a pointer for the target architecture */
|
||||
#define BIGINT_WORD_SIZE 8
|
||||
|
||||
#define BIGINT_FBS_MASK (BIGINT_WORD_SIZE-1) /* the last five bits indicate which is the first bit set */
|
||||
#define BIGINT_NEG_MASK 0x80 /* this bit indicates a negative value */
|
||||
typedef struct{
|
||||
uint16_t length_B;
|
||||
uint8_t info;
|
||||
uint8_t *wordv; /* word vector, pointing to the LSB */
|
||||
bigint_word_t *wordv; /* word vector, pointing to the LSB */
|
||||
}bigint_t;
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void bigint_adjust(bigint_t* a);
|
||||
uint32_t bigint_get_first_set_bit(bigint_t* a);
|
||||
uint32_t bigint_get_last_set_bit(bigint_t* a);
|
||||
uint16_t bigint_length_b(bigint_t* a);
|
||||
uint16_t bigint_length_B(bigint_t* a);
|
||||
void bigint_copy(bigint_t* dest, const bigint_t* src);
|
||||
void bigint_add_u(bigint_t* dest, const bigint_t* a, const bigint_t* b);
|
||||
void bigint_add_scale_u(bigint_t* dest, const bigint_t* a, uint16_t scale);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* bigint_io.c */
|
||||
/*
|
||||
This file is part of the AVR-Crypto-Lib.
|
||||
This file is part of the ARM-Crypto-Lib.
|
||||
Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
@ -20,7 +20,6 @@
|
|||
#include "cli.h"
|
||||
#include "hexdigit_tab.h"
|
||||
#include "bigint.h"
|
||||
#include <avr/pgmspace.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
@ -33,15 +32,37 @@ void bigint_print_hex(const bigint_t* a){
|
|||
cli_putc('-');
|
||||
}
|
||||
// cli_putc((a->info&BIGINT_NEG_MASK)?'-':'+'); /* print sign */
|
||||
if(a->wordv[a->length_B-1]<0x10){
|
||||
cli_putc(pgm_read_byte(hexdigit_tab_uc_P+a->wordv[a->length_B-1]));
|
||||
/* if(a->wordv[a->length_B-1]<0x10){
|
||||
cli_putc(hexdigit_tab_uc[a->wordv[a->length_B-1]]);
|
||||
cli_hexdump_rev(a->wordv, a->length_B-1);
|
||||
} else {
|
||||
cli_hexdump_rev(a->wordv, a->length_B);
|
||||
*/
|
||||
// cli_hexdump_rev(a->wordv, a->length_B*sizeof(bigint_word_t));
|
||||
// }
|
||||
uint32_t idx;
|
||||
uint8_t print_zero=0;
|
||||
uint8_t *p,x,y;
|
||||
p = (uint8_t*)&(a->wordv[a->length_B-1])+sizeof(bigint_word_t)-1;
|
||||
for(idx = a->length_B * sizeof(bigint_word_t); idx > 0; --idx){
|
||||
x = *p >> 4;
|
||||
y = *p & 0xf;
|
||||
if(x!=0 || print_zero!=0){
|
||||
cli_putc(pgm_read_byte(&hexdigit_tab_lc_P[x]));
|
||||
}
|
||||
if(x){
|
||||
print_zero = 1;
|
||||
}
|
||||
if(y!=0 || print_zero!=0){
|
||||
cli_putc(pgm_read_byte(&hexdigit_tab_lc_P[y]));
|
||||
}
|
||||
if(y){
|
||||
print_zero = 1;
|
||||
}
|
||||
--p;
|
||||
}
|
||||
}
|
||||
|
||||
#define BLOCKSIZE 20
|
||||
#define BLOCKSIZE 32
|
||||
|
||||
static uint8_t char2nibble(char c){
|
||||
if(c>='0' && c <='9'){
|
||||
|
@ -76,23 +97,24 @@ static uint16_t read_byte(void){
|
|||
uint8_t bigint_read_hex_echo(bigint_t* a){
|
||||
uint16_t allocated=0;
|
||||
uint8_t shift4=0;
|
||||
uint16_t t;
|
||||
uint16_t t, idx = 0;
|
||||
a->length_B = 0;
|
||||
a->wordv = NULL;
|
||||
a->info = 0;
|
||||
for(;;){
|
||||
if(allocated-a->length_B < 1){
|
||||
uint8_t *p;
|
||||
p = realloc(a->wordv, allocated+=BLOCKSIZE);
|
||||
if(allocated - idx < 1){
|
||||
bigint_word_t *p;
|
||||
p = realloc(a->wordv, allocated += BLOCKSIZE);
|
||||
if(p==NULL){
|
||||
cli_putstr_P(PSTR("\r\nERROR: Out of memory!"));
|
||||
cli_putstr("\r\nERROR: Out of memory!");
|
||||
free(a->wordv);
|
||||
return 0xff;
|
||||
}
|
||||
memset((uint8_t*)p + allocated - BLOCKSIZE, 0, BLOCKSIZE);
|
||||
a->wordv=p;
|
||||
}
|
||||
t = read_byte();
|
||||
if(a->length_B==0){
|
||||
if(idx==0){
|
||||
if(t&0x0400){
|
||||
/* got minus */
|
||||
a->info |= BIGINT_NEG_MASK;
|
||||
|
@ -106,11 +128,11 @@ uint8_t bigint_read_hex_echo(bigint_t* a){
|
|||
}
|
||||
}
|
||||
if(t<=0x00ff){
|
||||
a->wordv[a->length_B++] = (uint8_t)t;
|
||||
((uint8_t*)(a->wordv))[idx++] = (uint8_t)t;
|
||||
}else{
|
||||
if(t&0x0200){
|
||||
shift4 = 1;
|
||||
a->wordv[a->length_B++] = (uint8_t)((t&0x0f)<<4);
|
||||
((uint8_t*)(a->wordv))[idx++] = (uint8_t)((t&0x0f)<<4);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -118,18 +140,18 @@ uint8_t bigint_read_hex_echo(bigint_t* a){
|
|||
/* we have to reverse the byte array */
|
||||
uint8_t tmp;
|
||||
uint8_t *p, *q;
|
||||
p = a->wordv;
|
||||
q = a->wordv+a->length_B-1;
|
||||
a->length_B = (idx + sizeof(bigint_word_t)-1)/sizeof(bigint_word_t);
|
||||
p = (uint8_t*)(a->wordv);
|
||||
q = (uint8_t*)a->wordv + a->length_B * sizeof(bigint_word_t) - 1;
|
||||
while(q>p){
|
||||
tmp = *p;
|
||||
*p = *q;
|
||||
*q = tmp;
|
||||
p++; q--;
|
||||
}
|
||||
bigint_adjust(a);
|
||||
if(shift4){
|
||||
bigint_adjust(a);
|
||||
bigint_shiftright(a, 4);
|
||||
}
|
||||
bigint_adjust(a);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* bigint_io.h */
|
||||
/*
|
||||
This file is part of the AVR-Crypto-Lib.
|
||||
This file is part of the ARM-Crypto-Lib.
|
||||
Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
|
|
@ -23,7 +23,7 @@ $debug = false
|
|||
require 'rubygems'
|
||||
require 'serialport'
|
||||
require 'getopt/std'
|
||||
require 'ftools'
|
||||
require 'fileutils'
|
||||
require 'date'
|
||||
$buffer_size = 0
|
||||
$conffile_check = Hash.new
|
||||
|
@ -37,7 +37,7 @@ def readconfigfile(fname, conf)
|
|||
return conf if $conffile_check[fname]==1
|
||||
$conffile_check[fname]=1
|
||||
section = "default"
|
||||
if not File.exists?(fname)
|
||||
if ! File.exists?(fname)
|
||||
return conf
|
||||
end
|
||||
file = File.open(fname, "r")
|
||||
|
@ -49,7 +49,7 @@ def readconfigfile(fname, conf)
|
|||
conf[m[1]] = Hash.new
|
||||
next
|
||||
end
|
||||
next if not /=/.match(line)
|
||||
next if ! /=/.match(line)
|
||||
m=/[\s]*([^\s]*)[\s]*=[\s]*([^\s]*)/.match(line)
|
||||
if m[1]=="include"
|
||||
Dir.glob(m[2]){ |fn| conf = readconfigfile(fn, conf) }
|
||||
|
@ -158,7 +158,7 @@ def wait_for_prompt(prompt)
|
|||
return false
|
||||
end
|
||||
acc += line
|
||||
end while not m=prompt.match(acc)
|
||||
end while ! m=prompt.match(acc)
|
||||
return m
|
||||
end
|
||||
|
||||
|
@ -187,7 +187,7 @@ def add_test(a,b)
|
|||
puts line
|
||||
return false
|
||||
end
|
||||
end while not /[\s]*enter a:[\s]*/.match(line)
|
||||
end while ! /[\s]*enter a:[\s]*/.match(line)
|
||||
$sp.print(a.to_s(16)+" ")
|
||||
begin
|
||||
line = $sp.gets()
|
||||
|
@ -197,7 +197,7 @@ def add_test(a,b)
|
|||
puts line
|
||||
return false
|
||||
end
|
||||
end while not /[\s]*enter b:[\s]*/.match(line)
|
||||
end while ! /[\s]*enter b:[\s]*/.match(line)
|
||||
$sp.print(b.to_s(16)+" ")
|
||||
begin
|
||||
line = $sp.gets()
|
||||
|
@ -207,7 +207,7 @@ def add_test(a,b)
|
|||
puts line
|
||||
return false
|
||||
end
|
||||
end while not m=/[\s]*([-]?[0-9a-fA-F]*)[\s]+\+[\s]+([+-]?[0-9a-fA-F]*)[\s]*=[\s]*([+-]?[0-9a-fA-F]*)/.match(line)
|
||||
end while ! m=/[\s]*([-]?[0-9a-fA-F]*)[\s]+\+[\s]+([+-]?[0-9a-fA-F]*)[\s]*=[\s]*([+-]?[0-9a-fA-F]*)/.match(line)
|
||||
a_ = m[1].to_i(16)
|
||||
b_ = m[2].to_i(16)
|
||||
c_ = m[3].to_i(16)
|
||||
|
@ -236,7 +236,7 @@ def mul_test(a,b)
|
|||
puts line
|
||||
return false
|
||||
end
|
||||
end while not /[\s]*enter a:[\s]*/.match(line)
|
||||
end while ! /[\s]*enter a:[\s]*/.match(line)
|
||||
$sp.print(a.to_s(16)+" ")
|
||||
begin
|
||||
line = $sp.gets()
|
||||
|
@ -246,7 +246,7 @@ def mul_test(a,b)
|
|||
puts line
|
||||
return false
|
||||
end
|
||||
end while not /[\s]*enter b:[\s]*/.match(line)
|
||||
end while ! /[\s]*enter b:[\s]*/.match(line)
|
||||
$sp.print(b.to_s(16)+" ")
|
||||
begin
|
||||
line = $sp.gets()
|
||||
|
@ -256,7 +256,7 @@ def mul_test(a,b)
|
|||
puts line
|
||||
return false
|
||||
end
|
||||
end while not m=/[\s]*([+-]?[0-9a-fA-F]*)[\s]+\*[\s]+([+-]?[0-9a-fA-F]*)[\s]*=[\s]*([+-]?[0-9a-fA-F]*)/.match(line)
|
||||
end while ! m=/[\s]*([+-]?[0-9a-fA-F]*)[\s]+\*[\s]+([+-]?[0-9a-fA-F]*)[\s]*=[\s]*([+-]?[0-9a-fA-F]*)/.match(line)
|
||||
a_ = m[1].to_i(16)
|
||||
b_ = m[2].to_i(16)
|
||||
c_ = m[3].to_i(16)
|
||||
|
@ -330,7 +330,7 @@ def square_test(a)
|
|||
puts line
|
||||
return false
|
||||
end
|
||||
end while not /[\s]*enter a:[\s]*/.match(line)
|
||||
end while ! /[\s]*enter a:[\s]*/.match(line)
|
||||
$sp.print(a.to_s(16)+" ")
|
||||
begin
|
||||
line = $sp.gets()
|
||||
|
@ -340,7 +340,7 @@ def square_test(a)
|
|||
puts line
|
||||
return false
|
||||
end
|
||||
end while not m=/[\s]*([+-]?[0-9a-fA-F]*)[\s]*\*\*2[\s]*=[\s]*([+-]?[0-9a-fA-F]*)/.match(line)
|
||||
end while ! m=/[\s]*([+-]?[0-9a-fA-F]*)[\s]*\*\*2[\s]*=[\s]*([+-]?[0-9a-fA-F]*)/.match(line)
|
||||
a_ = m[1].to_i(16)
|
||||
c_ = m[2].to_i(16)
|
||||
line.chomp!
|
||||
|
@ -368,7 +368,7 @@ def reduce_test(a,b)
|
|||
puts line
|
||||
return false
|
||||
end
|
||||
end while not /[\s]*enter a:[\s]*/.match(line)
|
||||
end while ! /[\s]*enter a:[\s]*/.match(line)
|
||||
$sp.print(a.to_s(16)+" ")
|
||||
begin
|
||||
line = $sp.gets()
|
||||
|
@ -378,7 +378,7 @@ def reduce_test(a,b)
|
|||
puts line
|
||||
return false
|
||||
end
|
||||
end while not /[\s]*enter b:[\s]*/.match(line)
|
||||
end while ! /[\s]*enter b:[\s]*/.match(line)
|
||||
$sp.print(b.to_s(16)+" ")
|
||||
line=''
|
||||
begin
|
||||
|
@ -390,7 +390,7 @@ def reduce_test(a,b)
|
|||
puts line
|
||||
return false
|
||||
end
|
||||
end while not m=/[\s]*([+-]?[0-9a-fA-F]*)[\s]+%[\s]+([+-]?[0-9a-fA-F]*)[\s]*=[\s]*([+-]?[0-9a-fA-F]+)/.match(line)
|
||||
end while ! m=/[\s]*([+-]?[0-9a-fA-F]*)[\s]+%[\s]+([+-]?[0-9a-fA-F]*)[\s]*=[\s]*([+-]?[0-9a-fA-F]+)/.match(line)
|
||||
a_ = m[1].to_i(16)
|
||||
b_ = m[2].to_i(16)
|
||||
c_ = m[3].to_i(16)
|
||||
|
@ -419,7 +419,7 @@ def expmod_test(a,b,c)
|
|||
puts line
|
||||
return false
|
||||
end
|
||||
end while not /[\s]*enter a:[\s]*/.match(line)
|
||||
end while ! /[\s]*enter a:[\s]*/.match(line)
|
||||
$sp.print(a.to_s(16)+" ")
|
||||
begin
|
||||
line = $sp.gets()
|
||||
|
@ -429,7 +429,7 @@ def expmod_test(a,b,c)
|
|||
puts line
|
||||
return false
|
||||
end
|
||||
end while not /[\s]*enter b:[\s]*/.match(line)
|
||||
end while ! /[\s]*enter b:[\s]*/.match(line)
|
||||
$sp.print(b.to_s(16)+" ")
|
||||
begin
|
||||
line = $sp.gets()
|
||||
|
@ -439,7 +439,7 @@ def expmod_test(a,b,c)
|
|||
puts line
|
||||
return false
|
||||
end
|
||||
end while not /[\s]*enter c:[\s]*/.match(line)
|
||||
end while ! /[\s]*enter c:[\s]*/.match(line)
|
||||
$sp.print(c.to_s(16)+" ")
|
||||
line=''
|
||||
begin
|
||||
|
@ -451,7 +451,7 @@ def expmod_test(a,b,c)
|
|||
puts line
|
||||
return false
|
||||
end
|
||||
end while not m=/[\s]*([+-]?[0-9a-fA-F]*)\*\*([+-]?[0-9a-fA-F]*)[\s]+%[\s]+([+-]?[0-9a-fA-F]*)[\s]*=[\s]*([+-]?[0-9a-fA-F]+)/.match(line)
|
||||
end while ! m=/[\s]*([+-]?[0-9a-fA-F]*)\*\*([+-]?[0-9a-fA-F]*)[\s]+%[\s]+([+-]?[0-9a-fA-F]*)[\s]*=[\s]*([+-]?[0-9a-fA-F]+)/.match(line)
|
||||
a_ = m[1].to_i(16)
|
||||
b_ = m[2].to_i(16)
|
||||
c_ = m[3].to_i(16)
|
||||
|
@ -481,7 +481,7 @@ def gcdext_test(a,b)
|
|||
puts line
|
||||
return false
|
||||
end
|
||||
end while not /[\s]*enter a:[\s]*/.match(line)
|
||||
end while ! /[\s]*enter a:[\s]*/.match(line)
|
||||
$sp.print(a.to_s(16)+" ")
|
||||
begin
|
||||
line = $sp.gets()
|
||||
|
@ -491,7 +491,7 @@ def gcdext_test(a,b)
|
|||
puts line
|
||||
return false
|
||||
end
|
||||
end while not /[\s]*enter b:[\s]*/.match(line)
|
||||
end while ! /[\s]*enter b:[\s]*/.match(line)
|
||||
$sp.print(b.to_s(16)+" ")
|
||||
line=''
|
||||
begin
|
||||
|
@ -504,7 +504,7 @@ def gcdext_test(a,b)
|
|||
puts line
|
||||
return false
|
||||
end
|
||||
end while not m=/gcdext\([\s]*([+-]?[0-9a-fA-F]*)[\s]*,[\s]*([+-]?[0-9a-fA-F]*)[\s]*\)[\s]*=> a = ([+-]?[0-9a-fA-F]+); b = ([+-]?[0-9a-fA-F]+); gcd = ([+-]?[0-9a-fA-F]+)/.match(line)
|
||||
end while ! m=/gcdext\([\s]*([+-]?[0-9a-fA-F]*)[\s]*,[\s]*([+-]?[0-9a-fA-F]*)[\s]*\)[\s]*=> a = ([+-]?[0-9a-fA-F]+); b = ([+-]?[0-9a-fA-F]+); gcd = ([+-]?[0-9a-fA-F]+)/.match(line)
|
||||
a_ = m[1].to_i(16)
|
||||
b_ = m[2].to_i(16)
|
||||
c_ = m[3].to_i(16)
|
||||
|
@ -834,12 +834,16 @@ if File.exists?(logfilename)
|
|||
i+=1
|
||||
end while(File.exists?(logfilename))
|
||||
while(i>2) do
|
||||
File.move(sprintf('%s%04d%s', conf['PORT']['testlogbase']+'bigint_',i-2,'.txt'),
|
||||
sprintf('%s%04d%s', conf['PORT']['testlogbase']+'bigint_',i-1,'.txt'), true)
|
||||
n1 = sprintf('%s%04d%s', conf['PORT']['testlogbase']+'bigint_',i-2,'.txt')
|
||||
n2 = sprintf('%s%04d%s', conf['PORT']['testlogbase']+'bigint_',i-1,'.txt')
|
||||
File.rename(n1, n2)
|
||||
printf("%s -> %s\n", n1, n2)
|
||||
i-=1
|
||||
end
|
||||
File.move(sprintf('%s%s', conf['PORT']['testlogbase'],'bigint.txt'),
|
||||
sprintf('%s%04d%s', conf['PORT']['testlogbase']+'bigint_',1,'.txt'), true)
|
||||
n1 = sprintf('%s%s', conf['PORT']['testlogbase'],'bigint.txt')
|
||||
n2 = sprintf('%s%04d%s', conf['PORT']['testlogbase']+'bigint_',1,'.txt')
|
||||
File.rename(n1, n2)
|
||||
printf("%s -> %s\n", n1, n2)
|
||||
logfilename = conf['PORT']['testlogbase']+'bigint.txt'
|
||||
end
|
||||
$logfile = File.open(logfilename, 'w')
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
CLI_STD = cli-stub.o cli-basics.o cli-core.o cli-hexdump.o debug.o hexdigit_tab.o \
|
||||
dbz_strings.o string-extras-asm.o uart_i-asm.o circularbytebuffer-asm.o
|
||||
dbz_strings.o string-extras-asm.o uart_i-asm.o circularbytebuffer-asm.o \
|
||||
main-test-common.o
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
# Makefile for RSA
|
||||
ALGO_NAME := RSA_OAEP
|
||||
|
||||
# comment out the following line for removement of RSA from the build process
|
||||
PK_CIPHERS += $(ALGO_NAME)
|
||||
|
||||
$(ALGO_NAME)_DIR := rsa/
|
||||
$(ALGO_NAME)_INCDIR := memxor/ bigint/ noekeon/ hfal/ sha1/ mgf1/
|
||||
$(ALGO_NAME)_OBJ := bigint.o bigint_io.o rsa_basic.o rsa_oaep.o mgf1.o hfal-basic.o hfal_sha1.o sha1.o
|
||||
$(ALGO_NAME)_TESTBIN := main-rsa_oaep-test.o $(CLI_STD) random_dummy.o \
|
||||
noekeon.o noekeon_prng.o memxor.o
|
||||
|
||||
$(ALGO_NAME)_PERFORMANCE_TEST := performance
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
/* random_dummy.c */
|
||||
/*
|
||||
This file is part of the ARM-Crypto-Lib.
|
||||
Copyright (C) 2006-2011 Daniel Otte (daniel.otte@rub.de)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "random_dummy.h"
|
||||
|
||||
uint8_t(*prng_get_byte)(void);
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/* random.h */
|
||||
/*
|
||||
This file is part of the AVR-Crypto-Lib.
|
||||
Copyright (C) 2011 Daniel Otte (daniel.otte@rub.de)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef RANDOM_H_
|
||||
#define RANDOM_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
extern uint8_t(*prng_get_byte)(void);
|
||||
|
||||
#endif /* RANDOM_H_ */
|
|
@ -0,0 +1,161 @@
|
|||
/* rsa_basic.c */
|
||||
/*
|
||||
This file is part of the ARM-Crypto-Lib.
|
||||
Copyright (C) 2006-2011 Daniel Otte (daniel.otte@rub.de)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "bigint.h"
|
||||
#include "bigint_io.h"
|
||||
#include "rsa_basic.h"
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
#if DEBUG
|
||||
#include "cli.h"
|
||||
#endif
|
||||
|
||||
void rsa_enc(bigint_t* data, rsa_publickey_t* key){
|
||||
/*
|
||||
cli_putstr_P(PSTR("\r\n -->rsa_enc()\r\n m = "));
|
||||
bigint_print_hex(data);
|
||||
cli_putstr_P(PSTR("\r\n e = "));
|
||||
bigint_print_hex(key->exponent);
|
||||
cli_putstr_P(PSTR("\r\n n = "));
|
||||
bigint_print_hex(key->modulus);
|
||||
*/
|
||||
bigint_expmod_u(data, data, key->exponent, key->modulus);
|
||||
}
|
||||
|
||||
/*
|
||||
(p,q,dp,dq,qinv)
|
||||
m1 = c**dp % p
|
||||
m2 = c**dq % q
|
||||
h = (m1 - m2) * qinv % p
|
||||
m = m2 + q * h
|
||||
*/
|
||||
|
||||
uint8_t rsa_dec_crt_mono(bigint_t* data, rsa_privatekey_t* key){
|
||||
bigint_t m1, m2;
|
||||
m1.wordv = malloc((key->modulus->length_B + 1) * sizeof(bigint_word_t));
|
||||
m2.wordv = malloc(key->components[1]->length_B * sizeof(bigint_word_t));
|
||||
if(!m1.wordv || !m2.wordv){
|
||||
#if DEBUG
|
||||
cli_putstr_P(PSTR("\r\nERROR: OOM! (" __FILE__ ")"));
|
||||
#endif
|
||||
free(m1.wordv);
|
||||
free(m2.wordv);
|
||||
return 1;
|
||||
}
|
||||
#if DEBUG
|
||||
cli_putstr_P(PSTR("\r\nexp_mod a + b "));
|
||||
#endif
|
||||
bigint_expmod_u(&m1, data, key->components[2], key->components[0]);
|
||||
bigint_expmod_u(&m2, data, key->components[3], key->components[1]);
|
||||
#if DEBUG
|
||||
cli_putstr_P(PSTR("[done] "));
|
||||
#endif
|
||||
bigint_sub_s(&m1, &m1, &m2);
|
||||
#if DEBUG
|
||||
cli_putstr_P(PSTR("[done2] "));
|
||||
#endif
|
||||
while(BIGINT_NEG_MASK & m1.info){
|
||||
#if DEBUG
|
||||
cli_putc(',');
|
||||
#endif
|
||||
bigint_add_s(&m1, &m1, key->components[0]);
|
||||
}
|
||||
#if DEBUG
|
||||
cli_putstr_P(PSTR("\r\nreduce_mul "));
|
||||
#endif
|
||||
bigint_reduce(&m1, key->components[0]);
|
||||
bigint_mul_u(&m1, &m1, key->components[4]);
|
||||
#if DEBUG
|
||||
cli_putstr_P(PSTR("[done]"));
|
||||
#endif
|
||||
bigint_reduce(&m1, key->components[0]);
|
||||
bigint_mul_u(&m1, &m1, key->components[1]);
|
||||
#if DEBUG
|
||||
cli_putstr_P(PSTR(" [done]"));
|
||||
#endif
|
||||
bigint_add_u(data, &m1, &m2);
|
||||
free(m1.wordv);
|
||||
free(m2.wordv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t rsa_dec(bigint_t* data, rsa_privatekey_t* key){
|
||||
if(key->n == 1){
|
||||
bigint_expmod_u(data, data, key->components[0], key->modulus);
|
||||
return 0;
|
||||
}
|
||||
if(key->n == 5){
|
||||
if (rsa_dec_crt_mono(data, key)){
|
||||
return 3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if(key->n<8 || (key->n-5)%3 != 0){
|
||||
return 1;
|
||||
}
|
||||
//rsa_dec_crt_multi(data, key, (key->n-5)/3);
|
||||
return 2;
|
||||
}
|
||||
|
||||
void rsa_os2ip(bigint_t* dest, const void* data, uint32_t length_B){
|
||||
uint8_t off;
|
||||
off = length_B % sizeof(bigint_word_t);
|
||||
if(!data){
|
||||
if(off){
|
||||
dest->wordv = realloc(dest->wordv, length_B + sizeof(bigint_word_t) - off);
|
||||
memmove((uint8_t*)dest->wordv+off, dest->wordv, length_B);
|
||||
memset(dest->wordv, 0, off);
|
||||
}
|
||||
}else{
|
||||
if(off){
|
||||
memcpy((uint8_t*)dest->wordv + off, data, length_B);
|
||||
memset(dest, 0, off);
|
||||
}else{
|
||||
memcpy(dest->wordv, data, length_B);
|
||||
}
|
||||
}
|
||||
dest->length_B = (length_B + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
|
||||
bigint_changeendianess(dest);
|
||||
bigint_adjust(dest);
|
||||
}
|
||||
|
||||
void rsa_i2osp(void* dest, bigint_t* src, uint16_t* out_length_B){
|
||||
*out_length_B = bigint_get_first_set_bit(src) / 8 + 1;
|
||||
if(dest){
|
||||
uint16_t i;
|
||||
for(i=*out_length_B; i>0; --i){
|
||||
*((uint8_t*)dest) = ((uint8_t*)src->wordv)[i-1];
|
||||
dest = (uint8_t*)dest + 1;
|
||||
}
|
||||
}else{
|
||||
uint8_t off;
|
||||
bigint_changeendianess(src);
|
||||
bigint_adjust(src);
|
||||
|
||||
off = bigint_get_last_set_bit(src)/8;
|
||||
if(off){
|
||||
memmove(src->wordv, (uint8_t*)src->wordv+off, *out_length_B);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/* rsa_basic.h */
|
||||
/*
|
||||
This file is part of the AVR-Crypto-Lib.
|
||||
Copyright (C) 2011 Daniel Otte (daniel.otte@rub.de)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef RSA_BASIC_H_
|
||||
#define RSA_BASIC_H_
|
||||
|
||||
#include "bigint.h"
|
||||
|
||||
typedef struct {
|
||||
bigint_t* exponent;
|
||||
bigint_t* modulus;
|
||||
} rsa_publickey_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t n;
|
||||
bigint_t* modulus;
|
||||
bigint_t** components;
|
||||
} rsa_privatekey_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
rsa_privatekey_t priv;
|
||||
rsa_publickey_t pub;
|
||||
} rsa_fullkey_t;
|
||||
|
||||
|
||||
void rsa_enc(bigint_t* data, rsa_publickey_t* key);
|
||||
uint8_t rsa_dec(bigint_t* data, rsa_privatekey_t* key);
|
||||
void rsa_os2ip(bigint_t* dest, const void* data, uint32_t length_B);
|
||||
void rsa_i2osp(void* dest, bigint_t* src, uint16_t* out_length_B);
|
||||
|
||||
#endif /* RSA_BASIC_H_ */
|
|
@ -0,0 +1,247 @@
|
|||
|
||||
/* rsa_oaep.c */
|
||||
/*
|
||||
This file is part of the ARM-Crypto-Lib.
|
||||
Copyright (C) 2006-2012 Daniel Otte (daniel.otte@rub.de)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "memxor.h"
|
||||
#include "mgf1.h"
|
||||
#include "bigint.h"
|
||||
#include "rsa_basic.h"
|
||||
#include "rsa_oaep.h"
|
||||
|
||||
#include "random_dummy.h"
|
||||
|
||||
#include "hfal/hfal_sha1.h"
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
#if DEBUG
|
||||
#include "cli.h"
|
||||
#endif
|
||||
|
||||
mgf1_parameter_t mgf1_default_parameter = {
|
||||
&sha1_desc
|
||||
};
|
||||
|
||||
rsa_oaep_parameter_t rsa_oaep_default_parameter = {
|
||||
mgf1,
|
||||
&sha1_desc,
|
||||
&mgf1_default_parameter
|
||||
};
|
||||
|
||||
rsa_label_t rsa_oaep_default_label = {
|
||||
0, NULL
|
||||
};
|
||||
|
||||
uint8_t rsa_encrypt_oaep(void* dest, uint16_t* out_length,
|
||||
const void* src, uint16_t length_B,
|
||||
rsa_publickey_t* key, const rsa_oaep_parameter_t *p,
|
||||
const rsa_label_t* label, const void* seed){
|
||||
|
||||
if(!p){
|
||||
p = &rsa_oaep_default_parameter;
|
||||
}
|
||||
if(!label){
|
||||
label = &rsa_oaep_default_label;
|
||||
}
|
||||
uint16_t hv_len = (hfal_hash_getHashsize(p->hf)+7)/8;
|
||||
if(length_B > bigint_length_B(key->modulus) - 2*hv_len - 2){
|
||||
/* message too long */
|
||||
return 1;
|
||||
}
|
||||
uint16_t buffer_len = bigint_length_B(key->modulus);
|
||||
#if DEBUG
|
||||
cli_putstr("\r\n buffer_len = ");
|
||||
cli_hexdump_rev(&buffer_len, 2);
|
||||
cli_putstr("\r\n modulus_len = ");
|
||||
cli_hexdump_rev(&key->modulus->length_B, 2);
|
||||
#endif
|
||||
uint8_t* buffer = (uint8_t*)dest;
|
||||
uint8_t off;
|
||||
/* the following needs some explanation:
|
||||
* off is the offset which is used for compensating the effect of
|
||||
* changeendian() when it operates on multi-byte words.
|
||||
* */
|
||||
off = (sizeof(bigint_word_t) - (bigint_get_first_set_bit(key->modulus)/8+1) % sizeof(bigint_word_t))
|
||||
% (sizeof(bigint_word_t));
|
||||
buffer += off;
|
||||
buffer_len -= off;
|
||||
uint8_t* seed_buffer = buffer + 1;
|
||||
uint16_t db_len = buffer_len - hv_len - 1;
|
||||
uint8_t* db = seed_buffer + hv_len;
|
||||
uint16_t maskbuffer_len = db_len>hv_len?db_len:hv_len;
|
||||
uint8_t maskbuffer[maskbuffer_len];
|
||||
bigint_t x;
|
||||
|
||||
memset(dest, 0, seed_buffer - buffer + off);
|
||||
memset(db + hv_len, 0, db_len - hv_len - length_B -1);
|
||||
hfal_hash_mem(p->hf, db, label->label, label->length_b);
|
||||
db[db_len - length_B - 1] = 0x01;
|
||||
memcpy(db+db_len - length_B, src, length_B);
|
||||
if(seed){
|
||||
memcpy(seed_buffer, seed, hv_len);
|
||||
}else{
|
||||
/* generate random seed */
|
||||
if(!prng_get_byte){
|
||||
return 2; /* ERROR: no random generator specified */
|
||||
}
|
||||
uint16_t i;
|
||||
for(i=0; i<hv_len; ++i){
|
||||
seed_buffer[i] = prng_get_byte();
|
||||
}
|
||||
}
|
||||
#if DEBUG
|
||||
cli_putstr("\r\n msg (raw, pre-feistel):\r\n");
|
||||
cli_hexdump_block(dest, bigint_length_B(key->modulus), 4, 16);
|
||||
#endif
|
||||
p->mgf(maskbuffer, seed_buffer, hv_len, db_len, p->mgf_parameter);
|
||||
memxor(db, maskbuffer, db_len);
|
||||
p->mgf(maskbuffer, db, db_len, hv_len, p->mgf_parameter);
|
||||
memxor(seed_buffer, maskbuffer, hv_len);
|
||||
#if DEBUG
|
||||
cli_putstr("\r\n msg (raw, post-feistel):\r\n");
|
||||
cli_hexdump_block(dest, bigint_length_B(key->modulus), 4, 16);
|
||||
#endif
|
||||
x.info = 0;
|
||||
x.length_B = key->modulus->length_B;
|
||||
x.wordv = dest;
|
||||
bigint_adjust(&x);
|
||||
rsa_os2ip(&x, NULL, bigint_length_B(key->modulus));
|
||||
#if DEBUG
|
||||
cli_putstr("\r\ninput-msg (pre enc):\r\n");
|
||||
cli_hexdump_rev(&src, 2);
|
||||
cli_hexdump_block(src, length_B, 4, 16);
|
||||
#endif
|
||||
rsa_enc(&x, key);
|
||||
#if DEBUG
|
||||
cli_putstr("\r\ninput-msg (post enc):\r\n");
|
||||
cli_hexdump_rev(&src, 2);
|
||||
cli_hexdump_block(src, length_B, 4, 16);
|
||||
#endif
|
||||
rsa_i2osp(NULL, &x, out_length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t rsa_decrypt_oaep(void* dest, uint16_t* out_length,
|
||||
const void* src, uint16_t length_B,
|
||||
rsa_privatekey_t* key, const rsa_oaep_parameter_t *p,
|
||||
const rsa_label_t* label, void* seed){
|
||||
|
||||
// cli_putstr("\r\n -->rsa_decrypt_oaep()"); uart_flush(0);
|
||||
if(!label){
|
||||
label = &rsa_oaep_default_label;
|
||||
}
|
||||
if(!p){
|
||||
p = &rsa_oaep_default_parameter;
|
||||
}
|
||||
uint16_t x_len, data_len;
|
||||
bigint_t x;
|
||||
uint16_t hv_len = hfal_hash_getHashsize(p->hf)/8;
|
||||
uint8_t label_hv[hv_len];
|
||||
uint16_t msg_len = bigint_get_first_set_bit(key->modulus) / 8 + 1;
|
||||
uint16_t db_len = msg_len - hv_len - 1;
|
||||
uint8_t maskbuffer[db_len>hv_len?db_len:hv_len];
|
||||
|
||||
uint8_t *seed_buffer = dest;
|
||||
uint8_t *db_buffer = seed_buffer + hv_len;
|
||||
|
||||
x_len = bigint_get_first_set_bit(key->modulus)/8;
|
||||
memset(dest, 0, bigint_length_B(key->modulus) - length_B);
|
||||
memcpy((uint8_t*)dest + bigint_length_B(key->modulus) - length_B, src, length_B);
|
||||
|
||||
// cli_putc('a'); uart_flush(0);
|
||||
|
||||
x.wordv = dest;
|
||||
x.length_B = key->modulus->length_B;
|
||||
x.info = 0;
|
||||
bigint_adjust(&x);
|
||||
|
||||
|
||||
// cli_putc('b'); uart_flush(0);
|
||||
rsa_os2ip(&x, NULL, bigint_length_B(key->modulus));
|
||||
#if DEBUG
|
||||
cli_putstr_P(PSTR("\r\n rsa decrypting ..."));
|
||||
#endif
|
||||
rsa_dec(&x, key);
|
||||
#if DEBUG
|
||||
cli_putstr_P(PSTR(" [done]"));
|
||||
#endif
|
||||
rsa_i2osp(NULL, &x, &data_len);
|
||||
|
||||
// cli_putstr("\r\n msg (raw, pre-move):\r\n");
|
||||
// cli_hexdump_block(dest, bigint_length_B(key->modulus), 4, 16);
|
||||
|
||||
if(data_len > x_len){
|
||||
return 7;
|
||||
}
|
||||
/*
|
||||
cli_putstr("\r\n moving some bytes; x_len = ");
|
||||
cli_hexdump_rev(&x_len, 2);
|
||||
cli_putstr(" data_len = ");
|
||||
cli_hexdump_rev(&data_len, 2);
|
||||
uart_flush(0);
|
||||
*/
|
||||
if(x_len != data_len){
|
||||
memmove((uint8_t*)dest + x_len - data_len, dest, data_len);
|
||||
// cli_putstr(" (oh, not dead yet?!)");
|
||||
// uart_flush(0);
|
||||
memset(dest, 0, x_len - data_len);
|
||||
}
|
||||
|
||||
hfal_hash_mem(p->hf, label_hv, label->label, label->length_b);
|
||||
/*
|
||||
cli_putstr("\r\n msg (raw, pre-feistel):\r\n");
|
||||
cli_hexdump_block(seed_buffer, bigint_length_B(key->modulus), 4, 16);
|
||||
uart_flush(0);
|
||||
*/
|
||||
p->mgf(maskbuffer, db_buffer, db_len, hv_len, p->mgf_parameter);
|
||||
memxor(seed_buffer, maskbuffer, hv_len);
|
||||
p->mgf(maskbuffer, seed_buffer, hv_len, db_len, p->mgf_parameter);
|
||||
memxor(db_buffer, maskbuffer, db_len);
|
||||
|
||||
if(memcmp(label_hv, db_buffer, hv_len)){
|
||||
// cli_putstr("\r\nDBG: DB:\r\n");
|
||||
// cli_hexdump_block(db_buffer, db_len, 4, 16);
|
||||
return 2;
|
||||
}
|
||||
|
||||
uint16_t ps_len=0;
|
||||
while(db_buffer[hv_len + ps_len++] == 0)
|
||||
;
|
||||
|
||||
--ps_len;
|
||||
if(db_buffer[hv_len + ps_len] != 1){
|
||||
return 3;
|
||||
}
|
||||
|
||||
if(seed){
|
||||
memcpy(seed, seed_buffer, hv_len);
|
||||
}
|
||||
|
||||
msg_len = db_len - hv_len - 1 - ps_len;
|
||||
memmove(dest, db_buffer + hv_len + ps_len + 1, msg_len);
|
||||
|
||||
*out_length = msg_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/* rsa_oaep.h */
|
||||
/*
|
||||
This file is part of the AVR-Crypto-Lib.
|
||||
Copyright (C) 2012 Daniel Otte (daniel.otte@rub.de)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef RSA_OAEP_H_
|
||||
#define RSA_OAEP_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "mgf1.h"
|
||||
|
||||
|
||||
void mgf1(void* dest, const void* seed, uint16_t seed_len_B, uint16_t out_length_B, const mgf1_parameter_t* p);
|
||||
|
||||
|
||||
typedef struct {
|
||||
void (*mgf)(void* dst, const void* seed, uint16_t slen_B, uint16_t dstlen_B, const mgf1_parameter_t* p);
|
||||
const hfdesc_t* hf;
|
||||
mgf1_parameter_t* mgf_parameter;
|
||||
} rsa_oaep_parameter_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t length_b;
|
||||
const void* label;
|
||||
} rsa_label_t;
|
||||
|
||||
extern rsa_oaep_parameter_t rsa_oaep_default_parameter;
|
||||
extern rsa_label_t rsa_oaep_default_label;
|
||||
|
||||
uint8_t rsa_encrypt_oaep(void* dest, uint16_t* out_length,
|
||||
const void* src, uint16_t length_B,
|
||||
rsa_publickey_t* key, const rsa_oaep_parameter_t *p,
|
||||
const rsa_label_t* label, const void* seed);
|
||||
|
||||
uint8_t rsa_decrypt_oaep(void* dest, uint16_t* out_length,
|
||||
const void* src, uint16_t length_B,
|
||||
rsa_privatekey_t* key, const rsa_oaep_parameter_t *p,
|
||||
const rsa_label_t* label, void* seed);
|
||||
|
||||
#endif /* RSA_OAEP_H_ */
|
|
@ -80,33 +80,40 @@ const uint8_t skipjack_ftable[] PROGMEM ={
|
|||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
static
|
||||
uint16_t skipjack_sub_g(uint8_t g, uint8_t k, uint8_t *key){
|
||||
return pgm_read_byte(&(skipjack_ftable[g ^ key[9 - k % 10]]));
|
||||
}
|
||||
|
||||
static
|
||||
uint16_t skipjack_g(uint16_t g, uint8_t k, uint8_t *key){
|
||||
#define G1 (((uint8_t*)&g)[1])
|
||||
#define G2 (((uint8_t*)&g)[0])
|
||||
/* this could also be rolled up */
|
||||
G1 ^= pgm_read_byte_near(&(skipjack_ftable[G2 ^ key[9-(4*k+0)%10]]));
|
||||
G2 ^= pgm_read_byte_near(&(skipjack_ftable[G1 ^ key[9-(4*k+1)%10]]));
|
||||
G1 ^= pgm_read_byte_near(&(skipjack_ftable[G2 ^ key[9-(4*k+2)%10]]));
|
||||
G2 ^= pgm_read_byte_near(&(skipjack_ftable[G1 ^ key[9-(4*k+3)%10]]));
|
||||
k *= 4;
|
||||
G1 ^= skipjack_sub_g(G2, k + 0, key);
|
||||
G2 ^= skipjack_sub_g(G1, k + 1, key);
|
||||
G1 ^= skipjack_sub_g(G2, k + 2, key);
|
||||
G2 ^= skipjack_sub_g(G1, k + 3, key);
|
||||
return g;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static
|
||||
uint16_t skipjack_g_inv(uint16_t g, uint8_t k, uint8_t *key){
|
||||
// #define G1 (((uint8_t)&g)[1])
|
||||
// #define G2 (((uint8_t)&g)[0])
|
||||
/* this could also be rolled up */
|
||||
G2 ^= pgm_read_byte_near(&(skipjack_ftable[G1 ^ key[9-(4*k+3)%10]]));
|
||||
G1 ^= pgm_read_byte_near(&(skipjack_ftable[G2 ^ key[9-(4*k+2)%10]]));
|
||||
G2 ^= pgm_read_byte_near(&(skipjack_ftable[G1 ^ key[9-(4*k+1)%10]]));
|
||||
G1 ^= pgm_read_byte_near(&(skipjack_ftable[G2 ^ key[9-(4*k+0)%10]]));
|
||||
return g;
|
||||
k *= 4;
|
||||
G2 ^= skipjack_sub_g(G1, k + 3, key);
|
||||
G1 ^= skipjack_sub_g(G2, k + 2, key);
|
||||
G2 ^= skipjack_sub_g(G1, k + 1, key);
|
||||
G1 ^= skipjack_sub_g(G2, k + 0, key);
|
||||
return g;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static
|
||||
void skipjack_a(uint16_t* w, uint8_t k, uint8_t* key){
|
||||
uint16_t t;
|
||||
t = w[0];
|
||||
|
@ -117,7 +124,7 @@ void skipjack_a(uint16_t* w, uint8_t k, uint8_t* key){
|
|||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static
|
||||
void skipjack_a_inv(uint16_t* w, uint8_t k, uint8_t* key){
|
||||
uint16_t t;
|
||||
t = w[3] ^ w[2];
|
||||
|
@ -128,7 +135,7 @@ void skipjack_a_inv(uint16_t* w, uint8_t k, uint8_t* key){
|
|||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static
|
||||
void skipjack_b(uint16_t* w, uint8_t k, uint8_t* key){
|
||||
uint16_t t;
|
||||
t = w[3];
|
||||
|
@ -139,7 +146,7 @@ void skipjack_b(uint16_t* w, uint8_t k, uint8_t* key){
|
|||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static
|
||||
void skipjack_b_inv(uint16_t* w, uint8_t k, uint8_t* key){
|
||||
uint16_t t;
|
||||
t = w[1];
|
||||
|
|
|
@ -182,7 +182,7 @@ cli_hexdump_block:
|
|||
brne 7f
|
||||
cp WIDTH, LENG_0
|
||||
breq 6f
|
||||
brmi 7f
|
||||
brcs 7f
|
||||
mov r22, LENG_0
|
||||
6: inc r4
|
||||
7:
|
||||
|
@ -190,7 +190,7 @@ cli_hexdump_block:
|
|||
add DATA_0, WIDTH
|
||||
adc DATA_1, r1
|
||||
sub LENG_0, WIDTH
|
||||
sbc LENG_0, r1
|
||||
sbc LENG_1, r1
|
||||
tst r4
|
||||
breq 2b
|
||||
pop r4
|
||||
|
|
|
@ -0,0 +1,810 @@
|
|||
/* main-dsa-test.c */
|
||||
/*
|
||||
This file is part of the ARM-Crypto-Lib.
|
||||
Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*
|
||||
* RSA test-suit
|
||||
*
|
||||
*/
|
||||
#include "main-test-common.h"
|
||||
|
||||
#include "noekeon.h"
|
||||
#include "noekeon_prng.h"
|
||||
#include "bigint.h"
|
||||
#include "bigint_io.h"
|
||||
#include "random_dummy.h"
|
||||
#include "rsa_basic.h"
|
||||
#include "rsa_oaep.h"
|
||||
|
||||
#include "performance_test.h"
|
||||
|
||||
const char* algo_name = "RSA-OAEP";
|
||||
|
||||
#define BIGINT_CEIL(x) ((((x) + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t)) * sizeof(bigint_word_t))
|
||||
#define BIGINT_OFF(x) ((sizeof(bigint_word_t) - (x) % sizeof(bigint_word_t)) % sizeof(bigint_word_t))
|
||||
|
||||
/*****************************************************************************
|
||||
* additional validation-functions *
|
||||
*****************************************************************************/
|
||||
#if 0
|
||||
/* ==================================
|
||||
* Example 1: A 1024-bit RSA Key Pair
|
||||
* ================================== */
|
||||
|
||||
/* ------------------------------
|
||||
* Components of the RSA Key Pair
|
||||
* ------------------------------ */
|
||||
|
||||
/* RSA modulus n: */
|
||||
const uint8_t modulus[] = {
|
||||
0xa8, 0xb3, 0xb2, 0x84, 0xaf, 0x8e, 0xb5, 0x0b, 0x38, 0x70, 0x34, 0xa8, 0x60, 0xf1, 0x46, 0xc4,
|
||||
0x91, 0x9f, 0x31, 0x87, 0x63, 0xcd, 0x6c, 0x55, 0x98, 0xc8, 0xae, 0x48, 0x11, 0xa1, 0xe0, 0xab,
|
||||
0xc4, 0xc7, 0xe0, 0xb0, 0x82, 0xd6, 0x93, 0xa5, 0xe7, 0xfc, 0xed, 0x67, 0x5c, 0xf4, 0x66, 0x85,
|
||||
0x12, 0x77, 0x2c, 0x0c, 0xbc, 0x64, 0xa7, 0x42, 0xc6, 0xc6, 0x30, 0xf5, 0x33, 0xc8, 0xcc, 0x72,
|
||||
0xf6, 0x2a, 0xe8, 0x33, 0xc4, 0x0b, 0xf2, 0x58, 0x42, 0xe9, 0x84, 0xbb, 0x78, 0xbd, 0xbf, 0x97,
|
||||
0xc0, 0x10, 0x7d, 0x55, 0xbd, 0xb6, 0x62, 0xf5, 0xc4, 0xe0, 0xfa, 0xb9, 0x84, 0x5c, 0xb5, 0x14,
|
||||
0x8e, 0xf7, 0x39, 0x2d, 0xd3, 0xaa, 0xff, 0x93, 0xae, 0x1e, 0x6b, 0x66, 0x7b, 0xb3, 0xd4, 0x24,
|
||||
0x76, 0x16, 0xd4, 0xf5, 0xba, 0x10, 0xd4, 0xcf, 0xd2, 0x26, 0xde, 0x88, 0xd3, 0x9f, 0x16, 0xfb
|
||||
};
|
||||
|
||||
/* RSA public exponent e: */
|
||||
const uint8_t public_exponent[] = {
|
||||
0x00, 0x01, 0x00, 0x01
|
||||
};
|
||||
|
||||
/* RSA private exponent d: */
|
||||
const uint8_t private_exponent[] = {
|
||||
0x53, 0x33, 0x9c, 0xfd, 0xb7, 0x9f, 0xc8, 0x46, 0x6a, 0x65, 0x5c, 0x73, 0x16, 0xac, 0xa8, 0x5c,
|
||||
0x55, 0xfd, 0x8f, 0x6d, 0xd8, 0x98, 0xfd, 0xaf, 0x11, 0x95, 0x17, 0xef, 0x4f, 0x52, 0xe8, 0xfd,
|
||||
0x8e, 0x25, 0x8d, 0xf9, 0x3f, 0xee, 0x18, 0x0f, 0xa0, 0xe4, 0xab, 0x29, 0x69, 0x3c, 0xd8, 0x3b,
|
||||
0x15, 0x2a, 0x55, 0x3d, 0x4a, 0xc4, 0xd1, 0x81, 0x2b, 0x8b, 0x9f, 0xa5, 0xaf, 0x0e, 0x7f, 0x55,
|
||||
0xfe, 0x73, 0x04, 0xdf, 0x41, 0x57, 0x09, 0x26, 0xf3, 0x31, 0x1f, 0x15, 0xc4, 0xd6, 0x5a, 0x73,
|
||||
0x2c, 0x48, 0x31, 0x16, 0xee, 0x3d, 0x3d, 0x2d, 0x0a, 0xf3, 0x54, 0x9a, 0xd9, 0xbf, 0x7c, 0xbf,
|
||||
0xb7, 0x8a, 0xd8, 0x84, 0xf8, 0x4d, 0x5b, 0xeb, 0x04, 0x72, 0x4d, 0xc7, 0x36, 0x9b, 0x31, 0xde,
|
||||
0xf3, 0x7d, 0x0c, 0xf5, 0x39, 0xe9, 0xcf, 0xcd, 0xd3, 0xde, 0x65, 0x37, 0x29, 0xea, 0xd5, 0xd1
|
||||
};
|
||||
|
||||
/* Prime p: */
|
||||
const uint8_t p[] = {
|
||||
0xd3, 0x27, 0x37, 0xe7, 0x26, 0x7f, 0xfe, 0x13, 0x41, 0xb2, 0xd5, 0xc0, 0xd1, 0x50, 0xa8, 0x1b,
|
||||
0x58, 0x6f, 0xb3, 0x13, 0x2b, 0xed, 0x2f, 0x8d, 0x52, 0x62, 0x86, 0x4a, 0x9c, 0xb9, 0xf3, 0x0a,
|
||||
0xf3, 0x8b, 0xe4, 0x48, 0x59, 0x8d, 0x41, 0x3a, 0x17, 0x2e, 0xfb, 0x80, 0x2c, 0x21, 0xac, 0xf1,
|
||||
0xc1, 0x1c, 0x52, 0x0c, 0x2f, 0x26, 0xa4, 0x71, 0xdc, 0xad, 0x21, 0x2e, 0xac, 0x7c, 0xa3, 0x9d
|
||||
};
|
||||
|
||||
/* Prime q: */
|
||||
const uint8_t q[] = {
|
||||
0xcc, 0x88, 0x53, 0xd1, 0xd5, 0x4d, 0xa6, 0x30, 0xfa, 0xc0, 0x04, 0xf4, 0x71, 0xf2, 0x81, 0xc7,
|
||||
0xb8, 0x98, 0x2d, 0x82, 0x24, 0xa4, 0x90, 0xed, 0xbe, 0xb3, 0x3d, 0x3e, 0x3d, 0x5c, 0xc9, 0x3c,
|
||||
0x47, 0x65, 0x70, 0x3d, 0x1d, 0xd7, 0x91, 0x64, 0x2f, 0x1f, 0x11, 0x6a, 0x0d, 0xd8, 0x52, 0xbe,
|
||||
0x24, 0x19, 0xb2, 0xaf, 0x72, 0xbf, 0xe9, 0xa0, 0x30, 0xe8, 0x60, 0xb0, 0x28, 0x8b, 0x5d, 0x77
|
||||
};
|
||||
|
||||
/* p's CRT exponent dP: */
|
||||
const uint8_t dp[] = {
|
||||
0x0e, 0x12, 0xbf, 0x17, 0x18, 0xe9, 0xce, 0xf5, 0x59, 0x9b, 0xa1, 0xc3, 0x88, 0x2f, 0xe8, 0x04,
|
||||
0x6a, 0x90, 0x87, 0x4e, 0xef, 0xce, 0x8f, 0x2c, 0xcc, 0x20, 0xe4, 0xf2, 0x74, 0x1f, 0xb0, 0xa3,
|
||||
0x3a, 0x38, 0x48, 0xae, 0xc9, 0xc9, 0x30, 0x5f, 0xbe, 0xcb, 0xd2, 0xd7, 0x68, 0x19, 0x96, 0x7d,
|
||||
0x46, 0x71, 0xac, 0xc6, 0x43, 0x1e, 0x40, 0x37, 0x96, 0x8d, 0xb3, 0x78, 0x78, 0xe6, 0x95, 0xc1
|
||||
};
|
||||
|
||||
/* q's CRT exponent dQ: */
|
||||
const uint8_t dq[] = {
|
||||
0x95, 0x29, 0x7b, 0x0f, 0x95, 0xa2, 0xfa, 0x67, 0xd0, 0x07, 0x07, 0xd6, 0x09, 0xdf, 0xd4, 0xfc,
|
||||
0x05, 0xc8, 0x9d, 0xaf, 0xc2, 0xef, 0x6d, 0x6e, 0xa5, 0x5b, 0xec, 0x77, 0x1e, 0xa3, 0x33, 0x73,
|
||||
0x4d, 0x92, 0x51, 0xe7, 0x90, 0x82, 0xec, 0xda, 0x86, 0x6e, 0xfe, 0xf1, 0x3c, 0x45, 0x9e, 0x1a,
|
||||
0x63, 0x13, 0x86, 0xb7, 0xe3, 0x54, 0xc8, 0x99, 0xf5, 0xf1, 0x12, 0xca, 0x85, 0xd7, 0x15, 0x83
|
||||
};
|
||||
|
||||
/* CRT coefficient qInv: */
|
||||
const uint8_t qinv[] = {
|
||||
0x4f, 0x45, 0x6c, 0x50, 0x24, 0x93, 0xbd, 0xc0, 0xed, 0x2a, 0xb7, 0x56, 0xa3, 0xa6, 0xed, 0x4d,
|
||||
0x67, 0x35, 0x2a, 0x69, 0x7d, 0x42, 0x16, 0xe9, 0x32, 0x12, 0xb1, 0x27, 0xa6, 0x3d, 0x54, 0x11,
|
||||
0xce, 0x6f, 0xa9, 0x8d, 0x5d, 0xbe, 0xfd, 0x73, 0x26, 0x3e, 0x37, 0x28, 0x14, 0x27, 0x43, 0x81,
|
||||
0x81, 0x66, 0xed, 0x7d, 0xd6, 0x36, 0x87, 0xdd, 0x2a, 0x8c, 0xa1, 0xd2, 0xf4, 0xfb, 0xd8, 0xe1
|
||||
};
|
||||
|
||||
/* ---------------------------------
|
||||
* RSAES-OAEP Encryption Example 1.1
|
||||
* --------------------------------- */
|
||||
|
||||
/* Message to be, encrypted: */
|
||||
const uint8_t message[] = {
|
||||
0x66, 0x28, 0x19, 0x4e, 0x12, 0x07, 0x3d, 0xb0, 0x3b, 0xa9, 0x4c, 0xda, 0x9e, 0xf9, 0x53, 0x23,
|
||||
0x97, 0xd5, 0x0d, 0xba, 0x79, 0xb9, 0x87, 0x00, 0x4a, 0xfe, 0xfe, 0x34
|
||||
};
|
||||
|
||||
/* Seed: */
|
||||
const uint8_t seed[] = {
|
||||
0x18, 0xb7, 0x76, 0xea, 0x21, 0x06, 0x9d, 0x69, 0x77, 0x6a, 0x33, 0xe9, 0x6b, 0xad, 0x48, 0xe1,
|
||||
0xdd, 0xa0, 0xa5, 0xef
|
||||
};
|
||||
|
||||
/* Encryption: */
|
||||
const uint8_t encrypted[] = {
|
||||
0x35, 0x4f, 0xe6, 0x7b, 0x4a, 0x12, 0x6d, 0x5d, 0x35, 0xfe, 0x36, 0xc7, 0x77, 0x79, 0x1a, 0x3f,
|
||||
0x7b, 0xa1, 0x3d, 0xef, 0x48, 0x4e, 0x2d, 0x39, 0x08, 0xaf, 0xf7, 0x22, 0xfa, 0xd4, 0x68, 0xfb,
|
||||
0x21, 0x69, 0x6d, 0xe9, 0x5d, 0x0b, 0xe9, 0x11, 0xc2, 0xd3, 0x17, 0x4f, 0x8a, 0xfc, 0xc2, 0x01,
|
||||
0x03, 0x5f, 0x7b, 0x6d, 0x8e, 0x69, 0x40, 0x2d, 0xe5, 0x45, 0x16, 0x18, 0xc2, 0x1a, 0x53, 0x5f,
|
||||
0xa9, 0xd7, 0xbf, 0xc5, 0xb8, 0xdd, 0x9f, 0xc2, 0x43, 0xf8, 0xcf, 0x92, 0x7d, 0xb3, 0x13, 0x22,
|
||||
0xd6, 0xe8, 0x81, 0xea, 0xa9, 0x1a, 0x99, 0x61, 0x70, 0xe6, 0x57, 0xa0, 0x5a, 0x26, 0x64, 0x26,
|
||||
0xd9, 0x8c, 0x88, 0x00, 0x3f, 0x84, 0x77, 0xc1, 0x22, 0x70, 0x94, 0xa0, 0xd9, 0xfa, 0x1e, 0x8c,
|
||||
0x40, 0x24, 0x30, 0x9c, 0xe1, 0xec, 0xcc, 0xb5, 0x21, 0x00, 0x35, 0xd4, 0x7a, 0xc7, 0x2e, 0x8a
|
||||
};
|
||||
|
||||
/* Message to be encrypted: */
|
||||
const uint8_t message2[] = {
|
||||
0x75, 0x0c, 0x40, 0x47, 0xf5, 0x47, 0xe8, 0xe4, 0x14, 0x11, 0x85, 0x65, 0x23, 0x29, 0x8a, 0xc9,
|
||||
0xba, 0xe2, 0x45, 0xef, 0xaf, 0x13, 0x97, 0xfb, 0xe5, 0x6f, 0x9d, 0xd5
|
||||
};
|
||||
|
||||
/* Seed: */
|
||||
const uint8_t seed2[] = {
|
||||
0x0c, 0xc7, 0x42, 0xce, 0x4a, 0x9b, 0x7f, 0x32, 0xf9, 0x51, 0xbc, 0xb2, 0x51, 0xef, 0xd9, 0x25,
|
||||
0xfe, 0x4f, 0xe3, 0x5f
|
||||
};
|
||||
|
||||
/* Encryption: */
|
||||
const uint8_t encrypted2[] = {
|
||||
0x64, 0x0d, 0xb1, 0xac, 0xc5, 0x8e, 0x05, 0x68, 0xfe, 0x54, 0x07, 0xe5, 0xf9, 0xb7, 0x01, 0xdf,
|
||||
0xf8, 0xc3, 0xc9, 0x1e, 0x71, 0x6c, 0x53, 0x6f, 0xc7, 0xfc, 0xec, 0x6c, 0xb5, 0xb7, 0x1c, 0x11,
|
||||
0x65, 0x98, 0x8d, 0x4a, 0x27, 0x9e, 0x15, 0x77, 0xd7, 0x30, 0xfc, 0x7a, 0x29, 0x93, 0x2e, 0x3f,
|
||||
0x00, 0xc8, 0x15, 0x15, 0x23, 0x6d, 0x8d, 0x8e, 0x31, 0x01, 0x7a, 0x7a, 0x09, 0xdf, 0x43, 0x52,
|
||||
0xd9, 0x04, 0xcd, 0xeb, 0x79, 0xaa, 0x58, 0x3a, 0xdc, 0xc3, 0x1e, 0xa6, 0x98, 0xa4, 0xc0, 0x52,
|
||||
0x83, 0xda, 0xba, 0x90, 0x89, 0xbe, 0x54, 0x91, 0xf6, 0x7c, 0x1a, 0x4e, 0xe4, 0x8d, 0xc7, 0x4b,
|
||||
0xbb, 0xe6, 0x64, 0x3a, 0xef, 0x84, 0x66, 0x79, 0xb4, 0xcb, 0x39, 0x5a, 0x35, 0x2d, 0x5e, 0xd1,
|
||||
0x15, 0x91, 0x2d, 0xf6, 0x96, 0xff, 0xe0, 0x70, 0x29, 0x32, 0x94, 0x6d, 0x71, 0x49, 0x2b, 0x44
|
||||
};
|
||||
|
||||
/**********************************************************************************************/
|
||||
/* ---------------------------------
|
||||
* RSAES-OAEP Encryption Example 2.1
|
||||
* --------------------------------- */
|
||||
|
||||
/* Message to be encrypted: */
|
||||
const uint8_t message3[] = {
|
||||
0x8f, 0xf0, 0x0c, 0xaa, 0x60, 0x5c, 0x70, 0x28, 0x30, 0x63, 0x4d, 0x9a, 0x6c, 0x3d, 0x42, 0xc6,
|
||||
0x52, 0xb5, 0x8c, 0xf1, 0xd9, 0x2f, 0xec, 0x57, 0x0b, 0xee, 0xe7
|
||||
};
|
||||
|
||||
/* Seed: */
|
||||
const uint8_t seed3[] = {
|
||||
0x8c, 0x40, 0x7b, 0x5e, 0xc2, 0x89, 0x9e, 0x50, 0x99, 0xc5, 0x3e, 0x8c, 0xe7, 0x93, 0xbf, 0x94,
|
||||
0xe7, 0x1b, 0x17, 0x82
|
||||
};
|
||||
|
||||
/* Encryption: */
|
||||
const uint8_t encrypted3[] = {
|
||||
0x01, 0x81, 0xaf, 0x89, 0x22, 0xb9, 0xfc, 0xb4, 0xd7, 0x9d, 0x92, 0xeb, 0xe1, 0x98, 0x15, 0x99,
|
||||
0x2f, 0xc0, 0xc1, 0x43, 0x9d, 0x8b, 0xcd, 0x49, 0x13, 0x98, 0xa0, 0xf4, 0xad, 0x3a, 0x32, 0x9a,
|
||||
0x5b, 0xd9, 0x38, 0x55, 0x60, 0xdb, 0x53, 0x26, 0x83, 0xc8, 0xb7, 0xda, 0x04, 0xe4, 0xb1, 0x2a,
|
||||
0xed, 0x6a, 0xac, 0xdf, 0x47, 0x1c, 0x34, 0xc9, 0xcd, 0xa8, 0x91, 0xad, 0xdc, 0xc2, 0xdf, 0x34,
|
||||
0x56, 0x65, 0x3a, 0xa6, 0x38, 0x2e, 0x9a, 0xe5, 0x9b, 0x54, 0x45, 0x52, 0x57, 0xeb, 0x09, 0x9d,
|
||||
0x56, 0x2b, 0xbe, 0x10, 0x45, 0x3f, 0x2b, 0x6d, 0x13, 0xc5, 0x9c, 0x02, 0xe1, 0x0f, 0x1f, 0x8a,
|
||||
0xbb, 0x5d, 0xa0, 0xd0, 0x57, 0x09, 0x32, 0xda, 0xcf, 0x2d, 0x09, 0x01, 0xdb, 0x72, 0x9d, 0x0f,
|
||||
0xef, 0xcc, 0x05, 0x4e, 0x70, 0x96, 0x8e, 0xa5, 0x40, 0xc8, 0x1b, 0x04, 0xbc, 0xae, 0xfe, 0x72,
|
||||
0x0e
|
||||
};
|
||||
#endif
|
||||
/**********************************************************************************************/
|
||||
|
||||
/* ---------------------------------
|
||||
* RSAES-OAEP Encryption Example 2.4
|
||||
* --------------------------------- */
|
||||
|
||||
/* Message to be encrypted: */
|
||||
const uint8_t message4[] PROGMEM = {
|
||||
0xa7, 0xeb, 0x2a, 0x50, 0x36, 0x93, 0x1d, 0x27, 0xd4, 0xe8, 0x91, 0x32, 0x6d, 0x99, 0x69, 0x2f,
|
||||
0xfa, 0xdd, 0xa9, 0xbf, 0x7e, 0xfd, 0x3e, 0x34, 0xe6, 0x22, 0xc4, 0xad, 0xc0, 0x85, 0xf7, 0x21,
|
||||
0xdf, 0xe8, 0x85, 0x07, 0x2c, 0x78, 0xa2, 0x03, 0xb1, 0x51, 0x73, 0x9b, 0xe5, 0x40, 0xfa, 0x8c,
|
||||
0x15, 0x3a, 0x10, 0xf0, 0x0a
|
||||
};
|
||||
|
||||
/* Seed: */
|
||||
const uint8_t seed4[] PROGMEM = {
|
||||
0x9a, 0x7b, 0x3b, 0x0e, 0x70, 0x8b, 0xd9, 0x6f, 0x81, 0x90, 0xec, 0xab, 0x4f, 0xb9, 0xb2, 0xb3,
|
||||
0x80, 0x5a, 0x81, 0x56
|
||||
};
|
||||
|
||||
/* Encryption: */
|
||||
const uint8_t encrypted4[] PROGMEM = {
|
||||
/* 0x00,*/ 0xa4, 0x57, 0x8c, 0xbc, 0x17, 0x63, 0x18, 0xa6, 0x38, 0xfb, 0xa7, 0xd0, 0x1d, 0xf1, 0x57,
|
||||
0x46, 0xaf, 0x44, 0xd4, 0xf6, 0xcd, 0x96, 0xd7, 0xe7, 0xc4, 0x95, 0xcb, 0xf4, 0x25, 0xb0, 0x9c,
|
||||
0x64, 0x9d, 0x32, 0xbf, 0x88, 0x6d, 0xa4, 0x8f, 0xba, 0xf9, 0x89, 0xa2, 0x11, 0x71, 0x87, 0xca,
|
||||
0xfb, 0x1f, 0xb5, 0x80, 0x31, 0x76, 0x90, 0xe3, 0xcc, 0xd4, 0x46, 0x92, 0x0b, 0x7a, 0xf8, 0x2b,
|
||||
0x31, 0xdb, 0x58, 0x04, 0xd8, 0x7d, 0x01, 0x51, 0x4a, 0xcb, 0xfa, 0x91, 0x56, 0xe7, 0x82, 0xf8,
|
||||
0x67, 0xf6, 0xbe, 0xd9, 0x44, 0x9e, 0x0e, 0x9a, 0x2c, 0x09, 0xbc, 0xec, 0xc6, 0xaa, 0x08, 0x76,
|
||||
0x36, 0x96, 0x5e, 0x34, 0xb3, 0xec, 0x76, 0x6f, 0x2f, 0xe2, 0xe4, 0x30, 0x18, 0xa2, 0xfd, 0xde,
|
||||
0xb1, 0x40, 0x61, 0x6a, 0x0e, 0x9d, 0x82, 0xe5, 0x33, 0x10, 0x24, 0xee, 0x06, 0x52, 0xfc, 0x76,
|
||||
0x41
|
||||
};
|
||||
|
||||
/**********************************************************************************************/
|
||||
#if 1
|
||||
/* RSA modulus n: */
|
||||
const uint8_t modulus2[] PROGMEM = {
|
||||
0x01, 0x94, 0x7c, 0x7f, 0xce, 0x90, 0x42, 0x5f, 0x47, 0x27, 0x9e, 0x70, 0x85, 0x1f, 0x25, 0xd5,
|
||||
0xe6, 0x23, 0x16, 0xfe, 0x8a, 0x1d, 0xf1, 0x93, 0x71, 0xe3, 0xe6, 0x28, 0xe2, 0x60, 0x54, 0x3e,
|
||||
0x49, 0x01, 0xef, 0x60, 0x81, 0xf6, 0x8c, 0x0b, 0x81, 0x41, 0x19, 0x0d, 0x2a, 0xe8, 0xda, 0xba,
|
||||
0x7d, 0x12, 0x50, 0xec, 0x6d, 0xb6, 0x36, 0xe9, 0x44, 0xec, 0x37, 0x22, 0x87, 0x7c, 0x7c, 0x1d,
|
||||
0x0a, 0x67, 0xf1, 0x4b, 0x16, 0x94, 0xc5, 0xf0, 0x37, 0x94, 0x51, 0xa4, 0x3e, 0x49, 0xa3, 0x2d,
|
||||
0xde, 0x83, 0x67, 0x0b, 0x73, 0xda, 0x91, 0xa1, 0xc9, 0x9b, 0xc2, 0x3b, 0x43, 0x6a, 0x60, 0x05,
|
||||
0x5c, 0x61, 0x0f, 0x0b, 0xaf, 0x99, 0xc1, 0xa0, 0x79, 0x56, 0x5b, 0x95, 0xa3, 0xf1, 0x52, 0x66,
|
||||
0x32, 0xd1, 0xd4, 0xda, 0x60, 0xf2, 0x0e, 0xda, 0x25, 0xe6, 0x53, 0xc4, 0xf0, 0x02, 0x76, 0x6f,
|
||||
0x45
|
||||
};
|
||||
|
||||
/* RSA public exponent e: */
|
||||
const uint8_t public_exponent2[] PROGMEM = {
|
||||
0x01, 0x00, 0x01
|
||||
};
|
||||
|
||||
/* RSA private exponent d: */
|
||||
const uint8_t private_exponent2[] PROGMEM = {
|
||||
0x08, 0x23, 0xf2, 0x0f, 0xad, 0xb5, 0xda, 0x89, 0x08, 0x8a, 0x9d, 0x00, 0x89, 0x3e, 0x21, 0xfa,
|
||||
0x4a, 0x1b, 0x11, 0xfb, 0xc9, 0x3c, 0x64, 0xa3, 0xbe, 0x0b, 0xaa, 0xea, 0x97, 0xfb, 0x3b, 0x93,
|
||||
0xc3, 0xff, 0x71, 0x37, 0x04, 0xc1, 0x9c, 0x96, 0x3c, 0x1d, 0x10, 0x7a, 0xae, 0x99, 0x05, 0x47,
|
||||
0x39, 0xf7, 0x9e, 0x02, 0xe1, 0x86, 0xde, 0x86, 0xf8, 0x7a, 0x6d, 0xde, 0xfe, 0xa6, 0xd8, 0xcc,
|
||||
0xd1, 0xd3, 0xc8, 0x1a, 0x47, 0xbf, 0xa7, 0x25, 0x5b, 0xe2, 0x06, 0x01, 0xa4, 0xa4, 0xb2, 0xf0,
|
||||
0x8a, 0x16, 0x7b, 0x5e, 0x27, 0x9d, 0x71, 0x5b, 0x1b, 0x45, 0x5b, 0xdd, 0x7e, 0xab, 0x24, 0x59,
|
||||
0x41, 0xd9, 0x76, 0x8b, 0x9a, 0xce, 0xfb, 0x3c, 0xcd, 0xa5, 0x95, 0x2d, 0xa3, 0xce, 0xe7, 0x25,
|
||||
0x25, 0xb4, 0x50, 0x16, 0x63, 0xa8, 0xee, 0x15, 0xc9, 0xe9, 0x92, 0xd9, 0x24, 0x62, 0xfe, 0x39
|
||||
};
|
||||
|
||||
/* Prime p: */
|
||||
const uint8_t p2[] PROGMEM = {
|
||||
0x01, 0x59, 0xdb, 0xde, 0x04, 0xa3, 0x3e, 0xf0, 0x6f, 0xb6, 0x08, 0xb8, 0x0b, 0x19, 0x0f, 0x4d,
|
||||
0x3e, 0x22, 0xbc, 0xc1, 0x3a, 0xc8, 0xe4, 0xa0, 0x81, 0x03, 0x3a, 0xbf, 0xa4, 0x16, 0xed, 0xb0,
|
||||
0xb3, 0x38, 0xaa, 0x08, 0xb5, 0x73, 0x09, 0xea, 0x5a, 0x52, 0x40, 0xe7, 0xdc, 0x6e, 0x54, 0x37,
|
||||
0x8c, 0x69, 0x41, 0x4c, 0x31, 0xd9, 0x7d, 0xdb, 0x1f, 0x40, 0x6d, 0xb3, 0x76, 0x9c, 0xc4, 0x1a,
|
||||
0x43
|
||||
};
|
||||
|
||||
/* Prime q: */
|
||||
const uint8_t q2[] PROGMEM = {
|
||||
0x01, 0x2b, 0x65, 0x2f, 0x30, 0x40, 0x3b, 0x38, 0xb4, 0x09, 0x95, 0xfd, 0x6f, 0xf4, 0x1a, 0x1a,
|
||||
0xcc, 0x8a, 0xda, 0x70, 0x37, 0x32, 0x36, 0xb7, 0x20, 0x2d, 0x39, 0xb2, 0xee, 0x30, 0xcf, 0xb4,
|
||||
0x6d, 0xb0, 0x95, 0x11, 0xf6, 0xf3, 0x07, 0xcc, 0x61, 0xcc, 0x21, 0x60, 0x6c, 0x18, 0xa7, 0x5b,
|
||||
0x8a, 0x62, 0xf8, 0x22, 0xdf, 0x03, 0x1b, 0xa0, 0xdf, 0x0d, 0xaf, 0xd5, 0x50, 0x6f, 0x56, 0x8b,
|
||||
0xd7
|
||||
};
|
||||
|
||||
/* p's CRT exponent dP: */
|
||||
const uint8_t dp2[] PROGMEM = {
|
||||
0x43, 0x6e, 0xf5, 0x08, 0xde, 0x73, 0x65, 0x19, 0xc2, 0xda, 0x4c, 0x58, 0x0d, 0x98, 0xc8, 0x2c,
|
||||
0xb7, 0x45, 0x2a, 0x3f, 0xb5, 0xef, 0xad, 0xc3, 0xb9, 0xc7, 0x78, 0x9a, 0x1b, 0xc6, 0x58, 0x4f,
|
||||
0x79, 0x5a, 0xdd, 0xbb, 0xd3, 0x24, 0x39, 0xc7, 0x46, 0x86, 0x55, 0x2e, 0xcb, 0x6c, 0x2c, 0x30,
|
||||
0x7a, 0x4d, 0x3a, 0xf7, 0xf5, 0x39, 0xee, 0xc1, 0x57, 0x24, 0x8c, 0x7b, 0x31, 0xf1, 0xa2, 0x55
|
||||
};
|
||||
|
||||
/* q's CRT exponent dQ: */
|
||||
const uint8_t dq2[] PROGMEM = {
|
||||
0x01, 0x2b, 0x15, 0xa8, 0x9f, 0x3d, 0xfb, 0x2b, 0x39, 0x07, 0x3e, 0x73, 0xf0, 0x2b, 0xdd, 0x0c,
|
||||
0x1a, 0x7b, 0x37, 0x9d, 0xd4, 0x35, 0xf0, 0x5c, 0xdd, 0xe2, 0xef, 0xf9, 0xe4, 0x62, 0x94, 0x8b,
|
||||
0x7c, 0xec, 0x62, 0xee, 0x90, 0x50, 0xd5, 0xe0, 0x81, 0x6e, 0x07, 0x85, 0xa8, 0x56, 0xb4, 0x91,
|
||||
0x08, 0xdc, 0xb7, 0x5f, 0x36, 0x83, 0x87, 0x4d, 0x1c, 0xa6, 0x32, 0x9a, 0x19, 0x01, 0x30, 0x66,
|
||||
0xff
|
||||
};
|
||||
|
||||
/* CRT coefficient qInv: */
|
||||
const uint8_t qinv2[] PROGMEM = {
|
||||
0x02, 0x70, 0xdb, 0x17, 0xd5, 0x91, 0x4b, 0x01, 0x8d, 0x76, 0x11, 0x8b, 0x24, 0x38, 0x9a, 0x73,
|
||||
0x50, 0xec, 0x83, 0x6b, 0x00, 0x63, 0xa2, 0x17, 0x21, 0x23, 0x6f, 0xd8, 0xed, 0xb6, 0xd8, 0x9b,
|
||||
0x51, 0xe7, 0xee, 0xb8, 0x7b, 0x61, 0x1b, 0x71, 0x32, 0xcb, 0x7e, 0xa7, 0x35, 0x6c, 0x23, 0x15,
|
||||
0x1c, 0x1e, 0x77, 0x51, 0x50, 0x7c, 0x78, 0x6d, 0x9e, 0xe1, 0x79, 0x41, 0x70, 0xa8, 0xc8, 0xe8
|
||||
};
|
||||
|
||||
#endif
|
||||
/**********************************************************************************************/
|
||||
|
||||
|
||||
uint8_t keys_allocated = 0;
|
||||
rsa_publickey_t pub_key;
|
||||
rsa_privatekey_t priv_key;
|
||||
|
||||
#if 0
|
||||
#define MSG message
|
||||
#define SEED seed
|
||||
#define ENCRYPTED encrypted
|
||||
#define MODULUS modulus
|
||||
#define PUB_EXPONENT public_exponent
|
||||
#define PRIV_EXPONENT private_exponent
|
||||
#define P p
|
||||
#define Q q
|
||||
#define DP dp
|
||||
#define DQ dq
|
||||
#define QINV qinv
|
||||
#else
|
||||
#define MSG message4
|
||||
#define SEED seed4
|
||||
#define ENCRYPTED encrypted4
|
||||
#define MODULUS modulus2
|
||||
#define PUB_EXPONENT public_exponent2
|
||||
#define PRIV_EXPONENT private_exponent2
|
||||
#define P p2
|
||||
#define Q q2
|
||||
#define DP dp2
|
||||
#define DQ dq2
|
||||
#define QINV qinv2
|
||||
#endif
|
||||
|
||||
|
||||
uint8_t convert_nibble(uint8_t c){
|
||||
if(c>='0' && c<='9'){
|
||||
return c - '0';
|
||||
}
|
||||
c |= 'A' ^ 'a';
|
||||
if(c>='a' && c<='f'){
|
||||
return c - 'a' + 10;
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
const char *block_ignore_string=" \t\r\n,;";
|
||||
#define BUFFER_LIMIT 120
|
||||
uint16_t read_os(void* dst, uint16_t length, const char* ignore_string){
|
||||
uint16_t counter = 0;
|
||||
uint16_t c;
|
||||
uint8_t v, tmp = 0, idx = 0;
|
||||
if(!ignore_string){
|
||||
ignore_string = block_ignore_string;
|
||||
}
|
||||
while(counter < length){
|
||||
c = cli_getc();
|
||||
if(c > 0xff){
|
||||
return counter;
|
||||
}
|
||||
if(strchr(ignore_string, c)){
|
||||
continue;
|
||||
}
|
||||
v = convert_nibble(c);
|
||||
if(v > 0x0f){
|
||||
return counter;
|
||||
}
|
||||
if(idx){
|
||||
((uint8_t*)dst)[counter++] = (tmp << 4) | v;
|
||||
idx = 0;
|
||||
if(counter % (BUFFER_LIMIT/2) == 0){
|
||||
cli_putc('.');
|
||||
}
|
||||
}else{
|
||||
tmp = v;
|
||||
idx = 1;
|
||||
}
|
||||
}
|
||||
return counter;
|
||||
}
|
||||
|
||||
uint16_t own_atou(const char* str){
|
||||
uint16_t r=0;
|
||||
while(*str && *str >= '0' && *str <= '9'){
|
||||
r *= 10;
|
||||
r += *str++ - '0';
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
uint8_t read_bigint(bigint_t* a, char* prompt){
|
||||
uint16_t read_length, actual_length;
|
||||
uint8_t off;
|
||||
uint8_t *buffer;
|
||||
char read_int_str[18];
|
||||
cli_putstr(prompt);
|
||||
cli_putstr_P(PSTR("\r\n length: "));
|
||||
cli_getsn(read_int_str, 16);
|
||||
read_length = own_atou(read_int_str);
|
||||
off = (sizeof(bigint_word_t) - (read_length % sizeof(bigint_word_t))) % sizeof(bigint_word_t);
|
||||
buffer = malloc(((read_length + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t)) * sizeof(bigint_word_t));
|
||||
if(!buffer){
|
||||
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||
return 2;
|
||||
}
|
||||
cli_putstr_P(PSTR("\r\n data: "));
|
||||
memset(buffer, 0, sizeof(bigint_word_t));
|
||||
actual_length = read_os(buffer + off, read_length, NULL);
|
||||
if(actual_length != read_length){
|
||||
cli_putstr_P(PSTR("\r\nERROR: unexpected end of data!"));
|
||||
free(buffer);
|
||||
return 1;
|
||||
}
|
||||
a->wordv = (bigint_word_t*)buffer;
|
||||
a->length_B = (read_length + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
|
||||
bigint_changeendianess(a);
|
||||
bigint_adjust(a);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t pre_alloc_key_crt(void){
|
||||
uint8_t c;
|
||||
pub_key.modulus = malloc(sizeof(bigint_t));
|
||||
if(!pub_key.modulus){
|
||||
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||
return 2;
|
||||
}
|
||||
priv_key.modulus = pub_key.modulus;
|
||||
priv_key.n = 5;
|
||||
priv_key.components = malloc(5 * sizeof(bigint_t*));
|
||||
if(!priv_key.components){
|
||||
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||
return 2;
|
||||
}
|
||||
pub_key.exponent = malloc(sizeof(bigint_t));
|
||||
if(!pub_key.exponent){
|
||||
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||
return 2;
|
||||
}
|
||||
for(c=0; c<5; ++c){
|
||||
priv_key.components[c] = malloc(sizeof(bigint_t));
|
||||
if(!priv_key.components[c]){
|
||||
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void free_key(void){
|
||||
uint8_t c;
|
||||
free(pub_key.modulus->wordv);
|
||||
free(pub_key.exponent->wordv);
|
||||
free(pub_key.modulus);
|
||||
pub_key.modulus = priv_key.modulus = NULL;
|
||||
free(pub_key.exponent);
|
||||
pub_key.exponent = NULL;
|
||||
for(c = 0; c < priv_key.n; ++c){
|
||||
free(priv_key.components[c]->wordv);
|
||||
free(priv_key.components[c]);
|
||||
}
|
||||
free(priv_key.components);
|
||||
priv_key.components = NULL;
|
||||
}
|
||||
|
||||
uint8_t read_key_crt(void){
|
||||
uint8_t r;
|
||||
cli_putstr_P(PSTR("\r\n== reading key (crt) =="));
|
||||
r = pre_alloc_key_crt();
|
||||
if(r) return r;
|
||||
r = read_bigint(pub_key.modulus,"\r\n = module =");
|
||||
if(r) return r;
|
||||
r = read_bigint(pub_key.exponent,"\r\n = public exponent =");
|
||||
if(r) return r;
|
||||
r = read_bigint(priv_key.components[0],"\r\n = p (first prime) =");
|
||||
if(r) return r;
|
||||
r = read_bigint(priv_key.components[1],"\r\n = q (second prime) =");
|
||||
if(r) return r;
|
||||
r = read_bigint(priv_key.components[2],"\r\n = dp (p's exponent) =");
|
||||
if(r) return r;
|
||||
r = read_bigint(priv_key.components[3],"\r\n = dq (q's exponent) =");
|
||||
if(r) return r;
|
||||
r = read_bigint(priv_key.components[4],"\r\n = qInv (q' coefficient) =");
|
||||
return r;
|
||||
}
|
||||
|
||||
uint8_t read_key_conv(void){
|
||||
uint8_t r;
|
||||
cli_putstr_P(PSTR("\r\n== reading key (crt) =="));
|
||||
pub_key.modulus = malloc(sizeof(bigint_t));
|
||||
if(!pub_key.modulus){
|
||||
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||
return 2;
|
||||
}
|
||||
r = read_bigint(pub_key.modulus,"\r\n = module =");
|
||||
if(r) return r;
|
||||
priv_key.modulus = pub_key.modulus;
|
||||
priv_key.n = 1;
|
||||
pub_key.exponent = malloc(sizeof(bigint_t));
|
||||
if(!pub_key.exponent){
|
||||
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||
return 2;
|
||||
}
|
||||
priv_key.components = malloc(sizeof(bigint_t*));
|
||||
if(!priv_key.components){
|
||||
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||
return 2;
|
||||
}
|
||||
priv_key.components[0] = malloc(sizeof(bigint_t));
|
||||
if(!priv_key.components[0]){
|
||||
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||
return 2;
|
||||
}
|
||||
r = read_bigint(pub_key.exponent,"\r\n = public exponent =");
|
||||
if(r) return r;
|
||||
r = read_bigint(priv_key.components[0],"\r\n = private exponent =");
|
||||
return r;
|
||||
}
|
||||
|
||||
void load_priv_conventional(void){
|
||||
bigint_t *epriv;
|
||||
epriv = malloc(sizeof(bigint_t));
|
||||
if(!epriv){
|
||||
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||
return;
|
||||
}
|
||||
epriv->length_B = (sizeof(PRIV_EXPONENT) + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
|
||||
epriv->wordv = malloc(epriv->length_B * sizeof(bigint_word_t));
|
||||
if(!epriv->wordv){
|
||||
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||
return;
|
||||
}
|
||||
memcpy(epriv->wordv, PRIV_EXPONENT, sizeof(PRIV_EXPONENT));
|
||||
priv_key.components = malloc(sizeof(bigint_t*));
|
||||
priv_key.components[0] = epriv;
|
||||
priv_key.n = 1;
|
||||
bigint_changeendianess(epriv);
|
||||
bigint_adjust(epriv);
|
||||
}
|
||||
|
||||
|
||||
void load_priv_crt_mono(void){
|
||||
bigint_t **v;
|
||||
const uint8_t *bv[5] = {P,Q,DP,DQ,QINV};
|
||||
uint16_t sv[5] = {sizeof(P), sizeof(Q), sizeof(DP), sizeof(DQ), sizeof(QINV)};
|
||||
uint8_t i;
|
||||
v = malloc(5 * sizeof(bigint_t));
|
||||
if(!v){
|
||||
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||
return;
|
||||
}
|
||||
priv_key.components = malloc(5*sizeof(bigint_t*));
|
||||
if(!priv_key.components){
|
||||
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||
return;
|
||||
}
|
||||
priv_key.n = 5;
|
||||
for(i=0; i<5; ++i){
|
||||
v[i] = malloc(sizeof(bigint_t));
|
||||
v[i]->info = 0;
|
||||
v[i]->length_B = (sv[i] + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
|
||||
v[i]->wordv = calloc(v[i]->length_B , sizeof(bigint_word_t));
|
||||
if(!v[i]->wordv){
|
||||
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||
return;
|
||||
}
|
||||
memcpy(v[i]->wordv, bv[i], sv[i]);
|
||||
bigint_changeendianess(v[i]);
|
||||
bigint_adjust(v[i]);
|
||||
priv_key.components[i] = v[i];
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t load_bigint_from_os(bigint_t* a, PGM_VOID_P os, uint16_t length_B){
|
||||
a->length_B = BIGINT_CEIL(length_B) / sizeof(bigint_word_t);
|
||||
a->wordv = malloc(BIGINT_CEIL(length_B));
|
||||
if(!a->wordv){
|
||||
cli_putstr_P(PSTR("\r\nOOM!\r\n"));
|
||||
return 1;
|
||||
}
|
||||
memset(a->wordv, 0, sizeof(bigint_word_t));
|
||||
memcpy_P((uint8_t*)a->wordv + BIGINT_OFF(length_B), os, length_B);
|
||||
a->info = 0;
|
||||
bigint_changeendianess(a);
|
||||
bigint_adjust(a);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void load_fix_rsa(void){
|
||||
if(keys_allocated){
|
||||
free_key();
|
||||
}
|
||||
keys_allocated = 1;
|
||||
|
||||
if(pre_alloc_key_crt()){
|
||||
cli_putstr_P(PSTR("\r\nOOM!\r\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
load_bigint_from_os(pub_key.modulus, MODULUS, sizeof(MODULUS));
|
||||
load_bigint_from_os(pub_key.exponent, PUB_EXPONENT, sizeof(PUB_EXPONENT));
|
||||
priv_key.n = 5;
|
||||
load_bigint_from_os(priv_key.components[0], P, sizeof(P));
|
||||
load_bigint_from_os(priv_key.components[1], Q, sizeof(Q));
|
||||
load_bigint_from_os(priv_key.components[2], DP, sizeof(DP));
|
||||
load_bigint_from_os(priv_key.components[3], DQ, sizeof(DQ));
|
||||
load_bigint_from_os(priv_key.components[4], QINV, sizeof(QINV));
|
||||
|
||||
// load_priv_conventional();
|
||||
// load_priv_crt_mono();
|
||||
}
|
||||
|
||||
void quick_test(void){
|
||||
uint8_t *ciphertext, *plaintext, rc;
|
||||
uint8_t seed[sizeof(SEED)];
|
||||
uint16_t clen, plen;
|
||||
ciphertext = malloc(clen = pub_key.modulus->length_B * sizeof(bigint_word_t));
|
||||
plaintext = malloc(pub_key.modulus->length_B * sizeof(bigint_word_t));
|
||||
memcpy_P(plaintext, MSG, sizeof(MSG));
|
||||
memcpy_P(seed, SEED, sizeof(SEED));
|
||||
cli_putstr_P(PSTR("\r\nplaintext:"));
|
||||
cli_hexdump_block(plaintext, sizeof(MSG), 4, 8);
|
||||
cli_putstr_P(PSTR("\r\nencrypting: ..."));
|
||||
rc = rsa_encrypt_oaep(ciphertext, &clen, plaintext, sizeof(MSG), &pub_key, NULL, NULL, seed);
|
||||
if(rc){
|
||||
cli_putstr_P(PSTR("\r\nERROR: rsa_encrypt_oaep returned: "));
|
||||
cli_hexdump_byte(rc);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
cli_putstr_P(PSTR("\r\n\r\nciphertext:"));
|
||||
cli_hexdump_block(ciphertext, clen, 4, 8);
|
||||
if(clen!=sizeof(ENCRYPTED)){
|
||||
cli_putstr_P(PSTR("\r\n>>FAIL (no size match)<<"));
|
||||
}else{
|
||||
if(memcmp_P(ciphertext, ENCRYPTED, clen)){
|
||||
cli_putstr_P(PSTR("\r\n>>FAIL (no content match)<<"));
|
||||
}else{
|
||||
cli_putstr_P(PSTR("\r\n>>OK<<"));
|
||||
}
|
||||
}
|
||||
|
||||
cli_putstr_P(PSTR("\r\ndecrypting: ..."));
|
||||
rc = rsa_decrypt_oaep(plaintext, &plen, ciphertext, clen, &priv_key, NULL, NULL, NULL);
|
||||
if(rc){
|
||||
cli_putstr_P(PSTR("\r\nERROR: rsa_decrypt_oaep returned: "));
|
||||
cli_hexdump_byte(rc);
|
||||
return;
|
||||
}
|
||||
cli_putstr_P(PSTR("\r\n\r\nplaintext:"));
|
||||
cli_hexdump_block(plaintext, plen, 4, 8);
|
||||
|
||||
free(ciphertext);
|
||||
free(plaintext);
|
||||
}
|
||||
|
||||
void run_seed_test(void){
|
||||
uint8_t *msg, *ciph, *msg_;
|
||||
uint16_t msg_len, ciph_len, msg_len_;
|
||||
uint8_t seed[20], seed_out[20];
|
||||
char read_int_str[18];
|
||||
cli_putstr_P(PSTR("\r\n== test with given seed =="));
|
||||
cli_putstr_P(PSTR("\r\n = message ="));
|
||||
cli_putstr_P(PSTR("\r\n length: "));
|
||||
cli_getsn(read_int_str, 16);
|
||||
msg_len = own_atou(read_int_str);
|
||||
msg = malloc(msg_len);
|
||||
if(!msg){
|
||||
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||
return;
|
||||
}
|
||||
ciph = malloc(bigint_length_B(pub_key.modulus));
|
||||
if(!ciph){
|
||||
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||
return;
|
||||
}
|
||||
msg_ = malloc(bigint_length_B(pub_key.modulus));
|
||||
if(!msg_){
|
||||
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||
return;
|
||||
}
|
||||
cli_putstr_P(PSTR("\r\n data: "));
|
||||
read_os(msg, msg_len, NULL);
|
||||
cli_putstr_P(PSTR("\r\n seed (20 bytes): "));
|
||||
read_os(seed, 20, NULL);
|
||||
|
||||
cli_putstr_P(PSTR("\r\n encrypting ..."));
|
||||
rsa_encrypt_oaep(ciph, &ciph_len, msg, msg_len, &pub_key, NULL, NULL, seed);
|
||||
cli_putstr_P(PSTR("\r\n ciphertext:"));
|
||||
cli_hexdump_block(ciph, ciph_len, 4, 16);
|
||||
cli_putstr_P(PSTR("\r\n decrypting ... "));
|
||||
rsa_decrypt_oaep(msg_, &msg_len_, ciph, ciph_len, &priv_key, NULL, NULL, seed_out);
|
||||
cli_putstr_P(PSTR("[done]"));
|
||||
if(msg_len != msg_len_){
|
||||
char tstr[16];
|
||||
cli_putstr_P(PSTR("\r\nERROR: wrong decrypted message length ("));
|
||||
itoa(msg_len_, tstr, 10);
|
||||
cli_putstr(tstr);
|
||||
cli_putstr_P(PSTR(" instead of "));
|
||||
itoa(msg_len, tstr, 10);
|
||||
cli_putstr(tstr);
|
||||
cli_putc(')');
|
||||
goto end;
|
||||
}
|
||||
if(memcmp(msg, msg_, msg_len)){
|
||||
cli_putstr_P(PSTR("\r\nERROR: wrong decrypted message:"));
|
||||
cli_hexdump_block(msg_, msg_len_, 4, 16);
|
||||
cli_putstr_P(PSTR("\r\nreference:"));
|
||||
cli_hexdump_block(msg, msg_len, 4, 16);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if(memcmp(seed, seed_out, 20)){
|
||||
cli_putstr_P(PSTR("\r\nERROR: wrong decrypted seed:"));
|
||||
cli_hexdump_block(seed_out, 20, 4, 16);
|
||||
cli_putstr_P(PSTR("\r\nreference:"));
|
||||
cli_hexdump_block(seed, 20, 4, 16);
|
||||
goto end;
|
||||
}
|
||||
cli_putstr_P(PSTR("\r\n >>OK<<"));
|
||||
end:
|
||||
free(msg);
|
||||
free(msg_);
|
||||
free(ciph);
|
||||
}
|
||||
|
||||
void reset_prng(void){
|
||||
uint8_t buf[16];
|
||||
memset(buf, 0, 16);
|
||||
random_seed(buf);
|
||||
cli_putstr_P(PSTR("\r\nPRNG reset"));
|
||||
}
|
||||
|
||||
void rsa_init(void){
|
||||
prng_get_byte = random8;
|
||||
}
|
||||
|
||||
void load_key(void){
|
||||
if(keys_allocated){
|
||||
free_key();
|
||||
}
|
||||
keys_allocated = 1;
|
||||
read_key_crt();
|
||||
}
|
||||
|
||||
void test_dump(void){
|
||||
char lstr[16];
|
||||
int len;
|
||||
cli_putstr_P(PSTR("\r\nenter dump length: "));
|
||||
cli_getsn_cecho(lstr, 15);
|
||||
len = own_atou(lstr);
|
||||
cli_putstr_P(PSTR("\r\ndumping 0x"));
|
||||
cli_hexdump_rev(&len, 2);
|
||||
cli_putstr_P(PSTR(" byte:"));
|
||||
cli_hexdump_block(pub_key.modulus->wordv, len, 4, 8);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* main *
|
||||
*****************************************************************************/
|
||||
|
||||
const char echo_test_str[] PROGMEM = "echo-test";
|
||||
const char reset_prng_str[] PROGMEM = "reset-prng";
|
||||
const char load_key_str[] PROGMEM = "load-key";
|
||||
const char load_fix_key_str[] PROGMEM = "load-fix-key";
|
||||
const char quick_test_str[] PROGMEM = "quick-test";
|
||||
const char seed_test_str[] PROGMEM = "seed-test";
|
||||
const char dump_test_str[] PROGMEM = "dump-test";
|
||||
const char performance_str[] PROGMEM = "performance";
|
||||
const char echo_str[] PROGMEM = "echo";
|
||||
|
||||
const cmdlist_entry_t cmdlist[] PROGMEM = {
|
||||
{ reset_prng_str, NULL, reset_prng },
|
||||
{ load_key_str, NULL, load_key },
|
||||
{ load_fix_key_str, NULL, load_fix_rsa },
|
||||
{ quick_test_str, NULL, quick_test },
|
||||
{ seed_test_str, NULL, run_seed_test },
|
||||
{ dump_test_str, NULL, test_dump },
|
||||
// { performance_str, NULL, testrun_performance_bigint },
|
||||
{ echo_str, (void*)1, (void_fpt)echo_ctrl },
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
void dump_sp(void){
|
||||
uint8_t x;
|
||||
uint8_t *xa = &x;
|
||||
cli_putstr_P(PSTR("\r\nstack pointer: ~"));
|
||||
cli_hexdump_rev(&xa, 4);
|
||||
}
|
||||
|
||||
int main (void){
|
||||
main_setup();
|
||||
|
||||
for(;;){
|
||||
welcome_msg(algo_name);
|
||||
rsa_init();
|
||||
cmd_interface(cmdlist);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue