Merge branch 'release/1.18.2'

This commit is contained in:
Steffen Jaeckel 2018-07-01 22:49:01 +02:00
commit 7e7eb695d5
45 changed files with 385 additions and 136 deletions

13
changes
View File

@ -1,3 +1,16 @@
July 1st, 2018
v1.18.2
-- Fix Side Channel Based ECDSA Key Extraction (CVE-2018-12437) (PR #408)
-- Fix potential stack overflow when DER flexi-decoding (CVE-2018-0739) (PR #373)
-- Fix two-key 3DES (PR #390)
-- Fix accelerated CTR mode (PR #359)
-- Fix Fortuna PRNG (PR #363)
-- Fix compilation on platforms where cc doesn't point to gcc (PR #382)
-- Fix using the wrong environment variable LT instead of LIBTOOL (PR #392)
-- Fix build on platforms where the compiler provides __WCHAR_MAX__ but wchar.h is not available (PR #390)
-- Fix & re-factor crypt_list_all_sizes() and crypt_list_all_constants() (PR #414)
-- Minor fixes (PR's #350 #351 #375 #377 #378 #379)
January 22nd, 2018 January 22nd, 2018
v1.18.1 v1.18.1
-- Fix wrong SHA3 blocksizes, thanks to Claus Fischer for reporting this via Mail (PR #329) -- Fix wrong SHA3 blocksizes, thanks to Claus Fischer for reporting this via Mail (PR #329)

View File

@ -65,9 +65,10 @@ int main(int argc, char **argv)
/* get and print the length of the names (and values) list */ /* get and print the length of the names (and values) list */
if (crypt_list_all_constants(NULL, &names_list_len) != 0) exit(EXIT_FAILURE); if (crypt_list_all_constants(NULL, &names_list_len) != 0) exit(EXIT_FAILURE);
/* get and print the names (and values) list */ /* get and print the names (and values) list */
names_list = malloc(names_list_len); if ((names_list = malloc(names_list_len)) == NULL) exit(EXIT_FAILURE);
if (crypt_list_all_constants(names_list, &names_list_len) != 0) exit(EXIT_FAILURE); if (crypt_list_all_constants(names_list, &names_list_len) != 0) exit(EXIT_FAILURE);
printf("%s\n", names_list); printf("%s\n", names_list);
free(names_list);
} }
} else if (argc == 3) { } else if (argc == 3) {
if (strcmp(argv[1], "-s") == 0) { if (strcmp(argv[1], "-s") == 0) {

View File

@ -42,9 +42,10 @@ int main(int argc, char **argv)
printf(" need to allocate %u bytes \n\n", sizes_list_len); printf(" need to allocate %u bytes \n\n", sizes_list_len);
/* get and print the names (and sizes) list */ /* get and print the names (and sizes) list */
sizes_list = malloc(sizes_list_len); if ((sizes_list = malloc(sizes_list_len)) == NULL) exit(EXIT_FAILURE);
if (crypt_list_all_sizes(sizes_list, &sizes_list_len) != 0) exit(EXIT_FAILURE); if (crypt_list_all_sizes(sizes_list, &sizes_list_len) != 0) exit(EXIT_FAILURE);
printf(" supported sizes:\n\n%s\n\n", sizes_list); printf(" supported sizes:\n\n%s\n\n", sizes_list);
free(sizes_list);
} else if (argc == 2) { } else if (argc == 2) {
if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) { if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) {
char* base = strdup(basename(argv[0])); char* base = strdup(basename(argv[0]));
@ -60,9 +61,10 @@ int main(int argc, char **argv)
/* get and print the length of the names (and sizes) list */ /* get and print the length of the names (and sizes) list */
if (crypt_list_all_sizes(NULL, &sizes_list_len) != 0) exit(EXIT_FAILURE); if (crypt_list_all_sizes(NULL, &sizes_list_len) != 0) exit(EXIT_FAILURE);
/* get and print the names (and sizes) list */ /* get and print the names (and sizes) list */
sizes_list = malloc(sizes_list_len); if ((sizes_list = malloc(sizes_list_len)) == NULL) exit(EXIT_FAILURE);
if (crypt_list_all_sizes(sizes_list, &sizes_list_len) != 0) exit(EXIT_FAILURE); if (crypt_list_all_sizes(sizes_list, &sizes_list_len) != 0) exit(EXIT_FAILURE);
printf("%s\n", sizes_list); printf("%s\n", sizes_list);
free(sizes_list);
} }
} else if (argc == 3) { } else if (argc == 3) {
if (strcmp(argv[1], "-s") == 0) { if (strcmp(argv[1], "-s") == 0) {

View File

@ -466,7 +466,7 @@ static void time_cipher_lrw(void)
tally_results(1); tally_results(1);
} }
#else #else
static void time_cipher_lrw(void) { fprintf(stderr, "NO LRW\n"); return 0; } static void time_cipher_lrw(void) { fprintf(stderr, "NO LRW\n"); }
#endif #endif

View File

@ -78,7 +78,7 @@ void cipher_gen(void)
printf("keysize error: %s\n", error_to_string(err)); printf("keysize error: %s\n", error_to_string(err));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (kl == lastkl) break; if (kl == lastkl) continue;
lastkl = kl; lastkl = kl;
fprintf(out, "Key Size: %d bytes\n", kl); fprintf(out, "Key Size: %d bytes\n", kl);

View File

@ -38,7 +38,7 @@ PROJECT_NAME = LibTomCrypt
# could be handy for archiving the generated documentation or if some version # could be handy for archiving the generated documentation or if some version
# control system is used. # control system is used.
PROJECT_NUMBER=1.18.1 PROJECT_NUMBER=1.18.2
# Using the PROJECT_BRIEF tag one can provide an optional one line description # Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a # for a project that appears at the top of each page and should give viewer a

View File

@ -3666,11 +3666,15 @@ key, and any hash that produces at least a 256--bit output. However, to make th
it has been fixed to those choices. it has been fixed to those choices.
Fortuna is more secure than Yarrow in the sense that attackers who learn parts of the entropy being Fortuna is more secure than Yarrow in the sense that attackers who learn parts of the entropy being
added to the PRNG learn far less about the state than that of Yarrow. Without getting into to many added to the PRNG learn far less about the state than that of Yarrow. Without getting into too many
details Fortuna has the ability to recover from state determination attacks where the attacker starts details Fortuna has the ability to recover from state determination attacks where the attacker starts
to learn information from the PRNGs output about the internal state. Yarrow on the other hand, cannot to learn information from the PRNGs output about the internal state. Yarrow on the other hand, cannot
recover from that problem until new entropy is added to the pool and put to use through the ready() function. recover from that problem until new entropy is added to the pool and put to use through the ready() function.
For detailed information on how the algorithm works and what you have to do to maintain the secure state
get a copy of the book\footnote{Niels Ferguson and Bruce Schneier, Practical Cryptography. ISBN 0-471-22357-3.} or
read the paper online\footnote{\url{https://www.schneier.com/academic/paperfiles/fortuna.pdf} [Accessed on 7th Dec. 2017]}.
\subsubsection{RC4} \subsubsection{RC4}
RC4 is an old stream cipher that can also double duty as a PRNG in a pinch. You key RC4 by RC4 is an old stream cipher that can also double duty as a PRNG in a pinch. You key RC4 by

View File

@ -69,7 +69,7 @@ $(1): $(call print-help,$(1),Builds the library and the '$(1)' demo) demos/$(1).
ifneq ($V,1) ifneq ($V,1)
@echo " * $${CC} $$@" @echo " * $${CC} $$@"
endif endif
$${silent} $$(CC) $$(LTC_CFLAGS) $$< $$(LIB_PRE) $$(LIBNAME) $$(LIB_POST) $$(EXTRALIBS) -o $(1) $${silent} $$(CC) $$< $$(LIB_PRE) $$(LIBNAME) $$(LIB_POST) $$(EXTRALIBS) -o $(1)
endef endef
$(foreach demo, $(strip $(DEMOS)), $(eval $(call DEMO_template,$(demo)))) $(foreach demo, $(strip $(DEMOS)), $(eval $(call DEMO_template,$(demo))))

View File

@ -27,7 +27,7 @@ EXTRALIBS = -L../libtommath -ltommath
#Compilation flags #Compilation flags
LTC_CFLAGS = -Isrc/headers -Itests -DLTC_SOURCE $(CFLAGS) LTC_CFLAGS = -Isrc/headers -Itests -DLTC_SOURCE $(CFLAGS)
LTC_LDFLAGS = $(LDFLAGS) $(EXTRALIBS) LTC_LDFLAGS = $(LDFLAGS) $(EXTRALIBS)
VERSION=1.18.1 VERSION=1.18.2
#Libraries to be created #Libraries to be created
LIBMAIN_S =libtomcrypt.a LIBMAIN_S =libtomcrypt.a

View File

@ -22,7 +22,7 @@ EXTRALIBS = ../libtommath/tommath.lib
#Compilation flags #Compilation flags
LTC_CFLAGS = /nologo /Isrc/headers/ /Itests/ /D_CRT_SECURE_NO_WARNINGS /D_CRT_NONSTDC_NO_DEPRECATE /DLTC_SOURCE /W3 $(CFLAGS) LTC_CFLAGS = /nologo /Isrc/headers/ /Itests/ /D_CRT_SECURE_NO_WARNINGS /D_CRT_NONSTDC_NO_DEPRECATE /DLTC_SOURCE /W3 $(CFLAGS)
LTC_LDFLAGS = advapi32.lib $(EXTRALIBS) LTC_LDFLAGS = advapi32.lib $(EXTRALIBS)
VERSION=1.18.1 VERSION=1.18.2
#Libraries to be created (this makefile builds only static libraries) #Libraries to be created (this makefile builds only static libraries)
LIBMAIN_S =tomcrypt.lib LIBMAIN_S =tomcrypt.lib

View File

@ -16,19 +16,19 @@
PLATFORM := $(shell uname | sed -e 's/_.*//') PLATFORM := $(shell uname | sed -e 's/_.*//')
ifndef LT ifndef LIBTOOL
ifeq ($(PLATFORM), Darwin) ifeq ($(PLATFORM), Darwin)
LT:=glibtool LIBTOOL:=glibtool
else else
LT:=libtool LIBTOOL:=libtool
endif endif
endif endif
ifeq ($(PLATFORM), CYGWIN) ifeq ($(PLATFORM), CYGWIN)
NO_UNDEFINED:=-no-undefined NO_UNDEFINED:=-no-undefined
endif endif
LTCOMPILE = $(LT) --mode=compile --tag=CC $(CC) LTCOMPILE = $(LIBTOOL) --mode=compile --tag=CC $(CC)
INSTALL_CMD = $(LT) --mode=install install INSTALL_CMD = $(LIBTOOL) --mode=install install
UNINSTALL_CMD = $(LT) --mode=uninstall rm UNINSTALL_CMD = $(LIBTOOL) --mode=uninstall rm
#Output filenames for various targets. #Output filenames for various targets.
ifndef LIBNAME ifndef LIBNAME
@ -49,15 +49,15 @@ src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
LOBJECTS = $(OBJECTS:.o=.lo) LOBJECTS = $(OBJECTS:.o=.lo)
$(LIBNAME): $(OBJECTS) $(LIBNAME): $(OBJECTS)
$(LT) --mode=link --tag=CC $(CC) $(LTC_CFLAGS) $(CPPFLAGS) $(LTC_LDFLAGS) $(LOBJECTS) $(EXTRALIBS) -o $@ -rpath $(LIBPATH) -version-info $(VERSION_LT) $(NO_UNDEFINED) $(LIBTOOL) --mode=link --tag=CC $(CC) $(LTC_LDFLAGS) $(LOBJECTS) $(EXTRALIBS) -o $@ -rpath $(LIBPATH) -version-info $(VERSION_LT) $(NO_UNDEFINED)
test: $(call print-help,test,Builds the library and the 'test' application to run all self-tests) $(LIBNAME) $(TOBJECTS) test: $(call print-help,test,Builds the library and the 'test' application to run all self-tests) $(LIBNAME) $(TOBJECTS)
$(LT) --mode=link --tag=CC $(CC) $(LTC_CFLAGS) $(CPPFLAGS) $(LTC_LDFLAGS) -o $(TEST) $(TOBJECTS) $(LIBNAME) $(EXTRALIBS) $(LIBTOOL) --mode=link --tag=CC $(CC) $(LTC_LDFLAGS) -o $(TEST) $(TOBJECTS) $(LIBNAME) $(EXTRALIBS)
# build the demos from a template # build the demos from a template
define DEMO_template define DEMO_template
$(1): $(call print-help,$(1),Builds the library and the '$(1)' demo) demos/$(1).o $$(LIBNAME) $(1): $(call print-help,$(1),Builds the library and the '$(1)' demo) demos/$(1).o $$(LIBNAME)
$$(LT) --mode=link --tag=CC $$(CC) $$(LTC_CFLAGS) $$(CPPFLAGS) $$(LTC_LDFLAGS) $$^ $$(EXTRALIBS) -o $(1) $$(LIBTOOL) --mode=link --tag=CC $$(CC) $$(LTC_LDFLAGS) $$^ $$(EXTRALIBS) -o $(1)
endef endef
$(foreach demo, $(strip $(DEMOS)), $(eval $(call DEMO_template,$(demo)))) $(foreach demo, $(strip $(DEMOS)), $(eval $(call DEMO_template,$(demo))))

View File

@ -39,7 +39,7 @@ EXTRALIBS = ../libtommath/libtommath.a
#Compilation flags #Compilation flags
LTC_CFLAGS = -Isrc/headers -Itests -DLTC_SOURCE $(CFLAGS) LTC_CFLAGS = -Isrc/headers -Itests -DLTC_SOURCE $(CFLAGS)
LTC_LDFLAGS = $(LDFLAGS) $(EXTRALIBS) LTC_LDFLAGS = $(LDFLAGS) $(EXTRALIBS)
VERSION=1.18.1 VERSION=1.18.2
#Libraries to be created (this makefile builds only static libraries) #Libraries to be created (this makefile builds only static libraries)
LIBMAIN_S =libtomcrypt.a LIBMAIN_S =libtomcrypt.a

View File

@ -3,8 +3,8 @@
# (GNU make only) # (GNU make only)
# The version - BEWARE: VERSION, VERSION_PC and VERSION_LT are updated via ./updatemakes.sh # The version - BEWARE: VERSION, VERSION_PC and VERSION_LT are updated via ./updatemakes.sh
VERSION=1.18.1 VERSION=1.18.2
VERSION_PC=1.18.1 VERSION_PC=1.18.2
# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html # http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
VERSION_LT=1:1 VERSION_LT=1:1
@ -13,9 +13,23 @@ ifndef CROSS_COMPILE
CROSS_COMPILE:= CROSS_COMPILE:=
endif endif
ifeq ($(CC),cc) # We only need to go through this dance of determining the right compiler if we're using
CC := $(CROSS_COMPILE)gcc # cross compilation, otherwise $(CC) is fine as-is.
ifneq (,$(CROSS_COMPILE))
ifeq ($(origin CC),default)
CSTR := "\#ifdef __clang__\nCLANG\n\#endif\n"
ifeq ($(PLATFORM),FreeBSD)
# XXX: FreeBSD needs extra escaping for some reason
CSTR := $$$(CSTR)
endif endif
ifneq (,$(shell echo $(CSTR) | $(CC) -E - | grep CLANG))
CC := $(CROSS_COMPILE)clang
else
CC := $(CROSS_COMPILE)gcc
endif # Clang
endif # cc is Make's default
endif # CROSS_COMPILE non-empty
LD:=$(CROSS_COMPILE)ld LD:=$(CROSS_COMPILE)ld
AR:=$(CROSS_COMPILE)ar AR:=$(CROSS_COMPILE)ar
@ -24,7 +38,12 @@ AR:=$(CROSS_COMPILE)ar
ARFLAGS:=r ARFLAGS:=r
ifndef MAKE ifndef MAKE
MAKE:=make # BSDs refer to GNU Make as gmake
ifneq (,$(findstring $(PLATFORM),FreeBSD OpenBSD DragonFly NetBSD))
MAKE=gmake
else
MAKE=make
endif
endif endif
ifndef INSTALL_CMD ifndef INSTALL_CMD
@ -389,7 +408,7 @@ doc/crypt.pdf: $(call print-help,doc/crypt.pdf,Builds the Developer Manual)
$(MAKE) -C doc/ crypt.pdf V=$(V) $(MAKE) -C doc/ crypt.pdf V=$(V)
install_all: $(call print-help,install_all,Install everything - library bins docs tests) install install_bins install_docs install_test install_all: $(call print-help,install_all,Install everything - library bins docs tests) install install_bins install_docs
INSTALL_OPTS ?= -m 644 INSTALL_OPTS ?= -m 644

View File

@ -1434,6 +1434,58 @@ Key Size: 8 bytes
Cipher: 3des Cipher: 3des
Key Size: 16 bytes
0: DF0B6C9C31CD0CE4
1: 9B3503FDF249920B
2: 653924639C39E7FF
3: 6A29E0A7F42025BB
4: 1628B719BC875D20
5: 7D77004A18D0C0B2
6: 4D21684EFE962DC1
7: B6BD7F82B648A364
8: 1F87ABAD83D19E96
9: 3DF3533220C3CDED
10: D0E7D0ABFBA68747
11: 109FE5B38D74E6C9
12: AE12C4B4D523784F
13: 953CD7F264166764
14: 70B3A87D72FA0A22
15: 9C9D09AC66AB8F6D
16: 4A15AEACB35B76F0
17: EFA32F95623BCF1A
18: 679901F7737E195C
19: 221BB06209DDFCF4
20: 0889A953C60BB1BF
21: 88F2249380E2D5D9
22: 5AB26168B7FA24D5
23: 934229150997D390
24: 535E4F4C4DA97062
25: 03E8D711AC2B8154
26: CB5EF6E72EA3EC49
27: 9278A864F488C94A
28: CB91B77401DAF004
29: 4D0BA1C9794E0099
30: 9CFA24A21F48043F
31: BB6B3A33AEEC01F4
32: F2A8566E0FF6033D
33: E6AC213000E955E6
34: 91F5FF42BBE0B81B
35: 6506D72ADEA70E12
36: F9BD8C0506C7CC4E
37: 89CD85D1C98439ED
38: 409410E3E7D66B10
39: 4CA64F96F4F3D216
40: 383D18FBF8C006BC
41: 3806A8CB006EC243
42: EE73C06D903D2FCF
43: 624BFD3FAD7ED9EB
44: 1B5457F2731FB5D1
45: 4EC4632DFAC9D5D6
46: 8F0B3100FAD612C5
47: F955FCAD55AC6C90
48: BEB5F023BD413960
49: BDC369F3288ED754
Key Size: 24 bytes Key Size: 24 bytes
0: 58ED248F77F6B19E 0: 58ED248F77F6B19E
1: DA5C39983FD34F30 1: DA5C39983FD34F30

View File

@ -94,7 +94,7 @@ static const ulong32 TE0[256] = {
0x7bb0b0cbUL, 0xa85454fcUL, 0x6dbbbbd6UL, 0x2c16163aUL, 0x7bb0b0cbUL, 0xa85454fcUL, 0x6dbbbbd6UL, 0x2c16163aUL,
}; };
#ifndef PELI_TAB #if !defined(PELI_TAB) && defined(LTC_SMALL_CODE)
static const ulong32 Te4[256] = { static const ulong32 Te4[256] = {
0x63636363UL, 0x7c7c7c7cUL, 0x77777777UL, 0x7b7b7b7bUL, 0x63636363UL, 0x7c7c7c7cUL, 0x77777777UL, 0x7b7b7b7bUL,
0xf2f2f2f2UL, 0x6b6b6b6bUL, 0x6f6f6f6fUL, 0xc5c5c5c5UL, 0xf2f2f2f2UL, 0x6b6b6b6bUL, 0x6f6f6f6fUL, 0xc5c5c5c5UL,
@ -1017,11 +1017,13 @@ static const ulong32 Tks3[] = {
#endif /* SMALL CODE */ #endif /* SMALL CODE */
#ifndef PELI_TAB
static const ulong32 rcon[] = { static const ulong32 rcon[] = {
0x01000000UL, 0x02000000UL, 0x04000000UL, 0x08000000UL, 0x01000000UL, 0x02000000UL, 0x04000000UL, 0x08000000UL,
0x10000000UL, 0x20000000UL, 0x40000000UL, 0x80000000UL, 0x10000000UL, 0x20000000UL, 0x40000000UL, 0x80000000UL,
0x1B000000UL, 0x36000000UL, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ 0x1B000000UL, 0x36000000UL, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
}; };
#endif
#endif /* __LTC_AES_TAB_C__ */ #endif /* __LTC_AES_TAB_C__ */

View File

@ -36,7 +36,7 @@ const struct ltc_cipher_descriptor des3_desc =
{ {
"3des", "3des",
14, 14,
24, 24, 8, 16, 16, 24, 8, 16,
&des3_setup, &des3_setup,
&des3_ecb_encrypt, &des3_ecb_encrypt,
&des3_ecb_decrypt, &des3_ecb_decrypt,
@ -2068,8 +2068,11 @@ int des_keysize(int *keysize)
int des3_keysize(int *keysize) int des3_keysize(int *keysize)
{ {
LTC_ARGCHK(keysize != NULL); LTC_ARGCHK(keysize != NULL);
if(*keysize < 24) { if (*keysize < 16)
return CRYPT_INVALID_KEYSIZE; return CRYPT_INVALID_KEYSIZE;
if (*keysize < 24) {
*keysize = 16;
return CRYPT_OK;
} }
*keysize = 24; *keysize = 24;
return CRYPT_OK; return CRYPT_OK;

View File

@ -52,7 +52,7 @@ int ccm_memory(int cipher,
int err; int err;
unsigned long len, L, x, y, z, CTRlen; unsigned long len, L, x, y, z, CTRlen;
#ifdef LTC_FAST #ifdef LTC_FAST
LTC_FAST_TYPE fastMask = ~0; /* initialize fastMask at all zeroes */ LTC_FAST_TYPE fastMask = ~(LTC_FAST_TYPE)0; /* initialize fastMask at all zeroes */
#endif #endif
unsigned char mask = 0xff; /* initialize mask at all zeroes */ unsigned char mask = 0xff; /* initialize mask at all zeroes */

View File

@ -27,13 +27,15 @@ extern "C" {
/* version */ /* version */
#define CRYPT 0x0118 #define CRYPT 0x0118
#define SCRYPT "1.18.1" #define SCRYPT "1.18.2"
/* max size of either a cipher/hash block or symmetric key [largest of the two] */ /* max size of either a cipher/hash block or symmetric key [largest of the two] */
#define MAXBLOCKSIZE 128 #define MAXBLOCKSIZE 128
#ifndef TAB_SIZE
/* descriptor table size */ /* descriptor table size */
#define TAB_SIZE 32 #define TAB_SIZE 32
#endif
/* error codes [will be expanded in future releases] */ /* error codes [will be expanded in future releases] */
enum { enum {

View File

@ -472,6 +472,13 @@
#endif #endif
#endif #endif
#if defined(LTC_DER)
#ifndef LTC_DER_MAX_RECURSION
/* Maximum recursion limit when processing nested ASN.1 types. */
#define LTC_DER_MAX_RECURSION 30
#endif
#endif
#if defined(LTC_MECC) || defined(LTC_MRSA) || defined(LTC_MDSA) || defined(LTC_MKAT) #if defined(LTC_MECC) || defined(LTC_MRSA) || defined(LTC_MDSA) || defined(LTC_MKAT)
/* Include the MPI functionality? (required by the PK algorithms) */ /* Include the MPI functionality? (required by the PK algorithms) */
#define LTC_MPI #define LTC_MPI

View File

@ -667,16 +667,16 @@ int der_printable_value_decode(int v);
/* UTF-8 */ /* UTF-8 */
#if (defined(SIZE_MAX) || __STDC_VERSION__ >= 199901L || defined(WCHAR_MAX) || defined(__WCHAR_MAX__) || defined(_WCHAR_T) || defined(_WCHAR_T_DEFINED) || defined (__WCHAR_TYPE__)) && !defined(LTC_NO_WCHAR) #if (defined(SIZE_MAX) || __STDC_VERSION__ >= 199901L || defined(WCHAR_MAX) || defined(__WCHAR_MAX__) || defined(_WCHAR_T) || defined(_WCHAR_T_DEFINED) || defined (__WCHAR_TYPE__)) && !defined(LTC_NO_WCHAR)
#include <wchar.h> #if defined(__WCHAR_MAX__)
#if defined(__WCHAR_MAX__) #define LTC_WCHAR_MAX __WCHAR_MAX__
#define LTC_WCHAR_MAX __WCHAR_MAX__ #else
#elif defined(WCHAR_MAX) #include <wchar.h>
#define LTC_WCHAR_MAX WCHAR_MAX #define LTC_WCHAR_MAX WCHAR_MAX
#endif #endif
/* please note that it might happen that LTC_WCHAR_MAX is undefined */ /* please note that it might happen that LTC_WCHAR_MAX is undefined */
#else #else
typedef ulong32 wchar_t; typedef ulong32 wchar_t;
#define LTC_WCHAR_MAX 0xFFFFFFFF #define LTC_WCHAR_MAX 0xFFFFFFFF
#endif #endif
int der_encode_utf8_string(const wchar_t *in, unsigned long inlen, int der_encode_utf8_string(const wchar_t *in, unsigned long inlen,

View File

@ -23,6 +23,11 @@
int blake2bmac_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen) int blake2bmac_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen)
{ {
#ifdef LTC_NO_FILE #ifdef LTC_NO_FILE
LTC_UNUSED_PARAM(fname);
LTC_UNUSED_PARAM(key);
LTC_UNUSED_PARAM(keylen);
LTC_UNUSED_PARAM(mac);
LTC_UNUSED_PARAM(maclen);
return CRYPT_NOP; return CRYPT_NOP;
#else #else
blake2bmac_state st; blake2bmac_state st;

View File

@ -23,6 +23,11 @@
int blake2smac_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen) int blake2smac_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen)
{ {
#ifdef LTC_NO_FILE #ifdef LTC_NO_FILE
LTC_UNUSED_PARAM(fname);
LTC_UNUSED_PARAM(key);
LTC_UNUSED_PARAM(keylen);
LTC_UNUSED_PARAM(mac);
LTC_UNUSED_PARAM(maclen);
return CRYPT_NOP; return CRYPT_NOP;
#else #else
blake2smac_state st; blake2smac_state st;

View File

@ -31,6 +31,12 @@ int f9_file(int cipher,
unsigned char *out, unsigned long *outlen) unsigned char *out, unsigned long *outlen)
{ {
#ifdef LTC_NO_FILE #ifdef LTC_NO_FILE
LTC_UNUSED_PARAM(cipher);
LTC_UNUSED_PARAM(key);
LTC_UNUSED_PARAM(keylen);
LTC_UNUSED_PARAM(fname);
LTC_UNUSED_PARAM(out);
LTC_UNUSED_PARAM(outlen);
return CRYPT_NOP; return CRYPT_NOP;
#else #else
size_t x; size_t x;

View File

@ -30,6 +30,12 @@ int hmac_file(int hash, const char *fname,
unsigned char *out, unsigned long *outlen) unsigned char *out, unsigned long *outlen)
{ {
#ifdef LTC_NO_FILE #ifdef LTC_NO_FILE
LTC_UNUSED_PARAM(hash);
LTC_UNUSED_PARAM(fname);
LTC_UNUSED_PARAM(key);
LTC_UNUSED_PARAM(keylen);
LTC_UNUSED_PARAM(out);
LTC_UNUSED_PARAM(outlen);
return CRYPT_NOP; return CRYPT_NOP;
#else #else
hmac_state hmac; hmac_state hmac;

View File

@ -31,6 +31,12 @@ int omac_file(int cipher,
unsigned char *out, unsigned long *outlen) unsigned char *out, unsigned long *outlen)
{ {
#ifdef LTC_NO_FILE #ifdef LTC_NO_FILE
LTC_UNUSED_PARAM(cipher);
LTC_UNUSED_PARAM(key);
LTC_UNUSED_PARAM(keylen);
LTC_UNUSED_PARAM(filename);
LTC_UNUSED_PARAM(out);
LTC_UNUSED_PARAM(outlen);
return CRYPT_NOP; return CRYPT_NOP;
#else #else
size_t x; size_t x;

View File

@ -31,6 +31,12 @@ int pmac_file(int cipher,
unsigned char *out, unsigned long *outlen) unsigned char *out, unsigned long *outlen)
{ {
#ifdef LTC_NO_FILE #ifdef LTC_NO_FILE
LTC_UNUSED_PARAM(cipher);
LTC_UNUSED_PARAM(key);
LTC_UNUSED_PARAM(keylen);
LTC_UNUSED_PARAM(filename);
LTC_UNUSED_PARAM(out);
LTC_UNUSED_PARAM(outlen);
return CRYPT_NOP; return CRYPT_NOP;
#else #else
size_t x; size_t x;

View File

@ -28,6 +28,11 @@
int poly1305_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen) int poly1305_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen)
{ {
#ifdef LTC_NO_FILE #ifdef LTC_NO_FILE
LTC_UNUSED_PARAM(fname);
LTC_UNUSED_PARAM(key);
LTC_UNUSED_PARAM(keylen);
LTC_UNUSED_PARAM(mac);
LTC_UNUSED_PARAM(maclen);
return CRYPT_NOP; return CRYPT_NOP;
#else #else
poly1305_state st; poly1305_state st;

View File

@ -31,6 +31,12 @@ int xcbc_file(int cipher,
unsigned char *out, unsigned long *outlen) unsigned char *out, unsigned long *outlen)
{ {
#ifdef LTC_NO_FILE #ifdef LTC_NO_FILE
LTC_UNUSED_PARAM(cipher);
LTC_UNUSED_PARAM(key);
LTC_UNUSED_PARAM(keylen);
LTC_UNUSED_PARAM(filename);
LTC_UNUSED_PARAM(out);
LTC_UNUSED_PARAM(outlen);
return CRYPT_NOP; return CRYPT_NOP;
#else #else
size_t x; size_t x;

View File

@ -67,7 +67,6 @@ void ltc_cleanup_multi(void **a, ...)
cur = va_arg(args, void**); cur = va_arg(args, void**);
} }
va_end(args); va_end(args);
return;
} }
#endif #endif

View File

@ -8,7 +8,7 @@
*/ */
#include "tomcrypt.h" #include "tomcrypt.h"
#ifdef LTC_MDSA #if defined(LTC_MDSA) || defined(LTC_MECC)
/** /**
Generate a random number N with given bitlength (note: MSB can be 0) Generate a random number N with given bitlength (note: MSB can be 0)
*/ */

View File

@ -398,6 +398,7 @@ const char *crypt_build_settings =
#endif #endif
#if defined(LTC_DER) #if defined(LTC_DER)
" DER " " DER "
" " NAME_VALUE(LTC_DER_MAX_RECURSION) " "
#endif #endif
#if defined(LTC_PKCS_1) #if defined(LTC_PKCS_1)
" PKCS#1 " " PKCS#1 "

View File

@ -111,6 +111,7 @@ static const crypt_constant _crypt_constants[] = {
#ifdef LTC_DER #ifdef LTC_DER
/* DER handling */ /* DER handling */
{"LTC_DER", 1},
_C_STRINGIFY(LTC_ASN1_EOL), _C_STRINGIFY(LTC_ASN1_EOL),
_C_STRINGIFY(LTC_ASN1_BOOLEAN), _C_STRINGIFY(LTC_ASN1_BOOLEAN),
_C_STRINGIFY(LTC_ASN1_INTEGER), _C_STRINGIFY(LTC_ASN1_INTEGER),
@ -132,6 +133,9 @@ static const crypt_constant _crypt_constants[] = {
_C_STRINGIFY(LTC_ASN1_CONSTRUCTED), _C_STRINGIFY(LTC_ASN1_CONSTRUCTED),
_C_STRINGIFY(LTC_ASN1_CONTEXT_SPECIFIC), _C_STRINGIFY(LTC_ASN1_CONTEXT_SPECIFIC),
_C_STRINGIFY(LTC_ASN1_GENERALIZEDTIME), _C_STRINGIFY(LTC_ASN1_GENERALIZEDTIME),
_C_STRINGIFY(LTC_DER_MAX_RECURSION),
#else
{"LTC_DER", 0},
#endif #endif
#ifdef LTC_CTR_MODE #ifdef LTC_CTR_MODE
@ -248,20 +252,16 @@ int crypt_get_constant(const char* namein, int *valueout) {
int crypt_list_all_constants(char *names_list, unsigned int *names_list_size) { int crypt_list_all_constants(char *names_list, unsigned int *names_list_size) {
int i; int i;
unsigned int total_len = 0; unsigned int total_len = 0;
char number[32], *ptr; char *ptr;
int number_len; int number_len;
int count = sizeof(_crypt_constants) / sizeof(_crypt_constants[0]); int count = sizeof(_crypt_constants) / sizeof(_crypt_constants[0]);
/* calculate amount of memory required for the list */ /* calculate amount of memory required for the list */
for (i=0; i<count; i++) { for (i=0; i<count; i++) {
total_len += (unsigned int)strlen(_crypt_constants[i].name) + 1; number_len = snprintf(NULL, 0, "%s,%d\n", _crypt_constants[i].name, _crypt_constants[i].value);
/* the above +1 is for the commas */ if (number_len < 0)
number_len = snprintf(number, sizeof(number), "%d", _crypt_constants[i].value);
if ((number_len < 0) ||
((unsigned int)number_len >= sizeof(number)))
return -1; return -1;
total_len += number_len + 1; total_len += number_len;
/* this last +1 is for newlines (and ending NULL) */
} }
if (names_list == NULL) { if (names_list == NULL) {
@ -273,16 +273,11 @@ int crypt_list_all_constants(char *names_list, unsigned int *names_list_size) {
/* build the names list */ /* build the names list */
ptr = names_list; ptr = names_list;
for (i=0; i<count; i++) { for (i=0; i<count; i++) {
strcpy(ptr, _crypt_constants[i].name); number_len = snprintf(ptr, total_len, "%s,%d\n", _crypt_constants[i].name, _crypt_constants[i].value);
ptr += strlen(_crypt_constants[i].name); if (number_len < 0) return -1;
strcpy(ptr, ","); if ((unsigned int)number_len > total_len) return -1;
ptr += 1; total_len -= number_len;
number_len = snprintf(number, sizeof(number), "%d", _crypt_constants[i].value);
strcpy(ptr, number);
ptr += number_len; ptr += number_len;
strcpy(ptr, "\n");
ptr += 1;
} }
/* to remove the trailing new-line */ /* to remove the trailing new-line */
ptr -= 1; ptr -= 1;

View File

@ -307,19 +307,16 @@ int crypt_get_size(const char* namein, unsigned int *sizeout) {
int crypt_list_all_sizes(char *names_list, unsigned int *names_list_size) { int crypt_list_all_sizes(char *names_list, unsigned int *names_list_size) {
int i; int i;
unsigned int total_len = 0; unsigned int total_len = 0;
char number[32], *ptr; char *ptr;
int number_len; int number_len;
int count = sizeof(_crypt_sizes) / sizeof(_crypt_sizes[0]); int count = sizeof(_crypt_sizes) / sizeof(_crypt_sizes[0]);
/* calculate amount of memory required for the list */ /* calculate amount of memory required for the list */
for (i=0; i<count; i++) { for (i=0; i<count; i++) {
total_len += (unsigned int)strlen(_crypt_sizes[i].name) + 1; number_len = snprintf(NULL, 0, "%s,%u\n", _crypt_sizes[i].name, _crypt_sizes[i].size);
/* the above +1 is for the commas */ if (number_len < 0)
number_len = snprintf(number, sizeof(number), "%u", _crypt_sizes[i].size);
if ((number_len < 0) ||
((unsigned int)number_len >= sizeof(number)))
return -1; return -1;
total_len += (unsigned int)strlen(number) + 1; total_len += number_len;
/* this last +1 is for newlines (and ending NULL) */ /* this last +1 is for newlines (and ending NULL) */
} }
@ -332,16 +329,11 @@ int crypt_list_all_sizes(char *names_list, unsigned int *names_list_size) {
/* build the names list */ /* build the names list */
ptr = names_list; ptr = names_list;
for (i=0; i<count; i++) { for (i=0; i<count; i++) {
strcpy(ptr, _crypt_sizes[i].name); number_len = snprintf(ptr, total_len, "%s,%u\n", _crypt_sizes[i].name, _crypt_sizes[i].size);
ptr += strlen(_crypt_sizes[i].name); if (number_len < 0) return -1;
strcpy(ptr, ","); if ((unsigned int)number_len > total_len) return -1;
ptr += 1; total_len -= number_len;
number_len = snprintf(number, sizeof(number), "%u", _crypt_sizes[i].size);
strcpy(ptr, number);
ptr += number_len; ptr += number_len;
strcpy(ptr, "\n");
ptr += 1;
} }
/* to remove the trailing new-line */ /* to remove the trailing new-line */
ptr -= 1; ptr -= 1;

View File

@ -17,47 +17,17 @@
#ifdef LTC_CTR_MODE #ifdef LTC_CTR_MODE
/** /**
CTR encrypt CTR encrypt software implementation
@param pt Plaintext @param pt Plaintext
@param ct [out] Ciphertext @param ct [out] Ciphertext
@param len Length of plaintext (octets) @param len Length of plaintext (octets)
@param ctr CTR state @param ctr CTR state
@return CRYPT_OK if successful @return CRYPT_OK if successful
*/ */
int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr) static int _ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr)
{ {
int x, err; int x, err;
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(ctr != NULL);
if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) {
return err;
}
/* is blocklen/padlen valid? */
if (ctr->blocklen < 1 || ctr->blocklen > (int)sizeof(ctr->ctr) ||
ctr->padlen < 0 || ctr->padlen > (int)sizeof(ctr->pad)) {
return CRYPT_INVALID_ARG;
}
#ifdef LTC_FAST
if (ctr->blocklen % sizeof(LTC_FAST_TYPE)) {
return CRYPT_INVALID_ARG;
}
#endif
/* handle acceleration only if pad is empty, accelerator is present and length is >= a block size */
if ((ctr->padlen == ctr->blocklen) && cipher_descriptor[ctr->cipher].accel_ctr_encrypt != NULL && (len >= (unsigned long)ctr->blocklen)) {
if ((err = cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key)) != CRYPT_OK) {
return err;
}
pt += (len / ctr->blocklen) * ctr->blocklen;
ct += (len / ctr->blocklen) * ctr->blocklen;
len %= ctr->blocklen;
}
while (len) { while (len) {
/* is the pad empty? */ /* is the pad empty? */
if (ctr->padlen == ctr->blocklen) { if (ctr->padlen == ctr->blocklen) {
@ -87,7 +57,7 @@ int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
ctr->padlen = 0; ctr->padlen = 0;
} }
#ifdef LTC_FAST #ifdef LTC_FAST
if (ctr->padlen == 0 && len >= (unsigned long)ctr->blocklen) { if ((ctr->padlen == 0) && (len >= (unsigned long)ctr->blocklen)) {
for (x = 0; x < ctr->blocklen; x += sizeof(LTC_FAST_TYPE)) { for (x = 0; x < ctr->blocklen; x += sizeof(LTC_FAST_TYPE)) {
*(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ct + x)) = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)pt + x)) ^ *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ct + x)) = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)pt + x)) ^
*(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ctr->pad + x)); *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ctr->pad + x));
@ -105,6 +75,63 @@ int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
return CRYPT_OK; return CRYPT_OK;
} }
/**
CTR encrypt
@param pt Plaintext
@param ct [out] Ciphertext
@param len Length of plaintext (octets)
@param ctr CTR state
@return CRYPT_OK if successful
*/
int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr)
{
int err, fr;
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(ctr != NULL);
if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) {
return err;
}
/* is blocklen/padlen valid? */
if ((ctr->blocklen < 1) || (ctr->blocklen > (int)sizeof(ctr->ctr)) ||
(ctr->padlen < 0) || (ctr->padlen > (int)sizeof(ctr->pad))) {
return CRYPT_INVALID_ARG;
}
#ifdef LTC_FAST
if (ctr->blocklen % sizeof(LTC_FAST_TYPE)) {
return CRYPT_INVALID_ARG;
}
#endif
/* handle acceleration only if pad is empty, accelerator is present and length is >= a block size */
if ((cipher_descriptor[ctr->cipher].accel_ctr_encrypt != NULL) && (len >= (unsigned long)ctr->blocklen)) {
if (ctr->padlen < ctr->blocklen) {
fr = ctr->blocklen - ctr->padlen;
if ((err = _ctr_encrypt(pt, ct, fr, ctr)) != CRYPT_OK) {
return err;
}
pt += fr;
ct += fr;
len -= fr;
}
if (len >= (unsigned long)ctr->blocklen) {
if ((err = cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key)) != CRYPT_OK) {
return err;
}
pt += (len / ctr->blocklen) * ctr->blocklen;
ct += (len / ctr->blocklen) * ctr->blocklen;
len %= ctr->blocklen;
}
}
return _ctr_encrypt(pt, ct, len, ctr);
}
#endif #endif
/* ref: $Format:%D$ */ /* ref: $Format:%D$ */

View File

@ -79,8 +79,8 @@ static int _new_element(ltc_asn1_list **l)
*/ */
int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out) int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out)
{ {
ltc_asn1_list *l; ltc_asn1_list *l, *t;
unsigned long err, type, len, totlen, data_offset; unsigned long err, type, len, totlen, data_offset, len_len;
void *realloc_tmp; void *realloc_tmp;
LTC_ARGCHK(in != NULL); LTC_ARGCHK(in != NULL);
@ -407,6 +407,17 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc
l->child->parent = l; l->child->parent = l;
} }
t = l;
len_len = 0;
while((t != NULL) && (t->child != NULL)) {
len_len++;
t = t->child;
}
if (len_len > LTC_DER_MAX_RECURSION) {
err = CRYPT_ERROR;
goto error;
}
break; break;
case 0x80: /* Context-specific */ case 0x80: /* Context-specific */

View File

@ -80,7 +80,7 @@ int der_decode_subject_public_key_info(const unsigned char *in, unsigned long in
} }
if ((alg_id[0].size != oid.OIDlen) || if ((alg_id[0].size != oid.OIDlen) ||
XMEMCMP(oid.OID, alg_id[0].data, oid.OIDlen * sizeof(oid.OID[0]))) { XMEMCMP(oid.OID, alg_id[0].data, oid.OIDlen * sizeof(oid.OID[0])) != 0) {
/* OID mismatch */ /* OID mismatch */
err = CRYPT_PK_INVALID_TYPE; err = CRYPT_PK_INVALID_TYPE;
goto LBL_ERR; goto LBL_ERR;

View File

@ -69,7 +69,7 @@ int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key
} }
} else { } else {
if (std) { if (std) {
unsigned long tmplen = (mp_count_bits(key->y) / 8) + 8; unsigned long tmplen = (unsigned long)(mp_count_bits(key->y) / 8) + 8;
unsigned char* tmp = XMALLOC(tmplen); unsigned char* tmp = XMALLOC(tmplen);
ltc_asn1_list int_list[3]; ltc_asn1_list int_list[3];

View File

@ -72,8 +72,8 @@ static int _dsa_make_params(prng_state *prng, int wprng, int group_size, int mod
*/ */
seedbytes = group_size; seedbytes = group_size;
L = modulus_size * 8; L = (unsigned long)modulus_size * 8;
N = group_size * 8; N = (unsigned long)group_size * 8;
/* XXX-TODO no Lucas test */ /* XXX-TODO no Lucas test */
#ifdef LTC_MPI_HAS_LUCAS_TEST #ifdef LTC_MPI_HAS_LUCAS_TEST

View File

@ -21,7 +21,7 @@ static int _ecc_sign_hash(const unsigned char *in, unsigned long inlen,
prng_state *prng, int wprng, ecc_key *key, int sigformat) prng_state *prng, int wprng, ecc_key *key, int sigformat)
{ {
ecc_key pubkey; ecc_key pubkey;
void *r, *s, *e, *p; void *r, *s, *e, *p, *b;
int err, max_iterations = LTC_PK_MAX_RETRIES; int err, max_iterations = LTC_PK_MAX_RETRIES;
unsigned long pbits, pbytes, i, shift_right; unsigned long pbits, pbytes, i, shift_right;
unsigned char ch, buf[MAXBLOCKSIZE]; unsigned char ch, buf[MAXBLOCKSIZE];
@ -46,7 +46,7 @@ static int _ecc_sign_hash(const unsigned char *in, unsigned long inlen,
} }
/* init the bignums */ /* init the bignums */
if ((err = mp_init_multi(&r, &s, &p, &e, NULL)) != CRYPT_OK) { if ((err = mp_init_multi(&r, &s, &p, &e, &b, NULL)) != CRYPT_OK) {
return err; return err;
} }
if ((err = mp_read_radix(p, (char *)key->dp->order, 16)) != CRYPT_OK) { goto errnokey; } if ((err = mp_read_radix(p, (char *)key->dp->order, 16)) != CRYPT_OK) { goto errnokey; }
@ -82,12 +82,15 @@ static int _ecc_sign_hash(const unsigned char *in, unsigned long inlen,
if (mp_iszero(r) == LTC_MP_YES) { if (mp_iszero(r) == LTC_MP_YES) {
ecc_free(&pubkey); ecc_free(&pubkey);
} else { } else {
if ((err = rand_bn_upto(b, p, prng, wprng)) != CRYPT_OK) { goto error; } /* b = blinding value */
/* find s = (e + xr)/k */ /* find s = (e + xr)/k */
if ((err = mp_invmod(pubkey.k, p, pubkey.k)) != CRYPT_OK) { goto error; } /* k = 1/k */ if ((err = mp_mulmod(pubkey.k, b, p, pubkey.k)) != CRYPT_OK) { goto error; } /* k = kb */
if ((err = mp_invmod(pubkey.k, p, pubkey.k)) != CRYPT_OK) { goto error; } /* k = 1/kb */
if ((err = mp_mulmod(key->k, r, p, s)) != CRYPT_OK) { goto error; } /* s = xr */ if ((err = mp_mulmod(key->k, r, p, s)) != CRYPT_OK) { goto error; } /* s = xr */
if ((err = mp_add(e, s, s)) != CRYPT_OK) { goto error; } /* s = e + xr */ if ((err = mp_mulmod(pubkey.k, s, p, s)) != CRYPT_OK) { goto error; } /* s = xr/kb */
if ((err = mp_mod(s, p, s)) != CRYPT_OK) { goto error; } /* s = e + xr */ if ((err = mp_mulmod(pubkey.k, e, p, e)) != CRYPT_OK) { goto error; } /* e = e/kb */
if ((err = mp_mulmod(s, pubkey.k, p, s)) != CRYPT_OK) { goto error; } /* s = (e + xr)/k */ if ((err = mp_add(e, s, s)) != CRYPT_OK) { goto error; } /* s = e/kb + xr/kb */
if ((err = mp_mulmod(s, b, p, s)) != CRYPT_OK) { goto error; } /* s = b(e/kb + xr/kb) = (e + xr)/k */
ecc_free(&pubkey); ecc_free(&pubkey);
if (mp_iszero(s) == LTC_MP_NO) { if (mp_iszero(s) == LTC_MP_NO) {
break; break;
@ -121,7 +124,7 @@ static int _ecc_sign_hash(const unsigned char *in, unsigned long inlen,
error: error:
ecc_free(&pubkey); ecc_free(&pubkey);
errnokey: errnokey:
mp_clear_multi(r, s, p, e, NULL); mp_clear_multi(r, s, p, e, b, NULL);
return err; return err;
} }

View File

@ -58,7 +58,7 @@ int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key
unsigned char* tmp = NULL; unsigned char* tmp = NULL;
if (type & PK_STD) { if (type & PK_STD) {
tmplen = (mp_count_bits(key->N)/8)*2+8; tmplen = (unsigned long)(mp_count_bits(key->N) / 8) * 2 + 8;
tmp = XMALLOC(tmplen); tmp = XMALLOC(tmplen);
ptmplen = &tmplen; ptmplen = &tmplen;
if (tmp == NULL) { if (tmp == NULL) {

View File

@ -114,7 +114,7 @@ int rsa_import_pkcs8(const unsigned char *in, unsigned long inlen,
/* check alg oid */ /* check alg oid */
if ((alg_seq[0].size != rsaoid.OIDlen) || if ((alg_seq[0].size != rsaoid.OIDlen) ||
XMEMCMP(rsaoid.OID, alg_seq[0].data, rsaoid.OIDlen * sizeof(rsaoid.OID[0]))) { XMEMCMP(rsaoid.OID, alg_seq[0].data, rsaoid.OIDlen * sizeof(rsaoid.OID[0])) != 0) {
err = CRYPT_PK_INVALID_TYPE; err = CRYPT_PK_INVALID_TYPE;
goto LBL_ERR; goto LBL_ERR;
} }

View File

@ -66,9 +66,9 @@ static int _fortuna_reseed(prng_state *prng)
{ {
unsigned char tmp[MAXBLOCKSIZE]; unsigned char tmp[MAXBLOCKSIZE];
hash_state md; hash_state md;
ulong64 reset_cnt;
int err, x; int err, x;
++prng->fortuna.reset_cnt;
/* new K == LTC_SHA256(K || s) where s == LTC_SHA256(P0) || LTC_SHA256(P1) ... */ /* new K == LTC_SHA256(K || s) where s == LTC_SHA256(P0) || LTC_SHA256(P1) ... */
sha256_init(&md); sha256_init(&md);
@ -77,8 +77,10 @@ static int _fortuna_reseed(prng_state *prng)
return err; return err;
} }
reset_cnt = prng->fortuna.reset_cnt + 1;
for (x = 0; x < LTC_FORTUNA_POOLS; x++) { for (x = 0; x < LTC_FORTUNA_POOLS; x++) {
if (x == 0 || ((prng->fortuna.reset_cnt >> (x-1)) & 1) == 0) { if (x == 0 || ((reset_cnt >> (x-1)) & 1) == 0) {
/* terminate this hash */ /* terminate this hash */
if ((err = sha256_done(&prng->fortuna.pool[x], tmp)) != CRYPT_OK) { if ((err = sha256_done(&prng->fortuna.pool[x], tmp)) != CRYPT_OK) {
sha256_done(&md, tmp); sha256_done(&md, tmp);
@ -108,9 +110,10 @@ static int _fortuna_reseed(prng_state *prng)
} }
_fortuna_update_iv(prng); _fortuna_update_iv(prng);
/* reset pool len */ /* reset/update internals */
prng->fortuna.pool0_len = 0; prng->fortuna.pool0_len = 0;
prng->fortuna.wd = 0; prng->fortuna.wd = 0;
prng->fortuna.reset_cnt = reset_cnt;
#ifdef LTC_CLEAN_STACK #ifdef LTC_CLEAN_STACK
@ -121,6 +124,46 @@ static int _fortuna_reseed(prng_state *prng)
return CRYPT_OK; return CRYPT_OK;
} }
/**
"Update Seed File"-compliant update of K
@param in The PRNG state
@param inlen Size of the state
@param prng The PRNG to import
@return CRYPT_OK if successful
*/
static int _fortuna_update_seed(const unsigned char *in, unsigned long inlen, prng_state *prng)
{
int err;
unsigned char tmp[MAXBLOCKSIZE];
hash_state md;
LTC_MUTEX_LOCK(&prng->lock);
/* new K = LTC_SHA256(K || in) */
sha256_init(&md);
if ((err = sha256_process(&md, prng->fortuna.K, 32)) != CRYPT_OK) {
sha256_done(&md, tmp);
goto LBL_UNLOCK;
}
if ((err = sha256_process(&md, in, inlen)) != CRYPT_OK) {
sha256_done(&md, tmp);
goto LBL_UNLOCK;
}
/* finish key */
if ((err = sha256_done(&md, prng->fortuna.K)) != CRYPT_OK) {
goto LBL_UNLOCK;
}
_fortuna_update_iv(prng);
LBL_UNLOCK:
LTC_MUTEX_UNLOCK(&prng->lock);
#ifdef LTC_CLEAN_STACK
zeromem(&md, sizeof(md));
#endif
return err;
}
/** /**
Start the PRNG Start the PRNG
@param prng [out] The PRNG state to initialize @param prng [out] The PRNG state to initialize
@ -245,12 +288,17 @@ unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state
} }
/* do we have to reseed? */ /* do we have to reseed? */
if (++prng->fortuna.wd == LTC_FORTUNA_WD || prng->fortuna.pool0_len >= 64) { if ((++prng->fortuna.wd == LTC_FORTUNA_WD) && (prng->fortuna.pool0_len >= 64)) {
if (_fortuna_reseed(prng) != CRYPT_OK) { if (_fortuna_reseed(prng) != CRYPT_OK) {
goto LBL_UNLOCK; goto LBL_UNLOCK;
} }
} }
/* ensure that one reseed happened before allowing to read */
if (prng->fortuna.reset_cnt == 0) {
goto LBL_UNLOCK;
}
/* now generate the blocks required */ /* now generate the blocks required */
tlen = outlen; tlen = outlen;
@ -404,10 +452,10 @@ LBL_UNLOCK:
*/ */
int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prng) int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
{ {
int err, x; int err;
LTC_ARGCHK(in != NULL); LTC_ARGCHK(in != NULL);
LTC_ARGCHK(prng != NULL); LTC_ARGCHK(prng != NULL);
if (inlen < (unsigned long)fortuna_desc.export_size) { if (inlen < (unsigned long)fortuna_desc.export_size) {
return CRYPT_INVALID_ARG; return CRYPT_INVALID_ARG;
@ -416,12 +464,12 @@ int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prn
if ((err = fortuna_start(prng)) != CRYPT_OK) { if ((err = fortuna_start(prng)) != CRYPT_OK) {
return err; return err;
} }
for (x = 0; x < LTC_FORTUNA_POOLS; x++) {
if ((err = fortuna_add_entropy(in+x*32, 32, prng)) != CRYPT_OK) { if ((err = _fortuna_update_seed(in, inlen, prng)) != CRYPT_OK) {
return err; return err;
}
} }
return CRYPT_OK;
return err;
} }
/** /**

View File

@ -189,7 +189,7 @@ int sober128_import(const unsigned char *in, unsigned long inlen, prng_state *pr
if (inlen < (unsigned long)sober128_desc.export_size) return CRYPT_INVALID_ARG; if (inlen < (unsigned long)sober128_desc.export_size) return CRYPT_INVALID_ARG;
if ((err = sober128_start(prng)) != CRYPT_OK) return err; if ((err = sober128_start(prng)) != CRYPT_OK) return err;
if ((err = sober128_add_entropy(in, sober128_desc.export_size, prng)) != CRYPT_OK) return err; if ((err = sober128_add_entropy(in, inlen, prng)) != CRYPT_OK) return err;
return CRYPT_OK; return CRYPT_OK;
} }

View File

@ -16,9 +16,11 @@ extern prng_state yarrow_prng;
#ifdef LTC_VERBOSE #ifdef LTC_VERBOSE
#define DO(x) do { fprintf(stderr, "%s:\n", #x); run_cmd((x), __LINE__, __FILE__, #x, NULL); } while (0) #define DO(x) do { fprintf(stderr, "%s:\n", #x); run_cmd((x), __LINE__, __FILE__, #x, NULL); } while (0)
#define DOX(x, str) do { fprintf(stderr, "%s - %s:\n", #x, (str)); run_cmd((x), __LINE__, __FILE__, #x, (str)); } while (0) #define DOX(x, str) do { fprintf(stderr, "%s - %s:\n", #x, (str)); run_cmd((x), __LINE__, __FILE__, #x, (str)); } while (0)
#define SHOULD_FAIL(x) do { fprintf(stderr, "%s:\n", #x); run_cmd((x) != CRYPT_OK ? CRYPT_OK : CRYPT_FAIL_TESTVECTOR, __LINE__, __FILE__, #x, NULL); } while (0)
#else #else
#define DO(x) do { run_cmd((x), __LINE__, __FILE__, #x, NULL); } while (0) #define DO(x) do { run_cmd((x), __LINE__, __FILE__, #x, NULL); } while (0)
#define DOX(x, str) do { run_cmd((x), __LINE__, __FILE__, #x, (str)); } while (0) #define DOX(x, str) do { run_cmd((x), __LINE__, __FILE__, #x, (str)); } while (0)
#define SHOULD_FAIL(x) do { run_cmd((x) != CRYPT_OK ? CRYPT_OK : CRYPT_FAIL_TESTVECTOR, __LINE__, __FILE__, #x, NULL); } while (0)
#endif #endif
void run_cmd(int res, int line, const char *file, const char *cmd, const char *algorithm); void run_cmd(int res, int line, const char *file, const char *cmd, const char *algorithm);

View File

@ -1094,6 +1094,25 @@ static int der_choice_test(void)
} }
static void _der_recursion_limit(void)
{
int failed = 0;
unsigned int n;
unsigned long integer = 123, s;
ltc_asn1_list seqs[LTC_DER_MAX_RECURSION + 2], dummy[1], *flexi;
unsigned char buf[2048];
LTC_SET_ASN1(dummy, 0, LTC_ASN1_SHORT_INTEGER, &integer, 1);
LTC_SET_ASN1(seqs, LTC_DER_MAX_RECURSION + 1, LTC_ASN1_SEQUENCE, dummy, 1);
for (n = 0; n < LTC_DER_MAX_RECURSION + 1; ++n) {
LTC_SET_ASN1(seqs, LTC_DER_MAX_RECURSION - n, LTC_ASN1_SEQUENCE, &seqs[LTC_DER_MAX_RECURSION - n + 1], 1);
}
s = sizeof(buf);
DO(der_encode_sequence(seqs, 1, buf, &s));
DO(der_decode_sequence(buf, s, seqs, 1));
SHOULD_FAIL(der_decode_sequence_flexi(buf, &s, &flexi));
if (failed) exit(EXIT_FAILURE);
}
int der_test(void) int der_test(void)
{ {
unsigned long x, y, z, zz, oid[2][32]; unsigned long x, y, z, zz, oid[2][32];
@ -1126,6 +1145,8 @@ int der_test(void)
unsigned char utf8_buf[32]; unsigned char utf8_buf[32];
wchar_t utf8_out[32]; wchar_t utf8_out[32];
_der_recursion_limit();
der_cacert_test(); der_cacert_test();
DO(mp_init_multi(&a, &b, &c, &d, &e, &f, &g, NULL)); DO(mp_init_multi(&a, &b, &c, &d, &e, &f, &g, NULL));