├── emv.c ├── include └── libemv.h ├── demo └── libemv-demo-windows-0.1.exe ├── crypt ├── r_random.h ├── prime.h ├── rsaref.h ├── md5.h ├── rsa.h ├── global.h ├── sha1.h ├── r_stdlib.c ├── r_random.c ├── nn.h ├── r_keygen.c ├── rsaeuro.h ├── des.h ├── md5.c ├── prime.c ├── sha1.c ├── rsa.c ├── nn.c └── des.c ├── tools.c ├── .gitignore ├── libemv.sln ├── init.c ├── params.c ├── libemv.vcproj ├── internal.h ├── tlv.c └── main.cpp /emv.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbteam/libemv/HEAD/emv.c -------------------------------------------------------------------------------- /include/libemv.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbteam/libemv/HEAD/include/libemv.h -------------------------------------------------------------------------------- /demo/libemv-demo-windows-0.1.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbteam/libemv/HEAD/demo/libemv-demo-windows-0.1.exe -------------------------------------------------------------------------------- /crypt/r_random.h: -------------------------------------------------------------------------------- 1 | /* 2 | R_RANDOM.H - header file for R_RANDOM.C 3 | Copyright(C) 2002 by charry, charry@email.com.cn 4 | RSAEURO - RSA Library compatible with RSAREF 2.0. 5 | 6 | Random Number Routines Header File. 7 | */ 8 | 9 | int R_GenerateBytes PROTO_LIST 10 | ((unsigned char *, unsigned int, R_RANDOM_STRUCT *)); 11 | -------------------------------------------------------------------------------- /crypt/prime.h: -------------------------------------------------------------------------------- 1 | /* 2 | PRIME.H - header file for PRIME.C 3 | Copyright(C) 2002 by charry, charry@email.com.cn 4 | RSAEURO - RSA Library compatible with RSAREF 2.0. 5 | 6 | Prime Number routines header file. 7 | */ 8 | 9 | int GeneratePrime PROTO_LIST ((NN_DIGIT *, NN_DIGIT *, NN_DIGIT *, NN_DIGIT *, unsigned int, R_RANDOM_STRUCT *)); 10 | -------------------------------------------------------------------------------- /tools.c: -------------------------------------------------------------------------------- 1 | #include "include/libemv.h" 2 | #include "internal.h" 3 | #include 4 | 5 | void libemv_debug_buffer(char* strPre, unsigned char* buf, int size, char* strPost) 6 | { 7 | int i; 8 | libemv_printf(strPre); 9 | for (i = 0; i < size; i++) 10 | { 11 | libemv_printf("%02X", buf[i] & 0xFF); 12 | if (i != size - 1) 13 | libemv_printf(", "); 14 | } 15 | libemv_printf(strPost); 16 | } 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #ignore thumbnails created by windows 2 | Thumbs.db 3 | #Ignore files build by Visual Studio 4 | *.obj 5 | *.pdb 6 | *.aps 7 | *.pch 8 | *.vspscc 9 | *_i.c 10 | *_p.c 11 | *.ncb 12 | *.suo 13 | *.tlb 14 | *.tlh 15 | *.bak 16 | *.cache 17 | *.ilk 18 | *.dll 19 | [Bb]in 20 | [Dd]ebug*/ 21 | *.sbr 22 | obj/ 23 | [Rr]elease*/ 24 | _ReSharper*/ 25 | [Tt]est[Rr]esult* 26 | *.scc 27 | GeneratedFiles/ 28 | *.idb 29 | *.user 30 | CVS*/ 31 | -------------------------------------------------------------------------------- /crypt/rsaref.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | RSAREF.H - header file for RSAEURO cryptographic toolkit 4 | Copyright(C) 2002 by charry, charry@email.com.cn 5 | RSAEURO - RSA Library compatible with RSAREF 2.0. 6 | 7 | This header file is used to launch the RSAEURO.H header file. 8 | Provided for compatiblity with RSAREF. 9 | */ 10 | 11 | #ifndef _RSAREF_H_ 12 | #define _RSAREF_H_ 13 | 14 | #include "rsaeuro.h" 15 | 16 | #endif /* _RSAREF_H_ */ 17 | -------------------------------------------------------------------------------- /crypt/md5.h: -------------------------------------------------------------------------------- 1 | /* 2 | MD5.H - header file for MD5.C 3 | Copyright(C) 2002 by charry, charry@email.com.cn 4 | */ 5 | 6 | /* MD5 context. */ 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | typedef struct { 13 | UINT4 state[4]; /* state (ABCD) */ 14 | UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ 15 | unsigned char buffer[64]; /* input buffer */ 16 | } MD5_CTX; 17 | 18 | void MD5Init PROTO_LIST ((MD5_CTX *)); 19 | void MD5Update PROTO_LIST 20 | ((MD5_CTX *, unsigned char *, unsigned int)); 21 | void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *)); 22 | 23 | #ifdef __cplusplus 24 | } 25 | #endif 26 | -------------------------------------------------------------------------------- /crypt/rsa.h: -------------------------------------------------------------------------------- 1 | /* 2 | RSA.H - header file for RSA.C 3 | Copyright(C) 2002 by charry, charry@email.com.cn 4 | RSAEURO - RSA Library compatible with RSAREF 2.0. 5 | 6 | RSA Routines Header File. 7 | */ 8 | 9 | #ifdef __cplusplus 10 | extern "C" 11 | { 12 | #endif 13 | 14 | int RSAPublicEncrypt PROTO_LIST ((unsigned char *, unsigned int *, unsigned char *, unsigned int, 15 | R_RSA_PUBLIC_KEY *, R_RANDOM_STRUCT *)); 16 | int RSAPrivateEncrypt PROTO_LIST ((unsigned char *, unsigned int *, unsigned char *, unsigned int, 17 | R_RSA_PRIVATE_KEY *)); 18 | int RSAPublicDecrypt PROTO_LIST ((unsigned char *, unsigned int *, unsigned char *, unsigned int, 19 | R_RSA_PUBLIC_KEY *)); 20 | int RSAPrivateDecrypt PROTO_LIST ((unsigned char *, unsigned int *, unsigned char *, unsigned int, 21 | R_RSA_PRIVATE_KEY *)); 22 | 23 | #ifdef __cplusplus 24 | } 25 | #endif -------------------------------------------------------------------------------- /libemv.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual Studio 2008 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libemv", "libemv.vcproj", "{EB0A60F2-DCE5-4D91-AD52-C495B96369C4}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {EB0A60F2-DCE5-4D91-AD52-C495B96369C4}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {EB0A60F2-DCE5-4D91-AD52-C495B96369C4}.Debug|Win32.Build.0 = Debug|Win32 14 | {EB0A60F2-DCE5-4D91-AD52-C495B96369C4}.Release|Win32.ActiveCfg = Release|Win32 15 | {EB0A60F2-DCE5-4D91-AD52-C495B96369C4}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /crypt/global.h: -------------------------------------------------------------------------------- 1 | /* 2 | GLOBAL.H - RSAEURO types and constants 3 | Copyright(C) 2002 by charry, charry@email.com.cn 4 | RSAEURO - RSA Library compatible with RSAREF 2.0. 5 | 6 | Global types and contants file. 7 | */ 8 | 9 | #ifndef _GLOBAL_H_ 10 | #define _GLOBAL_H_ 11 | 12 | /* PROTOTYPES should be set to one if and only if the compiler supports 13 | function argument prototyping. 14 | The following makes PROTOTYPES default to 1 if it has not already been 15 | defined as 0 with C compiler flags. 16 | */ 17 | 18 | #ifndef PROTOTYPES 19 | #define PROTOTYPES 1 20 | #endif 21 | 22 | /* POINTER defines a generic pointer type */ 23 | 24 | typedef unsigned char *POINTER; 25 | 26 | /* UINT2 defines a two byte word */ 27 | 28 | typedef unsigned short int UINT2; 29 | 30 | /* UINT4 defines a four byte word */ 31 | 32 | typedef unsigned long int UINT4; 33 | 34 | /* BYTE defines a unsigned character */ 35 | 36 | typedef unsigned char BYTE; 37 | 38 | /* internal signed value */ 39 | 40 | typedef signed long int signeddigit; 41 | 42 | #ifndef NULL_PTR 43 | #define NULL_PTR ((POINTER)0) 44 | #endif 45 | 46 | #ifndef UNUSED_ARG 47 | #define UNUSED_ARG(x) x = *(&x); 48 | #endif 49 | 50 | /* PROTO_LIST is defined depending on how PROTOTYPES is defined above. 51 | If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it 52 | returns an empty list. 53 | */ 54 | 55 | #if PROTOTYPES 56 | #define PROTO_LIST(list) list 57 | #else 58 | #define PROTO_LIST(list) () 59 | #endif 60 | 61 | #endif /* _GLOBAL_H_ */ 62 | -------------------------------------------------------------------------------- /crypt/sha1.h: -------------------------------------------------------------------------------- 1 | /* 2 | * sha1.h 3 | * 4 | * Copyright (C) 1998, 2009 5 | * Paul E. Jones 6 | * All Rights Reserved 7 | * 8 | ***************************************************************************** 9 | * $Id: sha1.h 12 2009-06-22 19:34:25Z paulej $ 10 | ***************************************************************************** 11 | * 12 | * Description: 13 | * This class implements the Secure Hashing Standard as defined 14 | * in FIPS PUB 180-1 published April 17, 1995. 15 | * 16 | * Many of the variable names in the SHA1Context, especially the 17 | * single character names, were used because those were the names 18 | * used in the publication. 19 | * 20 | * Please read the file sha1.c for more information. 21 | * 22 | */ 23 | 24 | #ifndef _SHA1_H_ 25 | #define _SHA1_H_ 26 | 27 | /* 28 | * This structure will hold context information for the hashing 29 | * operation 30 | */ 31 | typedef struct SHA1Context 32 | { 33 | unsigned Message_Digest[5]; /* Message Digest (output) */ 34 | 35 | unsigned Length_Low; /* Message length in bits */ 36 | unsigned Length_High; /* Message length in bits */ 37 | 38 | unsigned char Message_Block[64]; /* 512-bit message blocks */ 39 | int Message_Block_Index; /* Index into message block array */ 40 | 41 | int Computed; /* Is the digest computed? */ 42 | int Corrupted; /* Is the message digest corruped? */ 43 | } SHA1Context; 44 | 45 | /* 46 | * Function Prototypes 47 | */ 48 | void SHA1Reset(SHA1Context *); 49 | int SHA1Result(SHA1Context *); 50 | void SHA1Input( SHA1Context *, 51 | const unsigned char *, 52 | unsigned); 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /init.c: -------------------------------------------------------------------------------- 1 | #include "include/libemv.h" 2 | #include "internal.h" 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | static void init_functions(void); 10 | static void get_transaction_date_YYMMDD(char* strdate); 11 | static void get_transaction_time_HHmmss(char* strtime); 12 | 13 | // This function can cause problems in custom platforms 14 | static void init_functions(void) 15 | { 16 | libemv_ext_apdu = 0; 17 | 18 | libemv_malloc = malloc; 19 | libemv_realloc = realloc; 20 | libemv_free = free; 21 | 22 | libemv_get_date = get_transaction_date_YYMMDD; 23 | libemv_get_time = get_transaction_time_HHmmss; 24 | 25 | libemv_rand = rand; 26 | 27 | libemv_printf = printf; 28 | } 29 | 30 | // This function can cause problems in custom platforms 31 | static void get_transaction_date_YYMMDD(char* strdate) 32 | { 33 | time_t rawtime; 34 | time(&rawtime); 35 | strftime(strdate, 6, "%y%m%d", localtime(&rawtime)); 36 | } 37 | 38 | // This function can cause problems in custom platforms 39 | static void get_transaction_time_HHmmss(char* strtime) 40 | { 41 | time_t rawtime; 42 | time(&rawtime); 43 | strftime(strtime, 6, "%H%M%S", localtime(&rawtime)); 44 | } 45 | 46 | LIBEMV_API void libemv_init(void) 47 | { 48 | init_functions(); 49 | libemv_debug_enabled = 0; 50 | 51 | libemv_init_tlv_buffer(); 52 | 53 | // Settings 54 | memset(&libemv_settings, 0, sizeof(libemv_settings)); 55 | memset(&libemv_global, 0, sizeof(libemv_global)); 56 | libemv_applications_count = 0; 57 | libemv_applications = 0; 58 | libemv_settings.appSelectionUsePSE = 1; 59 | libemv_settings.appSelectionSupportConfirm = 1; 60 | libemv_settings.appSelectionPartial = 1; 61 | libemv_settings.appSelectionSupport = 1; 62 | } 63 | 64 | LIBEMV_API void libemv_destroy(void) 65 | { 66 | if (libemv_debug_enabled) 67 | libemv_printf("Destroy allocated data...\n"); 68 | libemv_destroy_tlv_buffer(); 69 | libemv_destroy_settings(); 70 | } 71 | -------------------------------------------------------------------------------- /crypt/r_stdlib.c: -------------------------------------------------------------------------------- 1 | /* 2 | R_STDLIB.C - platform-specific C library routines for RSAEURO 3 | Copyright(C) 2002 by charry, charry@email.com.cn 4 | RSAEURO - RSA Library compatible with RSAREF(tm) 2.0. 5 | 6 | Secure Standard Library Routines. 7 | */ 8 | 9 | #include "rsaeuro.h" 10 | 11 | /* Library Copyright Message */ 12 | 13 | BYTE *Copyright[] = { "Copyright (c) J.S.A.Kapp 94-96." }; 14 | 15 | #ifndef USE_ANSI 16 | 17 | /* Secure memset routine */ 18 | 19 | #ifndef USEASM 20 | 21 | void R_memset(output, value, len) 22 | POINTER output; /* output block */ 23 | int value; /* value */ 24 | unsigned int len; /* length of block */ 25 | { 26 | if(len != 0) { 27 | do { 28 | *output++ = (unsigned char)value; 29 | }while(--len != 0); 30 | } 31 | } 32 | 33 | /* Secure memcpy routine */ 34 | 35 | void R_memcpy(output, input, len) 36 | POINTER output; /* output block */ 37 | POINTER input; /* input block */ 38 | unsigned int len; /* length of blocks */ 39 | { 40 | if (len != 0) { 41 | do { 42 | *output++ = *input++; 43 | }while (--len != 0); 44 | } 45 | } 46 | 47 | /* Secure memcmp routine */ 48 | 49 | int R_memcmp(Block1, Block2, len) 50 | POINTER Block1; /* first block */ 51 | POINTER Block2; /* second block */ 52 | unsigned int len; /* length of blocks */ 53 | { 54 | if(len != 0) { 55 | 56 | /* little trick in declaring vars */ 57 | 58 | register const unsigned char *p1 = Block1, *p2 = Block2; 59 | 60 | do { 61 | if(*p1++ != *p2++) 62 | return(*--p1 - *--p2); 63 | }while(--len != 0); 64 | } 65 | return(0); 66 | } 67 | 68 | #endif /* USEASM */ 69 | #endif /* USE_ANSI */ -------------------------------------------------------------------------------- /crypt/r_random.c: -------------------------------------------------------------------------------- 1 | /* 2 | R_RANDOM.C - random objects for RSAEURO 3 | Copyright(C) 2002 by charry, charry@email.com.cn 4 | RSAEURO - RSA Library compatible with RSAREF(tm) 2.0. 5 | 6 | Random Objects routines, based heavily on RSAREF(tm) random objects 7 | code. New routines REQUIRE and ANSI Standard C compiler that has 8 | clock() and time() functions. 9 | */ 10 | 11 | #include 12 | 13 | #ifdef MSDOS 14 | #include 15 | #endif 16 | 17 | #include "rsaeuro.h" 18 | #include "r_random.h" 19 | #include "md5.h" 20 | 21 | #define RANDOM_BYTES_RQ 256 22 | 23 | /* We use more seed data for an internally created object */ 24 | 25 | #define RANDOM_BYTES_RQINT 512 26 | 27 | /* Get the number of seed byte still required by the object */ 28 | 29 | int R_GetRandomBytesNeeded(bytesNeeded, random) 30 | unsigned int *bytesNeeded; /* number of mix-in bytes needed */ 31 | R_RANDOM_STRUCT *random; /* random structure */ 32 | { 33 | *bytesNeeded = random->bytesNeeded; 34 | 35 | return(ID_OK); 36 | } 37 | 38 | int R_GenerateBytes(block, len, random) 39 | unsigned char *block; /* block */ 40 | unsigned int len; /* length of block */ 41 | R_RANDOM_STRUCT *random; /* random structure */ 42 | { 43 | MD5_CTX context; 44 | unsigned int avail, i; 45 | 46 | if(random->bytesNeeded) 47 | return(RE_NEED_RANDOM); 48 | 49 | avail = random->outputAvailable; 50 | 51 | while(avail < len) { 52 | R_memcpy((POINTER)block, (POINTER)&random->output[16-avail], avail); 53 | len -= avail; 54 | block += avail; 55 | 56 | /* generate new output */ 57 | 58 | MD5Init(&context); 59 | MD5Update(&context, random->state, 16); 60 | MD5Final(random->output, &context); 61 | avail = 16; 62 | 63 | /* increment state */ 64 | 65 | for(i = 16; i > 0; i--) 66 | if(random->state[i-1]++) 67 | break; 68 | } 69 | 70 | R_memcpy((POINTER)block, (POINTER)&random->output[16-avail], len); 71 | random->outputAvailable = avail - len; 72 | 73 | return(ID_OK); 74 | } 75 | -------------------------------------------------------------------------------- /params.c: -------------------------------------------------------------------------------- 1 | #include "include/libemv.h" 2 | #include "internal.h" 3 | #include 4 | 5 | char (*libemv_ext_apdu)(unsigned char cla, unsigned char ins, unsigned char p1, unsigned char p2, 6 | unsigned char dataSize, const unsigned char* data, 7 | int* outDataSize, unsigned char* outData); 8 | 9 | void* (*libemv_malloc)(size_t size); 10 | void* (*libemv_realloc)(void* ptr, size_t size); 11 | void (*libemv_free)(void * ptr); 12 | 13 | void (*libemv_get_date)(char* strdate); 14 | void (*libemv_get_time)(char* strtime); 15 | 16 | int (*libemv_rand)(void); 17 | 18 | int (*libemv_printf)(const char * format, ...); 19 | 20 | char libemv_debug_enabled; 21 | 22 | LIBEMV_API void libemv_set_debug_enabled(char enabled) 23 | { 24 | libemv_debug_enabled = enabled; 25 | } 26 | 27 | LIBEMV_API void set_function_apdu(char (*f_apdu)(unsigned char cla, unsigned char ins, unsigned char p1, unsigned char p2, 28 | unsigned char dataSize, const unsigned char* data, 29 | int* outDataSize, unsigned char* outData)) 30 | { 31 | libemv_ext_apdu = f_apdu; 32 | } 33 | 34 | LIBEMV_API void set_function_malloc(void* (*f_malloc)(size_t size)) 35 | { 36 | libemv_malloc = f_malloc; 37 | } 38 | 39 | LIBEMV_API void set_function_realloc(void* (*f_realloc)(void* ptr, size_t size)) 40 | { 41 | libemv_realloc = f_realloc; 42 | } 43 | 44 | LIBEMV_API void set_function_free(void (*f_free)(void * ptr)) 45 | { 46 | libemv_free = f_free; 47 | } 48 | 49 | LIBEMV_API void set_function_get_date_YYMMDD(void (*f_get_date)(char* strdate)) 50 | { 51 | libemv_get_date = f_get_date; 52 | } 53 | 54 | LIBEMV_API void set_function_get_date_HHmmss(void (*f_get_time)(char* strtime)) 55 | { 56 | libemv_get_time = f_get_time; 57 | } 58 | 59 | LIBEMV_API void set_function_rand(int (*f_rand)(void)) 60 | { 61 | libemv_rand = f_rand; 62 | } 63 | 64 | LIBEMV_API void set_function_debug_printf(int (*f_printf)(const char * format, ...)) 65 | { 66 | libemv_printf = f_printf; 67 | } 68 | 69 | LIBEMV_SETTINGS libemv_settings; 70 | LIBEMV_GLOBAL libemv_global; 71 | int libemv_applications_count; 72 | LIBEMV_APPLICATIONS* libemv_applications; 73 | 74 | void libemv_destroy_settings(void) 75 | { 76 | if (libemv_applications) 77 | libemv_free(libemv_applications); 78 | } 79 | 80 | LIBEMV_API void libemv_set_library_settings(LIBEMV_SETTINGS* settings) 81 | { 82 | memcpy(&libemv_settings, settings, sizeof(LIBEMV_SETTINGS)); 83 | } 84 | 85 | LIBEMV_API void libemv_set_global_settings(LIBEMV_GLOBAL* settings) 86 | { 87 | memcpy(&libemv_global, settings, sizeof(LIBEMV_GLOBAL)); 88 | } 89 | 90 | LIBEMV_API void set_applications_data(LIBEMV_APPLICATIONS* apps, int countApps) 91 | { 92 | if (libemv_applications) 93 | libemv_free(libemv_applications); 94 | libemv_applications = libemv_malloc(countApps * sizeof(LIBEMV_APPLICATIONS)); 95 | memcpy(libemv_applications, apps, countApps * sizeof(LIBEMV_APPLICATIONS)); 96 | libemv_applications_count = countApps; 97 | } 98 | -------------------------------------------------------------------------------- /crypt/nn.h: -------------------------------------------------------------------------------- 1 | /* 2 | NN.H - header file for NN.C 3 | Copyright(C) 2002 by charry, charry@email.com.cn 4 | RSAEURO - RSA Library compatible with RSAREF 2.0. 5 | 6 | Math Library Routines Header File. 7 | */ 8 | 9 | #ifndef _NN_H_ 10 | #define _NN_H_ 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | /* Type definitions. */ 17 | 18 | typedef UINT4 NN_DIGIT; 19 | typedef UINT2 NN_HALF_DIGIT; 20 | 21 | /* Constants. 22 | 23 | Note: MAX_NN_DIGITS is long enough to hold any RSA modulus, plus 24 | one more digit as required by R_GeneratePEMKeys (for n and phiN, 25 | whose lengths must be even). All natural numbers have at most 26 | MAX_NN_DIGITS digits, except for double-length intermediate values 27 | in NN_Mult (t), NN_ModMult (t), NN_ModInv (w), and NN_Div (c). 28 | */ 29 | 30 | /* Length of digit in bits */ 31 | 32 | #define NN_DIGIT_BITS 32 33 | #define NN_HALF_DIGIT_BITS 16 34 | 35 | /* Length of digit in bytes */ 36 | 37 | #define NN_DIGIT_LEN (NN_DIGIT_BITS / 8) 38 | 39 | /* Maximum length in digits */ 40 | 41 | #define MAX_NN_DIGITS \ 42 | ((MAX_RSA_MODULUS_LEN + NN_DIGIT_LEN - 1) / NN_DIGIT_LEN + 1) 43 | 44 | /* Maximum digits */ 45 | 46 | #define MAX_NN_DIGIT 0xffffffff 47 | #define MAX_NN_HALF_DIGIT 0xffff 48 | 49 | #define NN_LT -1 50 | #define NN_EQ 0 51 | #define NN_GT 1 52 | 53 | /* Macros. */ 54 | 55 | #define LOW_HALF(x) ((x) & MAX_NN_HALF_DIGIT) 56 | #define HIGH_HALF(x) (((x) >> NN_HALF_DIGIT_BITS) & MAX_NN_HALF_DIGIT) 57 | #define TO_HIGH_HALF(x) (((NN_DIGIT)(x)) << NN_HALF_DIGIT_BITS) 58 | #define DIGIT_MSB(x) (unsigned int)(((x) >> (NN_DIGIT_BITS - 1)) & 1) 59 | #define DIGIT_2MSB(x) (unsigned int)(((x) >> (NN_DIGIT_BITS - 2)) & 3) 60 | 61 | /* CONVERSIONS 62 | NN_Decode (a, digits, b, len) Decodes character string b into a. 63 | NN_Encode (a, len, b, digits) Encodes a into character string b. 64 | 65 | ASSIGNMENTS 66 | NN_Assign (a, b, digits) Assigns a = b. 67 | NN_ASSIGN_DIGIT (a, b, digits) Assigns a = b, where b is a digit. 68 | NN_AssignZero (a, b, digits) Assigns a = 0. 69 | NN_Assign2Exp (a, b, digits) Assigns a = 2^b. 70 | 71 | ARITHMETIC OPERATIONS 72 | NN_Add (a, b, c, digits) Computes a = b + c. 73 | NN_Sub (a, b, c, digits) Computes a = b - c. 74 | NN_Mult (a, b, c, digits) Computes a = b * c. 75 | NN_LShift (a, b, c, digits) Computes a = b * 2^c. 76 | NN_RShift (a, b, c, digits) Computes a = b / 2^c. 77 | NN_Div (a, b, c, cDigits, d, dDigits) Computes a = c div d and b = c mod d. 78 | 79 | NUMBER THEORY 80 | NN_Mod (a, b, bDigits, c, cDigits) Computes a = b mod c. 81 | NN_ModMult (a, b, c, d, digits) Computes a = b * c mod d. 82 | NN_ModExp (a, b, c, cDigits, d, dDigits) Computes a = b^c mod d. 83 | NN_ModInv (a, b, c, digits) Computes a = 1/b mod c. 84 | NN_Gcd (a, b, c, digits) Computes a = gcd (b, c). 85 | 86 | OTHER OPERATIONS 87 | NN_EVEN (a, digits) Returns 1 iff a is even. 88 | NN_Cmp (a, b, digits) Returns sign of a - b. 89 | NN_EQUAL (a, digits) Returns 1 iff a = b. 90 | NN_Zero (a, digits) Returns 1 iff a = 0. 91 | NN_Digits (a, digits) Returns significant length of a in digits. 92 | NN_Bits (a, digits) Returns significant length of a in bits. 93 | */ 94 | 95 | void NN_Decode PROTO_LIST 96 | ((NN_DIGIT *, unsigned int, unsigned char *, unsigned int)); 97 | void NN_Encode PROTO_LIST 98 | ((unsigned char *, unsigned int, NN_DIGIT *, unsigned int)); 99 | 100 | void NN_Assign PROTO_LIST ((NN_DIGIT *, NN_DIGIT *, unsigned int)); 101 | void NN_AssignZero PROTO_LIST ((NN_DIGIT *, unsigned int)); 102 | void NN_Assign2Exp PROTO_LIST ((NN_DIGIT *, unsigned int, unsigned int)); 103 | 104 | NN_DIGIT NN_Add PROTO_LIST 105 | ((NN_DIGIT *, NN_DIGIT *, NN_DIGIT *, unsigned int)); 106 | NN_DIGIT NN_Sub PROTO_LIST 107 | ((NN_DIGIT *, NN_DIGIT *, NN_DIGIT *, unsigned int)); 108 | void NN_Mult PROTO_LIST ((NN_DIGIT *, NN_DIGIT *, NN_DIGIT *, unsigned int)); 109 | void NN_Div PROTO_LIST 110 | ((NN_DIGIT *, NN_DIGIT *, NN_DIGIT *, unsigned int, NN_DIGIT *, 111 | unsigned int)); 112 | NN_DIGIT NN_LShift PROTO_LIST 113 | ((NN_DIGIT *, NN_DIGIT *, unsigned int, unsigned int)); 114 | NN_DIGIT NN_RShift PROTO_LIST 115 | ((NN_DIGIT *, NN_DIGIT *, unsigned int, unsigned int)); 116 | NN_DIGIT NN_LRotate PROTO_LIST 117 | ((NN_DIGIT *, NN_DIGIT *, unsigned int, unsigned int)); 118 | 119 | void NN_Mod PROTO_LIST 120 | ((NN_DIGIT *, NN_DIGIT *, unsigned int, NN_DIGIT *, unsigned int)); 121 | void NN_ModMult PROTO_LIST 122 | ((NN_DIGIT *, NN_DIGIT *, NN_DIGIT *, NN_DIGIT *, unsigned int)); 123 | void NN_ModExp PROTO_LIST 124 | ((NN_DIGIT *, NN_DIGIT *, NN_DIGIT *, unsigned int, NN_DIGIT *, 125 | unsigned int)); 126 | void NN_ModInv PROTO_LIST 127 | ((NN_DIGIT *, NN_DIGIT *, NN_DIGIT *, unsigned int)); 128 | void NN_Gcd PROTO_LIST ((NN_DIGIT *, NN_DIGIT *, NN_DIGIT *, unsigned int)); 129 | 130 | int NN_Cmp PROTO_LIST ((NN_DIGIT *, NN_DIGIT *, unsigned int)); 131 | int NN_Zero PROTO_LIST ((NN_DIGIT *, unsigned int)); 132 | unsigned int NN_Bits PROTO_LIST ((NN_DIGIT *, unsigned int)); 133 | unsigned int NN_Digits PROTO_LIST ((NN_DIGIT *, unsigned int)); 134 | 135 | #define NN_ASSIGN_DIGIT(a, b, digits) {NN_AssignZero (a, digits); a[0] = b;} 136 | #define NN_EQUAL(a, b, digits) (! NN_Cmp (a, b, digits)) 137 | #define NN_EVEN(a, digits) (((digits) == 0) || ! (a[0] & 1)) 138 | 139 | #ifdef __cplusplus 140 | } 141 | #endif 142 | 143 | #endif /* _NN_H_ */ 144 | -------------------------------------------------------------------------------- /libemv.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 25 | 28 | 31 | 34 | 37 | 40 | 49 | 52 | 55 | 58 | 64 | 67 | 70 | 73 | 76 | 79 | 82 | 85 | 86 | 94 | 97 | 100 | 103 | 106 | 109 | 118 | 121 | 124 | 127 | 135 | 138 | 141 | 144 | 147 | 150 | 153 | 156 | 157 | 158 | 159 | 160 | 161 | 164 | 167 | 168 | 171 | 172 | 175 | 176 | 179 | 180 | 183 | 184 | 187 | 188 | 191 | 192 | 195 | 196 | 199 | 200 | 203 | 204 | 207 | 208 | 211 | 212 | 215 | 216 | 219 | 220 | 223 | 224 | 227 | 228 | 231 | 232 | 235 | 236 | 239 | 240 | 241 | 244 | 247 | 248 | 249 | 252 | 253 | 256 | 257 | 260 | 261 | 264 | 265 | 268 | 269 | 272 | 273 | 276 | 277 | 278 | 279 | 280 | 281 | -------------------------------------------------------------------------------- /crypt/r_keygen.c: -------------------------------------------------------------------------------- 1 | /* 2 | R_KEYGEN.C - key-pair generation for RSAEURO 3 | Copyright(C) 2002 by charry, charry@email.com.cn 4 | RSAEURO - RSA Library compatible with RSAREF(tm) 2.0. 5 | */ 6 | 7 | #include "rsaeuro.h" 8 | #include "r_random.h" 9 | #include "nn.h" 10 | #include "prime.h" 11 | 12 | static int RSAFilter PROTO_LIST 13 | ((NN_DIGIT *, unsigned int, NN_DIGIT *, unsigned int)); 14 | 15 | /* Generates an RSA key pair with a given length and public exponent. */ 16 | 17 | int R_GeneratePEMKeys(publicKey, privateKey, protoKey, randomStruct) 18 | R_RSA_PUBLIC_KEY *publicKey; /* new RSA public key */ 19 | R_RSA_PRIVATE_KEY *privateKey; /* new RSA private key */ 20 | R_RSA_PROTO_KEY *protoKey; /* RSA prototype key */ 21 | R_RANDOM_STRUCT *randomStruct; /* random structure */ 22 | { 23 | NN_DIGIT d[MAX_NN_DIGITS], dP[MAX_NN_DIGITS], dQ[MAX_NN_DIGITS], 24 | e[MAX_NN_DIGITS], n[MAX_NN_DIGITS], p[MAX_NN_DIGITS], phiN[MAX_NN_DIGITS], 25 | pMinus1[MAX_NN_DIGITS], q[MAX_NN_DIGITS], qInv[MAX_NN_DIGITS], 26 | qMinus1[MAX_NN_DIGITS], t[MAX_NN_DIGITS], u[MAX_NN_DIGITS], 27 | v[MAX_NN_DIGITS]; 28 | int status; 29 | unsigned int nDigits, pBits, pDigits, qBits; 30 | 31 | if((protoKey->bits < MIN_RSA_MODULUS_BITS) || (protoKey->bits > MAX_RSA_MODULUS_BITS)) 32 | return(RE_MODULUS_LEN); 33 | 34 | nDigits = (protoKey->bits + NN_DIGIT_BITS - 1) / NN_DIGIT_BITS; 35 | pDigits = (nDigits + 1) / 2; 36 | pBits = (protoKey->bits + 1) / 2; 37 | qBits = protoKey->bits - pBits; 38 | 39 | /* NB: for 65537, this means that NN_DIGIT is at least 17 bits 40 | in length. 41 | */ 42 | 43 | NN_ASSIGN_DIGIT(e, protoKey->useFermat4 ? (NN_DIGIT)65537 : (NN_DIGIT)3, nDigits); 44 | 45 | /* Generate prime p between 3*2^(pBits-2) and 2^pBits-1, searching 46 | in steps of 2, until one satisfies gcd (p-1, e) = 1. 47 | */ 48 | 49 | NN_Assign2Exp(t, pBits-1, pDigits); 50 | NN_Assign2Exp(u, pBits-2, pDigits); 51 | NN_Add(t, t, u, pDigits); 52 | NN_ASSIGN_DIGIT(v, 1, pDigits); 53 | NN_Sub(v, t, v, pDigits); 54 | NN_Add(u, u, v, pDigits); 55 | NN_ASSIGN_DIGIT(v, 2, pDigits); 56 | 57 | do { 58 | if(status = GeneratePrime(p, t, u, v, pDigits, randomStruct)) 59 | return(status); 60 | }while(!RSAFilter(p, pDigits, e, 1)); 61 | 62 | /* Generate prime q between 3*2^(qBits-2) and 2^qBits-1, searching 63 | in steps of 2, until one satisfies gcd (q-1, e) = 1. 64 | */ 65 | 66 | NN_Assign2Exp(t, qBits-1, pDigits); 67 | NN_Assign2Exp(u, qBits-2, pDigits); 68 | NN_Add(t, t, u, pDigits); 69 | NN_ASSIGN_DIGIT(v, 1, pDigits); 70 | NN_Sub(v, t, v, pDigits); 71 | NN_Add(u, u, v, pDigits); 72 | NN_ASSIGN_DIGIT(v, 2, pDigits); 73 | 74 | do { 75 | if(status = GeneratePrime(q, t, u, v, pDigits, randomStruct)) 76 | return(status); 77 | }while(!RSAFilter(q, pDigits, e, 1)); 78 | 79 | /* Sort so that p > q. (p = q case is extremely unlikely. */ 80 | 81 | if(NN_Cmp(p, q, pDigits) < 0) { 82 | NN_Assign(t, p, pDigits); 83 | NN_Assign(p, q, pDigits); 84 | NN_Assign(q, t, pDigits); 85 | } 86 | 87 | /* Compute n = pq, qInv = q^{-1} mod p, d = e^{-1} mod (p-1)(q-1), 88 | dP = d mod p-1, dQ = d mod q-1. 89 | */ 90 | 91 | NN_Mult(n, p, q, pDigits); 92 | NN_ModInv(qInv, q, p, pDigits); 93 | 94 | NN_ASSIGN_DIGIT(t, 1, pDigits); 95 | NN_Sub(pMinus1, p, t, pDigits); 96 | NN_Sub(qMinus1, q, t, pDigits); 97 | NN_Mult(phiN, pMinus1, qMinus1, pDigits); 98 | 99 | NN_ModInv(d, e, phiN, nDigits); 100 | NN_Mod(dP, d, nDigits, pMinus1, pDigits); 101 | NN_Mod(dQ, d, nDigits, qMinus1, pDigits); 102 | 103 | publicKey->bits = privateKey->bits = protoKey->bits; 104 | NN_Encode(publicKey->modulus, MAX_RSA_MODULUS_LEN, n, nDigits); 105 | NN_Encode(publicKey->exponent, MAX_RSA_MODULUS_LEN, e, 1); 106 | R_memcpy((POINTER)privateKey->modulus, (POINTER)publicKey->modulus, MAX_RSA_MODULUS_LEN); 107 | R_memcpy((POINTER)privateKey->publicExponent, (POINTER)publicKey->exponent, MAX_RSA_MODULUS_LEN); 108 | NN_Encode(privateKey->exponent, MAX_RSA_MODULUS_LEN, d, nDigits); 109 | NN_Encode(privateKey->prime[0], MAX_RSA_PRIME_LEN, p, pDigits); 110 | NN_Encode(privateKey->prime[1], MAX_RSA_PRIME_LEN, q, pDigits); 111 | NN_Encode(privateKey->primeExponent[0], MAX_RSA_PRIME_LEN, dP, pDigits); 112 | NN_Encode(privateKey->primeExponent[1], MAX_RSA_PRIME_LEN, dQ, pDigits); 113 | NN_Encode(privateKey->coefficient, MAX_RSA_PRIME_LEN, qInv, pDigits); 114 | 115 | /* Clear sensitive information. */ 116 | 117 | R_memset((POINTER)d, 0, sizeof(d)); 118 | R_memset((POINTER)dP, 0, sizeof(dP)); 119 | R_memset((POINTER)dQ, 0, sizeof(dQ)); 120 | R_memset((POINTER)p, 0, sizeof(p)); 121 | R_memset((POINTER)phiN, 0, sizeof(phiN)); 122 | R_memset((POINTER)pMinus1, 0, sizeof(pMinus1)); 123 | R_memset((POINTER)q, 0, sizeof(q)); 124 | R_memset((POINTER)qInv, 0, sizeof(qInv)); 125 | R_memset((POINTER)qMinus1, 0, sizeof(qMinus1)); 126 | R_memset((POINTER)t, 0, sizeof(t)); 127 | 128 | return (0); 129 | } 130 | 131 | /* Returns nonzero iff GCD (a-1, b) = 1. 132 | Assumes aDigits < MAX_NN_DIGITS, bDigits < MAX_NN_DIGITS. 133 | */ 134 | 135 | static int RSAFilter(a, aDigits, b, bDigits) 136 | NN_DIGIT *a, *b; 137 | unsigned int aDigits, bDigits; 138 | { 139 | int status = 0; 140 | NN_DIGIT aMinus1[MAX_NN_DIGITS], t[MAX_NN_DIGITS]; 141 | NN_DIGIT u[MAX_NN_DIGITS]; 142 | 143 | NN_ASSIGN_DIGIT(t, 1, aDigits); 144 | NN_Sub(aMinus1, a, t, aDigits); 145 | 146 | NN_Gcd(u, aMinus1, b, aDigits); 147 | 148 | status = NN_EQUAL(t, u, aDigits); 149 | 150 | R_memset((POINTER)aMinus1, 0, sizeof(aMinus1)); 151 | 152 | return(status); 153 | } -------------------------------------------------------------------------------- /internal.h: -------------------------------------------------------------------------------- 1 | #ifndef __INTERNAL_H 2 | #define __INTERNAL_H 3 | 4 | #include 5 | 6 | // Apdu transmit 7 | extern char (*libemv_ext_apdu)(unsigned char cla, unsigned char ins, unsigned char p1, unsigned char p2, 8 | unsigned char dataSize, const unsigned char* data, 9 | int* outDataSize, unsigned char* outData); 10 | 11 | // Alloc 12 | extern void* (*libemv_malloc)(size_t size); 13 | extern void* (*libemv_realloc)(void* ptr, size_t size); 14 | extern void (*libemv_free)(void * ptr); 15 | 16 | // Date time 17 | extern void (*libemv_get_date)(char* strdate); 18 | extern void (*libemv_get_time)(char* strtime); 19 | 20 | // Random 21 | extern int (*libemv_rand)(void); 22 | 23 | // Debug 24 | extern int (*libemv_printf)(const char * format, ...); 25 | 26 | // Debug disabled / enabled 27 | extern char libemv_debug_enabled; 28 | 29 | // Debug out binary 30 | void libemv_debug_buffer(char* strPre, unsigned char* buf, int size, char* strPost); 31 | 32 | // Init and destroy application buffer 33 | void libemv_init_tlv_buffer(void); 34 | void libemv_destroy_tlv_buffer(void); 35 | 36 | // Add or update tag in application buffer 37 | void libemv_set_tag(unsigned short tag, unsigned char* data, int size); 38 | 39 | // Clear application buffer data (not free memory) 40 | void libemv_clear_tlv_buffer(void); 41 | 42 | // Parse custom tlv buffer 43 | // outBuffer will point to inBuffer with some shift 44 | // Returns shift to the end of current [tag length value] 45 | int libemv_parse_tlv(unsigned char* inBuffer, int inBufferSize, unsigned short* outTag, unsigned char** outBuffer, int* outSize); 46 | 47 | // Make tlv from data (1 tag) 48 | // Returns maked size of tlvBuffer 49 | int libemv_make_tlv(unsigned char* inBuffer, int inBufferSize, unsigned short tag, unsigned char* tlvBuffer); 50 | 51 | // Make data from DOL list. If no data in buffer - fill zeros 52 | // Returns size of outBuffer 53 | int libemv_dol(unsigned char* dol, int dolSize, unsigned char* outBuffer); 54 | 55 | // Settings 56 | extern LIBEMV_SETTINGS libemv_settings; 57 | extern LIBEMV_GLOBAL libemv_global; 58 | extern int libemv_applications_count; 59 | extern LIBEMV_APPLICATIONS* libemv_applications; 60 | void libemv_destroy_settings(void); 61 | 62 | // Apdu function with debug info 63 | char libemv_apdu(unsigned char cla, unsigned char ins, unsigned char p1, unsigned char p2, 64 | unsigned char dataSize, const unsigned char* data, 65 | int* outDataSize, unsigned char* outData); 66 | 67 | // Tags 68 | #define TAG_FCI_TEMPLATE 0x6F 69 | #define TAG_DF_NAME 0x84 70 | #define TAG_FCI_PROP_TEMPLATE 0xA5 71 | #define TAG_SFI_OF_DEF 0x88 72 | #define TAG_LANGUAGE_PREFERENCE 0x5F2D 73 | #define TAG_ISSUER_CODE_TABLE_INDEX 0x9F11 74 | #define TAG_FCI_ISSUER_DISCR_DATA 0xBF0C 75 | #define TAG_APPLICATION_LABEL 0x50 76 | #define TAG_APP_PRIORITY_INDICATOR 0x87 77 | #define TAG_PDOL 0x9F38 78 | #define TAG_TVR 0x95 79 | #define TAG_TSI 0x9B 80 | #define TAG_APPLICATION_TEMPLATE 0x61 81 | #define TAG_ADF_NAME 0x4F 82 | #define TAG_APP_PREFERRED_NAME 0x9F12 83 | #define TAG_TERMINAL_CAPABILITIES 0x9F33 84 | #define TAG_ADDI_TERMINAL_CAPABILITIES 0x9F40 85 | #define TAG_AID 0x9F06 86 | #define TAG_IFD_SERIAL_NUMBER 0x9F1E 87 | #define TAG_TERMINAL_COUNTRY_CODE 0x9F1A 88 | #define TAG_TERMINAL_TYPE 0x9F35 89 | #define TAG_ACQUIRER_ID 0x9F01 90 | #define TAG_APPLICATION_VERSION_NUMBER 0x9F08 91 | #define TAG_MCC 0x9F15 92 | #define TAG_MERCHANT_ID 0x9F16 93 | #define TAG_MERCHANT_NAME_AND_LOCATION 0x9F4E 94 | #define TAG_TERMINAL_FLOOR_LIMIT 0x9F1B 95 | #define TAG_TERMINAL_ID 0x9F1C 96 | #define TAG_RISK_MANAGEMENT_DATA 0x9F1D 97 | #define TAG_TRANSACTION_REFERENCE_CURRENCY 0x9F3C 98 | #define TAG_TRANSACTION_REFERENCE_EXPONENT 0x9F3D 99 | #define TAG_AIP 0x82 100 | #define TAG_AFL 0x94 101 | #define TAG_COMMAND_TEMPLATE 0x83 102 | #define TAG_RESPONSE_FORMAT_1 0x80 103 | #define TAG_RESPONSE_FORMAT_2 0x77 104 | #define TAG_READ_RECORD_RESPONSE_TEMPLATE 0x70 105 | #define TAG_APPLICATION_EXP_DATE 0x5F24 106 | #define TAG_PAN 0x5A 107 | #define TAG_CDOL_1 0x8C 108 | #define TAG_CDOL_2 0x8D 109 | 110 | // Bit map, please control out of limits 111 | typedef struct 112 | { 113 | #ifdef BIG_ENDIAN 114 | unsigned char B1b8:1; 115 | unsigned char B1b7:1; 116 | unsigned char B1b6:1; 117 | unsigned char B1b5:1; 118 | unsigned char B1b4:1; 119 | unsigned char B1b3:1; 120 | unsigned char B1b2:1; 121 | unsigned char B1b1:1; 122 | 123 | unsigned char B2b8:1; 124 | unsigned char B2b7:1; 125 | unsigned char B2b6:1; 126 | unsigned char B2b5:1; 127 | unsigned char B2b4:1; 128 | unsigned char B2b3:1; 129 | unsigned char B2b2:1; 130 | unsigned char B2b1:1; 131 | 132 | unsigned char B3b8:1; 133 | unsigned char B3b7:1; 134 | unsigned char B3b6:1; 135 | unsigned char B3b5:1; 136 | unsigned char B3b4:1; 137 | unsigned char B3b3:1; 138 | unsigned char B3b2:1; 139 | unsigned char B3b1:1; 140 | 141 | unsigned char B4b8:1; 142 | unsigned char B4b7:1; 143 | unsigned char B4b6:1; 144 | unsigned char B4b5:1; 145 | unsigned char B4b4:1; 146 | unsigned char B4b3:1; 147 | unsigned char B4b2:1; 148 | unsigned char B4b1:1; 149 | 150 | unsigned char B5b8:1; 151 | unsigned char B5b7:1; 152 | unsigned char B5b6:1; 153 | unsigned char B5b5:1; 154 | unsigned char B5b4:1; 155 | unsigned char B5b3:1; 156 | unsigned char B5b2:1; 157 | unsigned char B5b1:1; 158 | #else 159 | unsigned char B1b1:1; 160 | unsigned char B1b2:1; 161 | unsigned char B1b3:1; 162 | unsigned char B1b4:1; 163 | unsigned char B1b5:1; 164 | unsigned char B1b6:1; 165 | unsigned char B1b7:1; 166 | unsigned char B1b8:1; 167 | 168 | unsigned char B2b1:1; 169 | unsigned char B2b2:1; 170 | unsigned char B2b3:1; 171 | unsigned char B2b4:1; 172 | unsigned char B2b5:1; 173 | unsigned char B2b6:1; 174 | unsigned char B2b7:1; 175 | unsigned char B2b8:1; 176 | 177 | unsigned char B3b1:1; 178 | unsigned char B3b2:1; 179 | unsigned char B3b3:1; 180 | unsigned char B3b4:1; 181 | unsigned char B3b5:1; 182 | unsigned char B3b6:1; 183 | unsigned char B3b7:1; 184 | unsigned char B3b8:1; 185 | 186 | unsigned char B4b1:1; 187 | unsigned char B4b2:1; 188 | unsigned char B4b3:1; 189 | unsigned char B4b4:1; 190 | unsigned char B4b5:1; 191 | unsigned char B4b6:1; 192 | unsigned char B4b7:1; 193 | unsigned char B4b8:1; 194 | 195 | unsigned char B5b1:1; 196 | unsigned char B5b2:1; 197 | unsigned char B5b3:1; 198 | unsigned char B5b4:1; 199 | unsigned char B5b5:1; 200 | unsigned char B5b6:1; 201 | unsigned char B5b7:1; 202 | unsigned char B5b8:1; 203 | #endif 204 | } EMV_BITS; 205 | 206 | extern EMV_BITS* libemv_TVR; 207 | extern EMV_BITS* libemv_TSI; 208 | extern EMV_BITS* libemv_capa; 209 | extern EMV_BITS* libemv_addi_capa; 210 | 211 | #endif // __INTERNAL_H 212 | -------------------------------------------------------------------------------- /crypt/rsaeuro.h: -------------------------------------------------------------------------------- 1 | /* 2 | RSAEURO.H - header file for RSAEURO cryptographic toolkit 3 | Copyright(C) 2002 by charry, charry@email.com.cn 4 | RSAEURO - RSA Library compatible with RSAREF(tm) 2.0. 5 | 6 | This header file contains prototypes, and other definitions used 7 | in and by RSAEURO. 8 | */ 9 | 10 | #ifndef _RSAEURO_H_ 11 | #define _RSAEURO_H_ 12 | 13 | #include 14 | 15 | #include "global.h" 16 | #include "nn.h" 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | /* Encryption algorithms to be ored with digest algorithm in Seal and Open. */ 23 | 24 | #define EA_DES_CBC 1 25 | #define EA_DES_EDE2_CBC 2 26 | #define EA_DES_EDE3_CBC 3 27 | #define EA_DESX_CBC 4 28 | 29 | 30 | /* RSA key lengths. */ 31 | 32 | #define MIN_RSA_MODULUS_BITS 508 33 | 34 | /* PGP 2.6.2 Now allows 2048-bit keys changing below will allow this. 35 | It does lengthen key generation slightly if the value is increased. 36 | */ 37 | 38 | #define MAX_RSA_MODULUS_BITS 2048 39 | #define MAX_RSA_MODULUS_LEN ((MAX_RSA_MODULUS_BITS + 7) / 8) 40 | #define MAX_RSA_PRIME_BITS ((MAX_RSA_MODULUS_BITS + 1) / 2) 41 | #define MAX_RSA_PRIME_LEN ((MAX_RSA_PRIME_BITS + 7) / 8) 42 | 43 | /* Maximum lengths of encoded and encrypted content, as a function of 44 | content length len. Also, inverse functions. 45 | */ 46 | 47 | #define ENCODED_CONTENT_LEN(len) (4*(len)/3 + 3) 48 | #define ENCRYPTED_CONTENT_LEN(len) ENCODED_CONTENT_LEN ((len)+8) 49 | #define DECODED_CONTENT_LEN(len) (3*(len)/4 + 1) 50 | #define DECRYPTED_CONTENT_LEN(len) (DECODED_CONTENT_LEN (len) - 1) 51 | 52 | /* Maximum lengths of signatures, encrypted keys, encrypted 53 | signatures, and message digests. 54 | */ 55 | 56 | #define MAX_SIGNATURE_LEN MAX_RSA_MODULUS_LEN 57 | #define MAX_PEM_SIGNATURE_LEN ENCODED_CONTENT_LEN(MAX_SIGNATURE_LEN) 58 | #define MAX_ENCRYPTED_KEY_LEN MAX_RSA_MODULUS_LEN 59 | #define MAX_PEM_ENCRYPTED_KEY_LEN ENCODED_CONTENT_LEN(MAX_ENCRYPTED_KEY_LEN) 60 | #define MAX_PEM_ENCRYPTED_SIGNATURE_LEN ENCRYPTED_CONTENT_LEN(MAX_SIGNATURE_LEN) 61 | #define MAX_DIGEST_LEN 20 62 | 63 | /* Error codes. */ 64 | 65 | #define RE_CONTENT_ENCODING 0x0400 66 | #define RE_DATA 0x0401 67 | #define RE_DIGEST_ALGORITHM 0x0402 68 | #define RE_ENCODING 0x0403 69 | #define RE_KEY 0x0404 70 | #define RE_KEY_ENCODING 0x0405 71 | #define RE_LEN 0x0406 72 | #define RE_MODULUS_LEN 0x0407 73 | #define RE_NEED_RANDOM 0x0408 74 | #define RE_PRIVATE_KEY 0x0409 75 | #define RE_PUBLIC_KEY 0x040a 76 | #define RE_SIGNATURE 0x040b 77 | #define RE_SIGNATURE_ENCODING 0x040c 78 | #define RE_ENCRYPTION_ALGORITHM 0x040d 79 | #define RE_FILE 0x040e 80 | 81 | /* Library details. */ 82 | 83 | #define RSAEURO_VER_MAJ 1 84 | #define RSAEURO_VER_MIN 04 85 | #define RSAEURO_IDENT "RSAEURO Toolkit" 86 | #define RSAEURO_DATE "21/08/94" 87 | 88 | /* Internal Error Codes */ 89 | 90 | /* IDOK and IDERROR changed to ID_OK and ID_ERROR */ 91 | 92 | #define ID_OK 0 93 | #define ID_ERROR 1 94 | 95 | /* Internal defs. */ 96 | 97 | #ifndef TRUE 98 | #define TRUE 1 99 | #endif 100 | #ifndef FALSE 101 | #define FALSE 0 102 | #endif 103 | 104 | /* Algorithm IDs */ 105 | 106 | #define IA_MD2 0x00000001 107 | #define IA_MD4 0x00000002 108 | #define IA_MD5 0x00000004 109 | #define IA_SHS 0x00000008 110 | #define IA_DES_CBC 0x00000010 111 | #define IA_DES_EDE2_CBC 0x00000020 112 | #define IA_DES_EDE3_CBC 0x00000040 113 | #define IA_DESX_CBC 0x00000080 114 | #define IA_RSA 0x00010000 115 | 116 | 117 | #define IA_FLAGS (IA_MD2|IA_MD4|IA_MD5|IA_SHS|IA_DES_CBC|IA_DES_EDE2_CBC|IA_DES_EDE3_CBC|IA_DESX_CBC|IA_RSA|IA_DH) 118 | 119 | /* RSAEuro Info Structure */ 120 | 121 | typedef struct { 122 | unsigned short int Version; /* RSAEuro Version */ 123 | unsigned int flags; /* Version Flags */ 124 | unsigned char ManufacturerID[32]; /* Toolkit ID */ 125 | unsigned int Algorithms; /* Algorithms Supported */ 126 | } RSAEUROINFO; 127 | 128 | /* Random structure. */ 129 | 130 | typedef struct { 131 | unsigned int bytesNeeded; /* seed bytes required */ 132 | unsigned char state[16]; /* state of object */ 133 | unsigned int outputAvailable; /* number byte available */ 134 | unsigned char output[16]; /* output bytes */ 135 | } R_RANDOM_STRUCT; 136 | 137 | /* RSA public and private key. */ 138 | 139 | typedef struct { 140 | unsigned int bits; /* length in bits of modulus */ 141 | unsigned char modulus[MAX_RSA_MODULUS_LEN]; /* modulus */ 142 | unsigned char exponent[MAX_RSA_MODULUS_LEN]; /* public exponent */ 143 | } R_RSA_PUBLIC_KEY; 144 | 145 | typedef struct { 146 | unsigned int bits; /* length in bits of modulus */ 147 | unsigned char modulus[MAX_RSA_MODULUS_LEN]; /* modulus */ 148 | unsigned char publicExponent[MAX_RSA_MODULUS_LEN]; /* public exponent */ 149 | unsigned char exponent[MAX_RSA_MODULUS_LEN]; /* private exponent */ 150 | unsigned char prime[2][MAX_RSA_PRIME_LEN]; /* prime factors */ 151 | unsigned char primeExponent[2][MAX_RSA_PRIME_LEN]; /* exponents for CRT */ 152 | unsigned char coefficient[MAX_RSA_PRIME_LEN]; /* CRT coefficient */ 153 | } R_RSA_PRIVATE_KEY; 154 | 155 | /* RSA prototype key. */ 156 | 157 | typedef struct { 158 | unsigned int bits; /* length in bits of modulus */ 159 | int useFermat4; /* public exponent (1 = F4, 0 = 3) */ 160 | } R_RSA_PROTO_KEY; 161 | 162 | /* Random Structures Routines. */ 163 | 164 | int R_GetRandomBytesNeeded PROTO_LIST ((unsigned int *, R_RANDOM_STRUCT *)); 165 | int R_GenerateBytes(unsigned char *block, unsigned int len, 166 | R_RANDOM_STRUCT *random); 167 | 168 | /* Printable ASCII encoding and decoding. */ 169 | 170 | int R_EncodePEMBlock PROTO_LIST ((unsigned char *, unsigned int *, 171 | unsigned char *, unsigned int)); 172 | int R_DecodePEMBlock PROTO_LIST ((unsigned char *, unsigned int *, 173 | unsigned char *, unsigned int)); 174 | 175 | /* Key-pair generation. */ 176 | 177 | int R_GeneratePEMKeys PROTO_LIST ((R_RSA_PUBLIC_KEY *, R_RSA_PRIVATE_KEY *, 178 | R_RSA_PROTO_KEY *, R_RANDOM_STRUCT *)); 179 | 180 | /* Standard library routines. */ 181 | 182 | #ifdef USE_ANSI 183 | #define R_memset(x, y, z) memset(x, y, z) 184 | #define R_memcpy(x, y, z) memcpy(x, y, z) 185 | #define R_memcmp(x, y, z) memcmp(x, y, z) 186 | #else 187 | void R_memset PROTO_LIST ((POINTER, int, unsigned int)); 188 | void R_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int)); 189 | int R_memcmp PROTO_LIST ((POINTER, POINTER, unsigned int)); 190 | #endif 191 | 192 | #ifdef __cplusplus 193 | } 194 | #endif 195 | 196 | #endif /* _RSAEURO_H_ */ 197 | -------------------------------------------------------------------------------- /crypt/des.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file des.h 3 | * 4 | * \brief DES block cipher 5 | * 6 | * Copyright (C) 2006-2010, Brainspark B.V. 7 | * 8 | * This file is part of PolarSSL (http://www.polarssl.org) 9 | * Lead Maintainer: Paul Bakker 10 | * 11 | * All rights reserved. 12 | * 13 | * This program is free software; you can redistribute it and/or modify 14 | * it under the terms of the GNU General Public License as published by 15 | * the Free Software Foundation; either version 2 of the License, or 16 | * (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License along 24 | * with this program; if not, write to the Free Software Foundation, Inc., 25 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 26 | */ 27 | #ifndef POLARSSL_DES_H 28 | #define POLARSSL_DES_H 29 | 30 | #include 31 | 32 | #define DES_ENCRYPT 1 33 | #define DES_DECRYPT 0 34 | 35 | #define POLARSSL_ERR_DES_INVALID_INPUT_LENGTH -0x0032 /**< The data input has an invalid length. */ 36 | 37 | #define DES_KEY_SIZE 8 38 | 39 | /** 40 | * \brief DES context structure 41 | */ 42 | typedef struct 43 | { 44 | int mode; /*!< encrypt/decrypt */ 45 | unsigned long sk[32]; /*!< DES subkeys */ 46 | } 47 | des_context; 48 | 49 | /** 50 | * \brief Triple-DES context structure 51 | */ 52 | typedef struct 53 | { 54 | int mode; /*!< encrypt/decrypt */ 55 | unsigned long sk[96]; /*!< 3DES subkeys */ 56 | } 57 | des3_context; 58 | 59 | #ifdef __cplusplus 60 | extern "C" { 61 | #endif 62 | 63 | /** 64 | * \brief Set key parity on the given key to odd. 65 | * 66 | * DES keys are 56 bits long, but each byte is padded with 67 | * a parity bit to allow verification. 68 | * 69 | * \param key 8-byte secret key 70 | */ 71 | void des_key_set_parity( unsigned char key[DES_KEY_SIZE] ); 72 | 73 | /** 74 | * \brief Check that key parity on the given key is odd. 75 | * 76 | * DES keys are 56 bits long, but each byte is padded with 77 | * a parity bit to allow verification. 78 | * 79 | * \param key 8-byte secret key 80 | * 81 | * \return 0 is parity was ok, 1 if parity was not correct. 82 | */ 83 | int des_key_check_key_parity( const unsigned char key[DES_KEY_SIZE] ); 84 | 85 | /** 86 | * \brief Check that key is not a weak or semi-weak DES key 87 | * 88 | * \param key 8-byte secret key 89 | * 90 | * \return 0 if no weak key was found, 1 if a weak key was identified. 91 | */ 92 | int des_key_check_weak( const unsigned char key[DES_KEY_SIZE] ); 93 | 94 | /** 95 | * \brief DES key schedule (56-bit, encryption) 96 | * 97 | * \param ctx DES context to be initialized 98 | * \param key 8-byte secret key 99 | * 100 | * \return 0 101 | */ 102 | int des_setkey_enc( des_context *ctx, const unsigned char key[DES_KEY_SIZE] ); 103 | 104 | /** 105 | * \brief DES key schedule (56-bit, decryption) 106 | * 107 | * \param ctx DES context to be initialized 108 | * \param key 8-byte secret key 109 | * 110 | * \return 0 111 | */ 112 | int des_setkey_dec( des_context *ctx, const unsigned char key[DES_KEY_SIZE] ); 113 | 114 | /** 115 | * \brief Triple-DES key schedule (112-bit, encryption) 116 | * 117 | * \param ctx 3DES context to be initialized 118 | * \param key 16-byte secret key 119 | * 120 | * \return 0 121 | */ 122 | int des3_set2key_enc( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 2] ); 123 | 124 | /** 125 | * \brief Triple-DES key schedule (112-bit, decryption) 126 | * 127 | * \param ctx 3DES context to be initialized 128 | * \param key 16-byte secret key 129 | * 130 | * \return 0 131 | */ 132 | int des3_set2key_dec( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 2] ); 133 | 134 | /** 135 | * \brief Triple-DES key schedule (168-bit, encryption) 136 | * 137 | * \param ctx 3DES context to be initialized 138 | * \param key 24-byte secret key 139 | * 140 | * \return 0 141 | */ 142 | int des3_set3key_enc( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 3] ); 143 | 144 | /** 145 | * \brief Triple-DES key schedule (168-bit, decryption) 146 | * 147 | * \param ctx 3DES context to be initialized 148 | * \param key 24-byte secret key 149 | * 150 | * \return 0 151 | */ 152 | int des3_set3key_dec( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 3] ); 153 | 154 | /** 155 | * \brief DES-ECB block encryption/decryption 156 | * 157 | * \param ctx DES context 158 | * \param input 64-bit input block 159 | * \param output 64-bit output block 160 | * 161 | * \return 0 if successful 162 | */ 163 | int des_crypt_ecb( des_context *ctx, 164 | const unsigned char input[8], 165 | unsigned char output[8] ); 166 | 167 | /** 168 | * \brief DES-CBC buffer encryption/decryption 169 | * 170 | * \param ctx DES context 171 | * \param mode DES_ENCRYPT or DES_DECRYPT 172 | * \param length length of the input data 173 | * \param iv initialization vector (updated after use) 174 | * \param input buffer holding the input data 175 | * \param output buffer holding the output data 176 | */ 177 | int des_crypt_cbc( des_context *ctx, 178 | int mode, 179 | size_t length, 180 | unsigned char iv[8], 181 | const unsigned char *input, 182 | unsigned char *output ); 183 | 184 | /** 185 | * \brief 3DES-ECB block encryption/decryption 186 | * 187 | * \param ctx 3DES context 188 | * \param input 64-bit input block 189 | * \param output 64-bit output block 190 | * 191 | * \return 0 if successful 192 | */ 193 | int des3_crypt_ecb( des3_context *ctx, 194 | const unsigned char input[8], 195 | unsigned char output[8] ); 196 | 197 | /** 198 | * \brief 3DES-CBC buffer encryption/decryption 199 | * 200 | * \param ctx 3DES context 201 | * \param mode DES_ENCRYPT or DES_DECRYPT 202 | * \param length length of the input data 203 | * \param iv initialization vector (updated after use) 204 | * \param input buffer holding the input data 205 | * \param output buffer holding the output data 206 | * 207 | * \return 0 if successful, or POLARSSL_ERR_DES_INVALID_INPUT_LENGTH 208 | */ 209 | int des3_crypt_cbc( des3_context *ctx, 210 | int mode, 211 | size_t length, 212 | unsigned char iv[8], 213 | const unsigned char *input, 214 | unsigned char *output ); 215 | 216 | /* 217 | * \brief Checkup routine 218 | * 219 | * \return 0 if successful, or 1 if the test failed 220 | */ 221 | int des_self_test( int verbose ); 222 | 223 | #ifdef __cplusplus 224 | } 225 | #endif 226 | 227 | #endif /* des.h */ 228 | -------------------------------------------------------------------------------- /tlv.c: -------------------------------------------------------------------------------- 1 | #include "include/libemv.h" 2 | #include "internal.h" 3 | #include 4 | 5 | // Application buffer, from ICC and terminal 6 | // ([unsigned short tag][int length][data]..) 7 | static unsigned char* tlv_buffer; 8 | static int tlv_allocated; 9 | static int tlv_length; 10 | 11 | void libemv_init_tlv_buffer(void) 12 | { 13 | tlv_buffer = 0; 14 | tlv_allocated = 0; 15 | tlv_length = 0; 16 | } 17 | 18 | void libemv_destroy_tlv_buffer(void) 19 | { 20 | if (tlv_buffer) 21 | libemv_free(tlv_buffer); 22 | } 23 | 24 | static void check_and_reserve_buffer(int incrSize) 25 | { 26 | if (tlv_length + incrSize <= tlv_allocated) 27 | return; 28 | 29 | if (tlv_allocated == 0) 30 | { 31 | // Init size 32 | tlv_allocated = 2 * 1024; 33 | tlv_buffer = libemv_malloc(tlv_allocated); 34 | } else 35 | { 36 | // incrSize musn't very big, but just in case 37 | while (tlv_length + incrSize > tlv_allocated) 38 | tlv_allocated *= 2; 39 | // Realloc must copy old data 40 | tlv_buffer = libemv_realloc(tlv_buffer, tlv_allocated); 41 | } 42 | 43 | // Unable allocate 44 | if (tlv_buffer == 0) 45 | { 46 | if (libemv_debug_enabled) 47 | libemv_printf("Unable allocate memory\n"); 48 | } 49 | } 50 | 51 | LIBEMV_API unsigned char* libemv_get_tag(unsigned short tag, int* outSize) 52 | { 53 | unsigned char* currBuf; 54 | int currPos; 55 | 56 | currBuf = tlv_buffer; 57 | currPos = 0; 58 | while (currPos < tlv_length) 59 | { 60 | unsigned short currTag; 61 | int currLength; 62 | 63 | // Corrupted buffer 64 | if (currPos + (int) sizeof(unsigned short) + (int) sizeof(int) > tlv_length) 65 | { 66 | if (libemv_debug_enabled) 67 | libemv_printf("tlv buffer malfunc\n"); 68 | break; 69 | } 70 | 71 | memcpy(&currTag, currBuf, sizeof(unsigned short)); 72 | currBuf += sizeof(unsigned short); 73 | currPos += sizeof(unsigned short); 74 | memcpy(&currLength, currBuf, sizeof(int)); 75 | currBuf += sizeof(int); 76 | currPos += sizeof(int); 77 | if (currTag == tag) 78 | { 79 | *outSize = currLength; 80 | return currBuf; 81 | } 82 | currBuf += currLength; 83 | currPos += currLength; 84 | } 85 | 86 | // Not found 87 | return 0; 88 | } 89 | 90 | int libemv_get_next_tag(int shift, unsigned short* outTag, unsigned char** outBuffer, int* outSize) 91 | { 92 | int sh; 93 | sh = shift; 94 | 95 | // Tag 96 | if (sh + (int) sizeof(unsigned short) > tlv_length) 97 | return 0; 98 | memcpy(outTag, tlv_buffer + sh, sizeof(unsigned short)); 99 | sh += sizeof(unsigned short); 100 | 101 | // Length 102 | if (sh + (int) sizeof(int) > tlv_length) 103 | return 0; 104 | memcpy(outSize, tlv_buffer + sh, sizeof(int)); 105 | sh += sizeof(int); 106 | 107 | // Value 108 | if (sh + *outSize > tlv_length) 109 | return 0; 110 | *outBuffer = tlv_buffer + sh; 111 | sh += *outSize; 112 | 113 | return sh; 114 | } 115 | 116 | void libemv_set_tag(unsigned short tag, unsigned char* data, int size) 117 | { 118 | unsigned char* findData; 119 | int findDataSize; 120 | findData = libemv_get_tag(tag, &findDataSize); 121 | if (findData) 122 | { 123 | // Replace data 124 | if (findDataSize == size) 125 | { 126 | // Size didn't change, just copy buffer 127 | memcpy(findData, data, size); 128 | } else 129 | { 130 | // Reserve memory and move data 131 | check_and_reserve_buffer(size - findDataSize); 132 | memmove(findData + size, findData + findDataSize, tlv_length - (findData - tlv_buffer) - findDataSize); 133 | memcpy(findData - sizeof(int), &size, sizeof(int)); 134 | memcpy(findData, data, size); 135 | tlv_length += size - findDataSize; 136 | } 137 | } else 138 | { 139 | unsigned char* endBuffer; 140 | // Add data to the end of buffer 141 | check_and_reserve_buffer(sizeof(unsigned short) + sizeof(int) + size); 142 | endBuffer = tlv_buffer + tlv_length; 143 | memcpy(endBuffer, &tag, sizeof(unsigned short)); 144 | endBuffer += sizeof(unsigned short); 145 | memcpy(endBuffer, &size, sizeof(int)); 146 | endBuffer += sizeof(int); 147 | memcpy(endBuffer, data, size); 148 | tlv_length += sizeof(unsigned short) + sizeof(int) + size; 149 | } 150 | } 151 | 152 | void libemv_clear_tlv_buffer(void) 153 | { 154 | tlv_length = 0; 155 | } 156 | 157 | int libemv_parse_tlv(unsigned char* inBuffer, int inBufferSize, unsigned short* outTag, unsigned char** outBuffer, int* outSize) 158 | { 159 | unsigned char* buf; 160 | int bufSize; 161 | buf = inBuffer; 162 | bufSize = inBufferSize; 163 | 164 | // 1 byte tag 165 | if (bufSize <= 0) 166 | return 0; 167 | *outTag = *buf; 168 | if ((*buf & 0x1F) == 0x1F) 169 | { 170 | // 2 byte tag 171 | buf++; 172 | bufSize--; 173 | if (bufSize <= 0) 174 | return 0; 175 | 176 | // Check "Another byte follows" 177 | if (*buf & 0x80) 178 | return 0; 179 | *outTag <<= 8; 180 | *outTag |= *buf; 181 | } 182 | buf++; 183 | bufSize--; 184 | 185 | // 1 byte length 186 | if (bufSize <= 0) 187 | return 0; 188 | if (*buf & 0x80) 189 | { 190 | int nBytes = *buf & 0x7F; 191 | // Next bytes length 192 | *outSize = 0; 193 | while (nBytes--) 194 | { 195 | buf++; 196 | bufSize--; 197 | if (bufSize <= 0) 198 | return 0; 199 | *outSize <<= 8; 200 | *outSize |= *buf; 201 | } 202 | } else 203 | { 204 | *outSize = *buf; 205 | } 206 | buf++; 207 | bufSize--; 208 | 209 | // Check size more than input size or max size 210 | if (inBufferSize < *outSize + (buf - inBuffer)) 211 | return 0; 212 | 213 | // Point data and return 214 | *outBuffer = buf; 215 | return *outSize + (buf - inBuffer); 216 | } 217 | 218 | int libemv_make_tlv(unsigned char* inBuffer, int inBufferSize, unsigned short tag, unsigned char* tlvBuffer) 219 | { 220 | int tlvSize; 221 | tlvSize = 0; 222 | if ((tag & 0x1F00) == 0x1F00) 223 | { 224 | // 2 byte tag 225 | tlvBuffer[tlvSize++] = (tag >> 8) & 0xFF; 226 | tlvBuffer[tlvSize++] = tag & 0xFF; 227 | } else 228 | { 229 | // 1 byte tag 230 | tlvBuffer[tlvSize++] = tag & 0xFF; 231 | } 232 | 233 | if (inBufferSize > 0x7F) 234 | { 235 | // n byte length 236 | int n; 237 | if (inBufferSize < 0x100) 238 | n = 1; 239 | else if (inBufferSize < 0x10000) 240 | n = 2; 241 | else if (inBufferSize < 0x1000000) 242 | n = 3; 243 | else 244 | n = 4; 245 | n |= 0x80; 246 | tlvBuffer[tlvSize++] = n & 0xFF; 247 | while (n--) 248 | { 249 | tlvBuffer[tlvSize++] = (inBufferSize >> (n * 8)) & 0xFF; 250 | } 251 | } else 252 | { 253 | // 1 byte length 254 | tlvBuffer[tlvSize++] = inBufferSize & 0x7F; 255 | } 256 | 257 | // Copy data 258 | memcpy(tlvBuffer + tlvSize, inBuffer, inBufferSize); 259 | tlvSize += inBufferSize; 260 | 261 | return tlvSize; 262 | } 263 | 264 | int libemv_dol(unsigned char* dol, int dolSize, unsigned char* outBuffer) 265 | { 266 | int outSize; 267 | int dolShift; 268 | outSize = 0; 269 | dolShift = 0; 270 | while (dolShift < dolSize) 271 | { 272 | unsigned short tag; 273 | int size; 274 | unsigned char* findData; 275 | int findSize; 276 | int sizeToCopy; 277 | 278 | // Tag could be 1 or 2 byte 279 | tag = dol[dolShift]; 280 | if ((dol[dolShift] & 0x1F) == 0x1F) 281 | { 282 | dolShift++; 283 | if (dolShift >= dolSize) 284 | break; 285 | tag <<= 8; 286 | tag |= dol[dolShift]; 287 | } 288 | dolShift++; 289 | if (dolShift >= dolSize) 290 | break; 291 | 292 | // Length could be only 1 byte 293 | size = dol[dolShift]; 294 | dolShift++; 295 | 296 | // Copy data 297 | findData = libemv_get_tag(tag, &findSize); 298 | if (!findData) 299 | findSize = 0; 300 | sizeToCopy = findSize < size ? findSize : size; 301 | if (findData) 302 | { 303 | memcpy(outBuffer + outSize, findData, sizeToCopy); 304 | outSize += sizeToCopy; 305 | } 306 | if (size > findSize) 307 | { 308 | memset(outBuffer + outSize, 0, size - findSize); 309 | outSize += size - findSize; 310 | } 311 | } 312 | 313 | return outSize; 314 | } 315 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "include/libemv.h" 6 | 7 | SCARDHANDLE hCardHandle; 8 | 9 | extern "C" char f_apdu(unsigned char cla, unsigned char ins, unsigned char p1, unsigned char p2, 10 | unsigned char dataSize, const unsigned char* data, 11 | int* outDataSize, unsigned char* outData) 12 | { 13 | BYTE pbRecv[256] = {0}; 14 | DWORD dwRecv = 256; 15 | BYTE pbSend[256] = {cla, ins, p1, p2, dataSize}; 16 | memcpy(pbSend + 5, data, dataSize); 17 | DWORD dwSend = 5 + dataSize; 18 | LONG lReturn = SCardTransmit(hCardHandle, 19 | SCARD_PCI_T0, 20 | pbSend, 21 | dwSend, 22 | NULL, 23 | pbRecv, 24 | &dwRecv ); 25 | if ( SCARD_S_SUCCESS != lReturn ) 26 | { 27 | printf("Failed SCardTransmit\n"); 28 | return 0; 29 | } 30 | if (dwRecv >= 2 && pbRecv[0] == 0x6C) 31 | { 32 | BYTE pbSend2[256] = {cla, ins, p1, p2, pbRecv[1]}; 33 | DWORD dwSend = 5; 34 | dwRecv = 256; 35 | LONG lReturn = SCardTransmit(hCardHandle, 36 | SCARD_PCI_T0, 37 | pbSend2, 38 | dwSend, 39 | NULL, 40 | pbRecv, 41 | &dwRecv ); 42 | if ( SCARD_S_SUCCESS != lReturn ) 43 | { 44 | printf("Failed SCardTransmit\n"); 45 | return 0; 46 | } 47 | } 48 | if (dwRecv >= 2 && pbRecv[0] == 0x61) 49 | { 50 | BYTE pbSend2[256] = {0x00, 0xC0, 0x00, 0x00, pbRecv[1]}; 51 | DWORD dwSend = 5; 52 | dwRecv = 256; 53 | LONG lReturn = SCardTransmit(hCardHandle, 54 | SCARD_PCI_T0, 55 | pbSend2, 56 | dwSend, 57 | NULL, 58 | pbRecv, 59 | &dwRecv ); 60 | if ( SCARD_S_SUCCESS != lReturn ) 61 | { 62 | printf("Failed SCardTransmit\n"); 63 | return 0; 64 | } 65 | } 66 | memcpy(outData, pbRecv, dwRecv); 67 | *outDataSize = dwRecv; 68 | return 1; 69 | } 70 | 71 | int main(int argc, char **argv) 72 | { 73 | SCARDCONTEXT hSC; 74 | LONG lReturn; 75 | // Establish the context. 76 | lReturn = SCardEstablishContext(SCARD_SCOPE_USER, 77 | NULL, 78 | NULL, 79 | &hSC); 80 | if ( SCARD_S_SUCCESS != lReturn ) 81 | { 82 | printf("Failed SCardEstablishContext\n"); 83 | return 1; 84 | } 85 | 86 | LPTSTR pmszReaders = NULL; 87 | DWORD cch = SCARD_AUTOALLOCATE; 88 | 89 | lReturn = SCardListReaders(hSC, 90 | NULL, 91 | (LPTSTR)&pmszReaders, 92 | &cch ); 93 | 94 | if (lReturn != SCARD_S_SUCCESS || *pmszReaders == '\0') 95 | { 96 | printf("No readers\n"); 97 | return 1; 98 | } 99 | 100 | DWORD dwAP; 101 | lReturn = SCardConnect( hSC, 102 | (LPCTSTR)pmszReaders, 103 | SCARD_SHARE_SHARED, 104 | SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, 105 | &hCardHandle, 106 | &dwAP ); 107 | SCardFreeMemory( hSC, pmszReaders ); 108 | if ( SCARD_S_SUCCESS != lReturn ) 109 | { 110 | lReturn = SCardReconnect(hCardHandle, 111 | SCARD_SHARE_SHARED, 112 | SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, 113 | SCARD_LEAVE_CARD, 114 | &dwAP ); 115 | if ( SCARD_S_SUCCESS != lReturn ) 116 | { 117 | printf("Failed SCardReconnect\n"); 118 | return 1; 119 | } 120 | } 121 | 122 | // Use the connection. 123 | // Display the active protocol. 124 | switch ( dwAP ) 125 | { 126 | case SCARD_PROTOCOL_T0: 127 | printf("Active protocol T0\n"); 128 | break; 129 | 130 | case SCARD_PROTOCOL_T1: 131 | printf("Active protocol T1\n"); 132 | break; 133 | 134 | case SCARD_PROTOCOL_UNDEFINED: 135 | default: 136 | printf("Active protocol unnegotiated or unknown\n"); 137 | break; 138 | } 139 | 140 | TCHAR szReader[200]; 141 | cch = 200; 142 | BYTE bAttr[32]; 143 | DWORD cByte = 32; 144 | DWORD dwState, dwProtocol; 145 | 146 | // Determine the status. 147 | // hCardHandle was set by an earlier call to SCardConnect. 148 | lReturn = SCardStatus(hCardHandle, 149 | szReader, 150 | &cch, 151 | &dwState, 152 | &dwProtocol, 153 | (LPBYTE)&bAttr, 154 | &cByte); 155 | 156 | if ( SCARD_S_SUCCESS != lReturn ) 157 | { 158 | printf("Failed SCardStatus\n"); 159 | return 1; 160 | } 161 | 162 | // Examine retrieved status elements. 163 | // Look at the reader name and card state. 164 | printf("%S\n", szReader ); 165 | switch ( dwState ) 166 | { 167 | case SCARD_ABSENT: 168 | printf("Card absent.\n"); 169 | break; 170 | case SCARD_PRESENT: 171 | printf("Card present.\n"); 172 | break; 173 | case SCARD_SWALLOWED: 174 | printf("Card swallowed.\n"); 175 | break; 176 | case SCARD_POWERED: 177 | printf("Card has power.\n"); 178 | break; 179 | case SCARD_NEGOTIABLE: 180 | printf("Card reset and waiting PTS negotiation.\n"); 181 | break; 182 | case SCARD_SPECIFIC: 183 | printf("Card has specific communication protocols set.\n"); 184 | break; 185 | default: 186 | printf("Unknown or unexpected card state.\n"); 187 | break; 188 | } 189 | 190 | srand((unsigned int) time(NULL)); 191 | libemv_init(); 192 | 193 | libemv_set_debug_enabled(1); 194 | set_function_apdu(f_apdu); 195 | 196 | // Global settings 197 | LIBEMV_GLOBAL globalSettings = {"12345678", {0x08, 0x40}, {0xC1, 0x00, 0xF0, 0xA0, 0x01}, {0xE0, 0xF8, 0xE8}, 0x22}; 198 | libemv_set_global_settings(&globalSettings); 199 | 200 | LIBEMV_APPLICATIONS visa; 201 | memset(&visa, 0, sizeof(visa)); 202 | memcpy(visa.RID, "\xA0\x00\x00\x00\x03", 5); 203 | 204 | LIBEMV_AID visa1010 = {7, {0xA0, 0x00, 0x00, 0x00, 0x03, 0x10, 0x10}, 1}; 205 | LIBEMV_AID visa2010 = {7, {0xA0, 0x00, 0x00, 0x00, 0x03, 0x20, 0x10}, 1}; 206 | LIBEMV_AID visa2020 = {7, {0xA0, 0x00, 0x00, 0x00, 0x03, 0x20, 0x20}, 1}; 207 | LIBEMV_AID visa8010 = {7, {0xA0, 0x00, 0x00, 0x00, 0x03, 0x80, 0x10}, 1}; 208 | visa.aidsCount = 4; 209 | visa.aids[0] = visa1010; 210 | visa.aids[1] = visa2010; 211 | visa.aids[2] = visa2020; 212 | visa.aids[3] = visa8010; 213 | 214 | set_applications_data(&visa, 1); 215 | 216 | if (libemv_is_emv_ATR(bAttr, cByte)) 217 | printf("ATR ok.\n"); 218 | else 219 | printf("ATR wrong.\n"); 220 | 221 | int resultBuildCand = libemv_build_candidate_list(); 222 | if (resultBuildCand != LIBEMV_OK) 223 | return 0; 224 | 225 | while (1) 226 | { 227 | int resultSelectApplication = libemv_application_selection(); 228 | if (resultSelectApplication < 0) 229 | return 0; 230 | 231 | if (resultSelectApplication == LIBEMV_NEED_CONFIRM_APPLICATION) 232 | { 233 | printf("Confirm select app %s (y/n): ", libemv_get_candidate(0)->strApplicationLabel); 234 | if (getchar() != 'y') 235 | return 0; 236 | if (libemv_select_application(0) != LIBEMV_OK) 237 | continue; 238 | } 239 | 240 | if (resultSelectApplication == LIBEMV_NEED_SELECT_APPLICATION) 241 | { 242 | printf("Select application from list:\n"); 243 | for (int idx = 0; idx < libemv_count_candidates(); idx++) 244 | { 245 | printf("%d (priority %d) - %s\n", idx, libemv_get_candidate(idx)->priority, libemv_get_candidate(idx)->strApplicationLabel); 246 | } 247 | printf("Index: "); 248 | int indexSelect = getchar() - '0'; 249 | if (libemv_select_application(indexSelect) != LIBEMV_OK) 250 | continue; 251 | } 252 | 253 | // Application selected ok, get processing option 254 | int resultProcessingOption = libemv_get_processing_option(); 255 | if (resultProcessingOption != LIBEMV_OK) 256 | continue; 257 | 258 | break; 259 | } 260 | 261 | int resultReadApp = libemv_read_app_data(); 262 | if (resultReadApp != LIBEMV_OK) 263 | return 0; 264 | 265 | // Debug out buffer 266 | { 267 | int shift = 0; 268 | unsigned short tag; 269 | unsigned char* data; 270 | int length; 271 | printf("\nApp buffer:\n"); 272 | while ((shift = libemv_get_next_tag(shift, &tag, &data, &length)) != 0) 273 | { 274 | bool isAscii = true; 275 | printf("- %4X [%d]: {", tag, length); 276 | for (int idx = 0; idx < length; idx++) 277 | { 278 | printf("%02X, ", data[idx] & 0xFF); 279 | if (data[idx] < ' ' || data[idx] > 0x7E) 280 | isAscii = false; 281 | } 282 | printf("}\n"); 283 | if (isAscii) 284 | { 285 | char* strData = new char[length + 1]; 286 | strData[length] = 0; 287 | memcpy(strData, data, length); 288 | printf("ascii: %s\n", strData); 289 | delete[] strData; 290 | } 291 | } 292 | } 293 | 294 | return 0; 295 | } 296 | -------------------------------------------------------------------------------- /crypt/md5.c: -------------------------------------------------------------------------------- 1 | /* 2 | MD5.C - MD5 message-digest algorithm 3 | Copyright(C) 2002 by charry, charry@email.com.cn 4 | */ 5 | 6 | #include "global.h" 7 | #include "md5.h" 8 | 9 | /* Constants for MD5Transform routine. */ 10 | 11 | #define S11 7 12 | #define S12 12 13 | #define S13 17 14 | #define S14 22 15 | #define S21 5 16 | #define S22 9 17 | #define S23 14 18 | #define S24 20 19 | #define S31 4 20 | #define S32 11 21 | #define S33 16 22 | #define S34 23 23 | #define S41 6 24 | #define S42 10 25 | #define S43 15 26 | #define S44 21 27 | 28 | static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64])); 29 | static void Encode PROTO_LIST 30 | ((unsigned char *, UINT4 *, unsigned int)); 31 | static void Decode PROTO_LIST 32 | ((UINT4 *, unsigned char *, unsigned int)); 33 | static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int)); 34 | static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int)); 35 | 36 | static unsigned char PADDING[64] = { 37 | 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 40 | }; 41 | 42 | /* F, G, H and I are basic MD5 functions. */ 43 | #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) 44 | #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) 45 | #define H(x, y, z) ((x) ^ (y) ^ (z)) 46 | #define I(x, y, z) ((y) ^ ((x) | (~z))) 47 | 48 | /* ROTATE_LEFT rotates x left n bits. */ 49 | 50 | #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) 51 | 52 | /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. 53 | Rotation is separate from addition to prevent recomputation. 54 | */ 55 | 56 | #define FF(a, b, c, d, x, s, ac) { \ 57 | (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ 58 | (a) = ROTATE_LEFT ((a), (s)); \ 59 | (a) += (b); \ 60 | } 61 | #define GG(a, b, c, d, x, s, ac) { \ 62 | (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ 63 | (a) = ROTATE_LEFT ((a), (s)); \ 64 | (a) += (b); \ 65 | } 66 | #define HH(a, b, c, d, x, s, ac) { \ 67 | (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ 68 | (a) = ROTATE_LEFT ((a), (s)); \ 69 | (a) += (b); \ 70 | } 71 | #define II(a, b, c, d, x, s, ac) { \ 72 | (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ 73 | (a) = ROTATE_LEFT ((a), (s)); \ 74 | (a) += (b); \ 75 | } 76 | 77 | /* MD5 initialization. Begins an MD5 operation, writing a new context. */ 78 | 79 | void MD5Init (context) 80 | MD5_CTX *context; /* context */ 81 | { 82 | context->count[0] = context->count[1] = 0; 83 | 84 | /* Load magic initialization constants. */ 85 | 86 | context->state[0] = 0x67452301; 87 | context->state[1] = 0xefcdab89; 88 | context->state[2] = 0x98badcfe; 89 | context->state[3] = 0x10325476; 90 | } 91 | 92 | /* MD5 block update operation. Continues an MD5 message-digest 93 | operation, processing another message block, and updating the 94 | context. 95 | */ 96 | 97 | void MD5Update (context, input, inputLen) 98 | MD5_CTX *context; /* context */ 99 | unsigned char *input; /* input block */ 100 | unsigned int inputLen; /* length of input block */ 101 | { 102 | unsigned int i, index, partLen; 103 | 104 | /* Compute number of bytes mod 64 */ 105 | 106 | index = (unsigned int)((context->count[0] >> 3) & 0x3F); 107 | 108 | /* Update number of bits */ 109 | 110 | if ((context->count[0] += ((UINT4)inputLen << 3)) 111 | < ((UINT4)inputLen << 3)) 112 | context->count[1]++; 113 | context->count[1] += ((UINT4)inputLen >> 29); 114 | 115 | partLen = 64 - index; 116 | 117 | /* Transform as many times as possible. */ 118 | 119 | if (inputLen >= partLen) { 120 | MD5_memcpy 121 | ((POINTER)&context->buffer[index], (POINTER)input, partLen); 122 | MD5Transform (context->state, context->buffer); 123 | 124 | for (i = partLen; i + 63 < inputLen; i += 64) 125 | MD5Transform (context->state, &input[i]); 126 | 127 | index = 0; 128 | } 129 | else 130 | i = 0; 131 | 132 | /* Buffer remaining input */ 133 | 134 | MD5_memcpy 135 | ((POINTER)&context->buffer[index], (POINTER)&input[i], 136 | inputLen-i); 137 | } 138 | 139 | /* MD5 finalization. Ends an MD5 message-digest operation, writing the 140 | the message digest and zeroizing the context. 141 | */ 142 | 143 | void MD5Final (digest, context) 144 | unsigned char digest[16]; /* message digest */ 145 | MD5_CTX *context; /* context */ 146 | { 147 | unsigned char bits[8]; 148 | unsigned int index, padLen; 149 | 150 | /* Save number of bits */ 151 | 152 | Encode (bits, context->count, 8); 153 | 154 | /* Pad out to 56 mod 64. */ 155 | 156 | index = (unsigned int)((context->count[0] >> 3) & 0x3f); 157 | padLen = (index < 56) ? (56 - index) : (120 - index); 158 | MD5Update (context, PADDING, padLen); 159 | 160 | /* Append length (before padding) */ 161 | 162 | MD5Update (context, bits, 8); 163 | 164 | /* Store state in digest */ 165 | 166 | Encode (digest, context->state, 16); 167 | 168 | /* Zeroize sensitive information. */ 169 | 170 | MD5_memset ((POINTER)context, 0, sizeof (*context)); 171 | } 172 | 173 | /* MD5 basic transformation. Transforms state based on block. */ 174 | 175 | static void MD5Transform (state, block) 176 | UINT4 state[4]; 177 | unsigned char block[64]; 178 | { 179 | UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; 180 | 181 | Decode (x, block, 64); 182 | 183 | /* Round 1 */ 184 | 185 | FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ 186 | FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ 187 | FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ 188 | FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ 189 | FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ 190 | FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ 191 | FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ 192 | FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ 193 | FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ 194 | FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ 195 | FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ 196 | FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ 197 | FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ 198 | FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ 199 | FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ 200 | FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ 201 | 202 | /* Round 2 */ 203 | 204 | GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ 205 | GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ 206 | GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ 207 | GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ 208 | GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ 209 | GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ 210 | GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ 211 | GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ 212 | GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ 213 | GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ 214 | GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ 215 | GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ 216 | GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ 217 | GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ 218 | GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ 219 | GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ 220 | 221 | /* Round 3 */ 222 | 223 | HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ 224 | HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ 225 | HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ 226 | HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ 227 | HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ 228 | HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ 229 | HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ 230 | HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ 231 | HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ 232 | HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ 233 | HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ 234 | HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ 235 | HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ 236 | HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ 237 | HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ 238 | HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ 239 | 240 | /* Round 4 */ 241 | 242 | II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ 243 | II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ 244 | II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ 245 | II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ 246 | II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ 247 | II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ 248 | II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ 249 | II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ 250 | II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ 251 | II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ 252 | II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ 253 | II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ 254 | II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ 255 | II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ 256 | II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ 257 | II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ 258 | 259 | state[0] += a; 260 | state[1] += b; 261 | state[2] += c; 262 | state[3] += d; 263 | 264 | /* Zeroize sensitive information. 265 | */ 266 | 267 | MD5_memset ((POINTER)x, 0, sizeof (x)); 268 | } 269 | 270 | /* Encodes input (UINT4) into output (unsigned char). Assumes len is 271 | a multiple of 4. 272 | */ 273 | 274 | static void Encode (output, input, len) 275 | unsigned char *output; 276 | UINT4 *input; 277 | unsigned int len; 278 | { 279 | unsigned int i, j; 280 | 281 | for (i = 0, j = 0; j < len; i++, j += 4) { 282 | output[j] = (unsigned char)(input[i] & 0xff); 283 | output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); 284 | output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); 285 | output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); 286 | } 287 | } 288 | 289 | /* Decodes input (unsigned char) into output (UINT4). Assumes len is 290 | a multiple of 4. 291 | */ 292 | 293 | static void Decode (output, input, len) 294 | UINT4 *output; 295 | unsigned char *input; 296 | unsigned int len; 297 | { 298 | unsigned int i, j; 299 | 300 | for (i = 0, j = 0; j < len; i++, j += 4) 301 | output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | 302 | (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); 303 | } 304 | 305 | /* Note: Replace "for loop" with standard memcpy if possible. */ 306 | 307 | static void MD5_memcpy (output, input, len) 308 | POINTER output; 309 | POINTER input; 310 | unsigned int len; 311 | { 312 | unsigned int i; 313 | 314 | for (i = 0; i < len; i++) 315 | output[i] = input[i]; 316 | } 317 | 318 | /* Note: Replace "for loop" with standard memset if possible. */ 319 | 320 | static void MD5_memset (output, value, len) 321 | POINTER output; 322 | int value; 323 | unsigned int len; 324 | { 325 | unsigned int i; 326 | 327 | for (i = 0; i < len; i++) 328 | ((char *)output)[i] = (char)value; 329 | } 330 | -------------------------------------------------------------------------------- /crypt/prime.c: -------------------------------------------------------------------------------- 1 | # /* 2 | # PRIME.C - primality-testing routines 3 | Copyright(C) 2002 by charry, charry@email.com.cn 4 | RSAEURO - RSA Library compatible with RSAREF(tm) 2.0. 5 | 6 | Uses a small primes factor test and the Fermat Test to determine if 7 | the number is probable prime number. 8 | */ 9 | 10 | #include "rsaeuro.h" 11 | #include "r_random.h" 12 | #include "nn.h" 13 | #include "prime.h" 14 | 15 | #define SMALL_PRIME_COUNT 1027 16 | 17 | static int probableprime PROTO_LIST ((NN_DIGIT *, unsigned int)); 18 | 19 | /* Generates a probable prime a between b and c such that a-1 is 20 | divisible by d. 21 | 22 | Assumes b < c, digits < MAX_NN_DIGITS. 23 | Returns RE_NEED_RANDOM if randomStruct not seeded, RE_DATA if 24 | unsuccessful. 25 | */ 26 | 27 | int GeneratePrime(a, b, c, d, digits, randomStruct) 28 | NN_DIGIT *a, *b, *c, *d; 29 | unsigned int digits; 30 | R_RANDOM_STRUCT *randomStruct; /* random structure */ 31 | { 32 | int status; 33 | unsigned char block[MAX_NN_DIGITS * NN_DIGIT_LEN]; 34 | NN_DIGIT t[MAX_NN_DIGITS], u[MAX_NN_DIGITS]; 35 | 36 | /* Generate random number between b and c. */ 37 | 38 | status = R_GenerateBytes(block, digits * NN_DIGIT_LEN, randomStruct); 39 | if(status) 40 | return(status); 41 | 42 | NN_Decode(a, digits, block, digits * NN_DIGIT_LEN); 43 | NN_Sub(t, c, b, digits); 44 | NN_ASSIGN_DIGIT(u, 1, digits); 45 | NN_Add(t, t, u, digits); 46 | NN_Mod(a, a, digits, t, digits); 47 | NN_Add(a, a, b, digits); 48 | 49 | /* Adjust so that a-1 is divisible by d. */ 50 | 51 | NN_Mod(t, a, digits, d, digits); 52 | NN_Sub(a, a, t, digits); 53 | NN_Add(a, a, u, digits); 54 | if(NN_Cmp(a, b, digits) < 0) 55 | NN_Add(a, a, d, digits); 56 | if(NN_Cmp(a, c, digits) > 0) 57 | NN_Sub(a, a, d, digits); 58 | 59 | /* Search to c in steps of d. */ 60 | 61 | NN_Assign(t, c, digits); 62 | NN_Sub(t, t, d, digits); 63 | 64 | while(!probableprime (a, digits)) { 65 | if(NN_Cmp (a, t, digits) > 0) 66 | return(RE_DATA); 67 | NN_Add(a, a, d, digits); 68 | } 69 | 70 | return(ID_OK); 71 | } 72 | 73 | /* Returns nonzero iff a is a probable prime. 74 | 75 | Does small factor test and a fermat test witness 2. 76 | */ 77 | 78 | static int probableprime(a, aDigits) 79 | NN_DIGIT *a; 80 | unsigned int aDigits; 81 | { 82 | 83 | int status; 84 | NN_DIGIT t[MAX_NN_DIGITS], u[MAX_NN_DIGITS]; 85 | 86 | /* This table can be reduced in size but the smaller 87 | the table the slower the testing. 88 | */ 89 | 90 | static unsigned int SMALL_PRIMES[] = { 91 | 3, 5, 7, 11, 13, 17, 19, 92 | 23, 29, 31, 37, 41, 43, 47, 53, 93 | 59, 61, 67, 71, 73, 79, 83, 89, 94 | 97, 101, 103, 107, 109, 113, 127, 131, 95 | 137, 139, 149, 151, 157, 163, 167, 173, 96 | 179, 181, 191, 193, 197, 199, 211, 223, 97 | 227, 229, 233, 239, 241, 251, 257, 263, 98 | 269, 271, 277, 281, 283, 293, 307, 311, 99 | 313, 317, 331, 337, 347, 349, 353, 359, 100 | 367, 373, 379, 383, 389, 397, 401, 409, 101 | 419, 421, 431, 433, 439, 443, 449, 457, 102 | 461, 463, 467, 479, 487, 491, 499, 503, 103 | 509, 521, 523, 541, 547, 557, 563, 569, 104 | 571, 577, 587, 593, 599, 601, 607, 613, 105 | 617, 619, 631, 641, 643, 647, 653, 659, 106 | 661, 673, 677, 683, 691, 701, 709, 719, 107 | 727, 733, 739, 743, 751, 757, 761, 769, 108 | 773, 787, 797, 809, 811, 821, 823, 827, 109 | 829, 839, 853, 857, 859, 863, 877, 881, 110 | 883, 887, 907, 911, 919, 929, 937, 941, 111 | 947, 953, 967, 971, 977, 983, 991, 997, 112 | 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 113 | 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 114 | 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 115 | 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 116 | 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 117 | 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 118 | 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 119 | 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 120 | 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 121 | 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 122 | 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, 123 | 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 124 | 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 125 | 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 126 | 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 127 | 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 128 | 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003, 129 | 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, 130 | 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, 131 | 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 132 | 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, 133 | 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, 134 | 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, 135 | 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 136 | 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 137 | 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, 138 | 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, 139 | 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, 140 | 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, 141 | 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 142 | 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 143 | 2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939, 144 | 2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011, 145 | 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, 146 | 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 147 | 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, 148 | 3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301, 149 | 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, 150 | 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, 151 | 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 152 | 3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541, 153 | 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 154 | 3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671, 155 | 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, 156 | 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, 157 | 3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863, 158 | 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923, 159 | 3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003, 160 | 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, 161 | 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, 162 | 4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211, 163 | 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, 164 | 4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337, 165 | 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, 166 | 4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481, 167 | 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547, 168 | 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, 169 | 4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673, 170 | 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, 171 | 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 172 | 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909, 173 | 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967, 174 | 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, 175 | 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 176 | 5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167, 177 | 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233, 178 | 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309, 179 | 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399, 180 | 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, 181 | 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, 182 | 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, 183 | 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653, 184 | 5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711, 185 | 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, 186 | 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 187 | 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897, 188 | 5903, 5923, 5927, 5939, 5953, 5981, 5987, 6007, 189 | 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, 190 | 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, 191 | 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, 192 | 6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271, 193 | 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, 194 | 6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379, 195 | 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, 196 | 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, 197 | 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, 198 | 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701, 199 | 6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779, 200 | 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, 201 | 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, 202 | 6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971, 203 | 6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027, 204 | 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, 205 | 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, 206 | 7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, 207 | 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, 208 | 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, 209 | 7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517, 210 | 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, 211 | 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, 212 | 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, 213 | 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, 214 | 7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853, 215 | 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, 216 | 7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009, 217 | 8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087, 218 | 8089, 8093, 8101, 8111, 8117, 8123, 8147, 8161, 219 | 8167, 8171, 8179, 8191, 0 220 | }; 221 | 222 | unsigned int i; 223 | 224 | status = 1; 225 | 226 | NN_AssignZero(t, aDigits); 227 | 228 | /* Small Primes test, weed out junk numbers before slower Fermat's */ 229 | 230 | for(i = 0; *(SMALL_PRIMES+i); i++) { 231 | *t = *(SMALL_PRIMES+i); 232 | if(aDigits == 1) 233 | if(NN_Cmp (a, t, 1) == 0) 234 | break; 235 | NN_Mod(t, a, aDigits, t, 1); 236 | if(NN_Zero (t, 1)) { 237 | status = 0; 238 | break; 239 | } 240 | } 241 | 242 | /* Clear sensitive information. */ 243 | 244 | i = 0; 245 | R_memset((POINTER)t, 0, sizeof(t)); 246 | 247 | /* Fermat's test for witness 2. 248 | (All primes pass the test, and nearly all composites fail.) 249 | */ 250 | 251 | if(status) { 252 | NN_ASSIGN_DIGIT(t, 2, aDigits); 253 | NN_ModExp(u, t, a, aDigits, a, aDigits); 254 | 255 | status = NN_EQUAL(t, u, aDigits); 256 | 257 | /* Clear sensitive information. */ 258 | 259 | R_memset((POINTER)u, 0, sizeof(u)); 260 | } 261 | 262 | return(status ? TRUE : FALSE); 263 | } 264 | -------------------------------------------------------------------------------- /crypt/sha1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * sha1.c 3 | * 4 | * Copyright (C) 1998, 2009 5 | * Paul E. Jones 6 | * All Rights Reserved 7 | * 8 | ***************************************************************************** 9 | * $Id: sha1.c 12 2009-06-22 19:34:25Z paulej $ 10 | ***************************************************************************** 11 | * 12 | * Description: 13 | * This file implements the Secure Hashing Standard as defined 14 | * in FIPS PUB 180-1 published April 17, 1995. 15 | * 16 | * The Secure Hashing Standard, which uses the Secure Hashing 17 | * Algorithm (SHA), produces a 160-bit message digest for a 18 | * given data stream. In theory, it is highly improbable that 19 | * two messages will produce the same message digest. Therefore, 20 | * this algorithm can serve as a means of providing a "fingerprint" 21 | * for a message. 22 | * 23 | * Portability Issues: 24 | * SHA-1 is defined in terms of 32-bit "words". This code was 25 | * written with the expectation that the processor has at least 26 | * a 32-bit machine word size. If the machine word size is larger, 27 | * the code should still function properly. One caveat to that 28 | * is that the input functions taking characters and character 29 | * arrays assume that only 8 bits of information are stored in each 30 | * character. 31 | * 32 | * Caveats: 33 | * SHA-1 is designed to work with messages less than 2^64 bits 34 | * long. Although SHA-1 allows a message digest to be generated for 35 | * messages of any number of bits less than 2^64, this 36 | * implementation only works with messages with a length that is a 37 | * multiple of the size of an 8-bit character. 38 | * 39 | */ 40 | 41 | #include "sha1.h" 42 | 43 | /* 44 | * Define the circular shift macro 45 | */ 46 | #define SHA1CircularShift(bits,word) \ 47 | ((((word) << (bits)) & 0xFFFFFFFF) | \ 48 | ((word) >> (32-(bits)))) 49 | 50 | /* Function prototypes */ 51 | void SHA1ProcessMessageBlock(SHA1Context *); 52 | void SHA1PadMessage(SHA1Context *); 53 | 54 | /* 55 | * SHA1Reset 56 | * 57 | * Description: 58 | * This function will initialize the SHA1Context in preparation 59 | * for computing a new message digest. 60 | * 61 | * Parameters: 62 | * context: [in/out] 63 | * The context to reset. 64 | * 65 | * Returns: 66 | * Nothing. 67 | * 68 | * Comments: 69 | * 70 | */ 71 | void SHA1Reset(SHA1Context *context) 72 | { 73 | context->Length_Low = 0; 74 | context->Length_High = 0; 75 | context->Message_Block_Index = 0; 76 | 77 | context->Message_Digest[0] = 0x67452301; 78 | context->Message_Digest[1] = 0xEFCDAB89; 79 | context->Message_Digest[2] = 0x98BADCFE; 80 | context->Message_Digest[3] = 0x10325476; 81 | context->Message_Digest[4] = 0xC3D2E1F0; 82 | 83 | context->Computed = 0; 84 | context->Corrupted = 0; 85 | } 86 | 87 | /* 88 | * SHA1Result 89 | * 90 | * Description: 91 | * This function will return the 160-bit message digest into the 92 | * Message_Digest array within the SHA1Context provided 93 | * 94 | * Parameters: 95 | * context: [in/out] 96 | * The context to use to calculate the SHA-1 hash. 97 | * 98 | * Returns: 99 | * 1 if successful, 0 if it failed. 100 | * 101 | * Comments: 102 | * 103 | */ 104 | int SHA1Result(SHA1Context *context) 105 | { 106 | 107 | if (context->Corrupted) 108 | { 109 | return 0; 110 | } 111 | 112 | if (!context->Computed) 113 | { 114 | SHA1PadMessage(context); 115 | context->Computed = 1; 116 | } 117 | 118 | return 1; 119 | } 120 | 121 | /* 122 | * SHA1Input 123 | * 124 | * Description: 125 | * This function accepts an array of octets as the next portion of 126 | * the message. 127 | * 128 | * Parameters: 129 | * context: [in/out] 130 | * The SHA-1 context to update 131 | * message_array: [in] 132 | * An array of characters representing the next portion of the 133 | * message. 134 | * length: [in] 135 | * The length of the message in message_array 136 | * 137 | * Returns: 138 | * Nothing. 139 | * 140 | * Comments: 141 | * 142 | */ 143 | void SHA1Input( SHA1Context *context, 144 | const unsigned char *message_array, 145 | unsigned length) 146 | { 147 | if (!length) 148 | { 149 | return; 150 | } 151 | 152 | if (context->Computed || context->Corrupted) 153 | { 154 | context->Corrupted = 1; 155 | return; 156 | } 157 | 158 | while(length-- && !context->Corrupted) 159 | { 160 | context->Message_Block[context->Message_Block_Index++] = 161 | (*message_array & 0xFF); 162 | 163 | context->Length_Low += 8; 164 | /* Force it to 32 bits */ 165 | context->Length_Low &= 0xFFFFFFFF; 166 | if (context->Length_Low == 0) 167 | { 168 | context->Length_High++; 169 | /* Force it to 32 bits */ 170 | context->Length_High &= 0xFFFFFFFF; 171 | if (context->Length_High == 0) 172 | { 173 | /* Message is too long */ 174 | context->Corrupted = 1; 175 | } 176 | } 177 | 178 | if (context->Message_Block_Index == 64) 179 | { 180 | SHA1ProcessMessageBlock(context); 181 | } 182 | 183 | message_array++; 184 | } 185 | } 186 | 187 | /* 188 | * SHA1ProcessMessageBlock 189 | * 190 | * Description: 191 | * This function will process the next 512 bits of the message 192 | * stored in the Message_Block array. 193 | * 194 | * Parameters: 195 | * None. 196 | * 197 | * Returns: 198 | * Nothing. 199 | * 200 | * Comments: 201 | * Many of the variable names in the SHAContext, especially the 202 | * single character names, were used because those were the names 203 | * used in the publication. 204 | * 205 | * 206 | */ 207 | void SHA1ProcessMessageBlock(SHA1Context *context) 208 | { 209 | const unsigned K[] = /* Constants defined in SHA-1 */ 210 | { 211 | 0x5A827999, 212 | 0x6ED9EBA1, 213 | 0x8F1BBCDC, 214 | 0xCA62C1D6 215 | }; 216 | int t; /* Loop counter */ 217 | unsigned temp; /* Temporary word value */ 218 | unsigned W[80]; /* Word sequence */ 219 | unsigned A, B, C, D, E; /* Word buffers */ 220 | 221 | /* 222 | * Initialize the first 16 words in the array W 223 | */ 224 | for(t = 0; t < 16; t++) 225 | { 226 | W[t] = ((unsigned) context->Message_Block[t * 4]) << 24; 227 | W[t] |= ((unsigned) context->Message_Block[t * 4 + 1]) << 16; 228 | W[t] |= ((unsigned) context->Message_Block[t * 4 + 2]) << 8; 229 | W[t] |= ((unsigned) context->Message_Block[t * 4 + 3]); 230 | } 231 | 232 | for(t = 16; t < 80; t++) 233 | { 234 | W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); 235 | } 236 | 237 | A = context->Message_Digest[0]; 238 | B = context->Message_Digest[1]; 239 | C = context->Message_Digest[2]; 240 | D = context->Message_Digest[3]; 241 | E = context->Message_Digest[4]; 242 | 243 | for(t = 0; t < 20; t++) 244 | { 245 | temp = SHA1CircularShift(5,A) + 246 | ((B & C) | ((~B) & D)) + E + W[t] + K[0]; 247 | temp &= 0xFFFFFFFF; 248 | E = D; 249 | D = C; 250 | C = SHA1CircularShift(30,B); 251 | B = A; 252 | A = temp; 253 | } 254 | 255 | for(t = 20; t < 40; t++) 256 | { 257 | temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1]; 258 | temp &= 0xFFFFFFFF; 259 | E = D; 260 | D = C; 261 | C = SHA1CircularShift(30,B); 262 | B = A; 263 | A = temp; 264 | } 265 | 266 | for(t = 40; t < 60; t++) 267 | { 268 | temp = SHA1CircularShift(5,A) + 269 | ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]; 270 | temp &= 0xFFFFFFFF; 271 | E = D; 272 | D = C; 273 | C = SHA1CircularShift(30,B); 274 | B = A; 275 | A = temp; 276 | } 277 | 278 | for(t = 60; t < 80; t++) 279 | { 280 | temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3]; 281 | temp &= 0xFFFFFFFF; 282 | E = D; 283 | D = C; 284 | C = SHA1CircularShift(30,B); 285 | B = A; 286 | A = temp; 287 | } 288 | 289 | context->Message_Digest[0] = 290 | (context->Message_Digest[0] + A) & 0xFFFFFFFF; 291 | context->Message_Digest[1] = 292 | (context->Message_Digest[1] + B) & 0xFFFFFFFF; 293 | context->Message_Digest[2] = 294 | (context->Message_Digest[2] + C) & 0xFFFFFFFF; 295 | context->Message_Digest[3] = 296 | (context->Message_Digest[3] + D) & 0xFFFFFFFF; 297 | context->Message_Digest[4] = 298 | (context->Message_Digest[4] + E) & 0xFFFFFFFF; 299 | 300 | context->Message_Block_Index = 0; 301 | } 302 | 303 | /* 304 | * SHA1PadMessage 305 | * 306 | * Description: 307 | * According to the standard, the message must be padded to an even 308 | * 512 bits. The first padding bit must be a '1'. The last 64 309 | * bits represent the length of the original message. All bits in 310 | * between should be 0. This function will pad the message 311 | * according to those rules by filling the Message_Block array 312 | * accordingly. It will also call SHA1ProcessMessageBlock() 313 | * appropriately. When it returns, it can be assumed that the 314 | * message digest has been computed. 315 | * 316 | * Parameters: 317 | * context: [in/out] 318 | * The context to pad 319 | * 320 | * Returns: 321 | * Nothing. 322 | * 323 | * Comments: 324 | * 325 | */ 326 | void SHA1PadMessage(SHA1Context *context) 327 | { 328 | /* 329 | * Check to see if the current message block is too small to hold 330 | * the initial padding bits and length. If so, we will pad the 331 | * block, process it, and then continue padding into a second 332 | * block. 333 | */ 334 | if (context->Message_Block_Index > 55) 335 | { 336 | context->Message_Block[context->Message_Block_Index++] = 0x80; 337 | while(context->Message_Block_Index < 64) 338 | { 339 | context->Message_Block[context->Message_Block_Index++] = 0; 340 | } 341 | 342 | SHA1ProcessMessageBlock(context); 343 | 344 | while(context->Message_Block_Index < 56) 345 | { 346 | context->Message_Block[context->Message_Block_Index++] = 0; 347 | } 348 | } 349 | else 350 | { 351 | context->Message_Block[context->Message_Block_Index++] = 0x80; 352 | while(context->Message_Block_Index < 56) 353 | { 354 | context->Message_Block[context->Message_Block_Index++] = 0; 355 | } 356 | } 357 | 358 | /* 359 | * Store the message length as the last 8 octets 360 | */ 361 | context->Message_Block[56] = (context->Length_High >> 24) & 0xFF; 362 | context->Message_Block[57] = (context->Length_High >> 16) & 0xFF; 363 | context->Message_Block[58] = (context->Length_High >> 8) & 0xFF; 364 | context->Message_Block[59] = (context->Length_High) & 0xFF; 365 | context->Message_Block[60] = (context->Length_Low >> 24) & 0xFF; 366 | context->Message_Block[61] = (context->Length_Low >> 16) & 0xFF; 367 | context->Message_Block[62] = (context->Length_Low >> 8) & 0xFF; 368 | context->Message_Block[63] = (context->Length_Low) & 0xFF; 369 | 370 | SHA1ProcessMessageBlock(context); 371 | } 372 | -------------------------------------------------------------------------------- /crypt/rsa.c: -------------------------------------------------------------------------------- 1 | /* 2 | RSA.C - RSA routines for RSAEURO 3 | Copyright(C) 2002 by charry, charry@email.com.cn 4 | RSAEURO - RSA Library compatible with RSAREF(tm) 2.0. 5 | 6 | RSA encryption performed as defined in the PKCS (#1) by RSADSI. 7 | */ 8 | 9 | #include "rsaeuro.h" 10 | #include "r_random.h" 11 | #include "rsa.h" 12 | #include "nn.h" 13 | 14 | static int rsapublicfunc PROTO_LIST((unsigned char *, unsigned int *, unsigned char *, unsigned int, R_RSA_PUBLIC_KEY *)); 15 | static int rsaprivatefunc PROTO_LIST((unsigned char *, unsigned int *, unsigned char *, unsigned int, R_RSA_PRIVATE_KEY *)); 16 | 17 | /* RSA encryption, according to RSADSI's PKCS #1. */ 18 | 19 | int RSAPublicEncrypt(output, outputLen, input, inputLen, publicKey, randomStruct) 20 | unsigned char *output; /* output block */ 21 | unsigned int *outputLen; /* length of output block */ 22 | unsigned char *input; /* input block */ 23 | unsigned int inputLen; /* length of input block */ 24 | R_RSA_PUBLIC_KEY *publicKey; /* RSA public key */ 25 | R_RANDOM_STRUCT *randomStruct; /* random structure */ 26 | { 27 | int status; 28 | unsigned char byte, pkcsBlock[MAX_RSA_MODULUS_LEN]; 29 | unsigned int i, modulusLen; 30 | 31 | modulusLen = (publicKey->bits + 7) / 8; 32 | 33 | if(inputLen + 11 > modulusLen) 34 | return(RE_LEN); 35 | 36 | R_GetRandomBytesNeeded(&i, randomStruct); 37 | if(i != 0) 38 | return(RE_NEED_RANDOM); 39 | 40 | *pkcsBlock = 0; /* PKCS Block Makeup */ 41 | 42 | /* block type 2 */ 43 | 44 | *(pkcsBlock+1) = 2; 45 | 46 | for(i = 2; i < modulusLen - inputLen - 1; i++) { 47 | 48 | /* Find nonzero random byte. */ 49 | 50 | do { 51 | 52 | /* random bytes used to pad the PKCS Block */ 53 | 54 | R_GenerateBytes(&byte, 1, randomStruct); 55 | }while(byte == 0); 56 | *(pkcsBlock+i) = byte; 57 | } 58 | 59 | /* separator */ 60 | 61 | pkcsBlock[i++] = 0; 62 | 63 | R_memcpy((POINTER)&pkcsBlock[i], (POINTER)input, inputLen); 64 | 65 | status = rsapublicfunc(output, outputLen, pkcsBlock, modulusLen, publicKey); 66 | 67 | /* Clear sensitive information. */ 68 | 69 | byte = 0; 70 | R_memset((POINTER)pkcsBlock, 0, sizeof(pkcsBlock)); 71 | 72 | return(status); 73 | } 74 | 75 | /* RSA decryption, according to RSADSI's PKCS #1. */ 76 | 77 | int RSAPublicDecrypt(output, outputLen, input, inputLen, publicKey) 78 | unsigned char *output; /* output block */ 79 | unsigned int *outputLen; /* length of output block */ 80 | unsigned char *input; /* input block */ 81 | unsigned int inputLen; /* length of input block */ 82 | R_RSA_PUBLIC_KEY *publicKey; /* RSA public key */ 83 | { 84 | int status; 85 | unsigned char pkcsBlock[MAX_RSA_MODULUS_LEN]; 86 | unsigned int i, modulusLen, pkcsBlockLen; 87 | 88 | modulusLen = (publicKey->bits + 7) / 8; 89 | 90 | if(inputLen > modulusLen) 91 | return(RE_LEN); 92 | 93 | status = rsapublicfunc(pkcsBlock, &pkcsBlockLen, input, inputLen, publicKey); 94 | if(status) 95 | return(status); 96 | 97 | if(pkcsBlockLen != modulusLen) 98 | return(RE_LEN); 99 | 100 | /* Require block type 1. */ 101 | 102 | if((pkcsBlock[0] != 0) || (pkcsBlock[1] != 1)) 103 | return(RE_DATA); 104 | 105 | for(i = 2; i < modulusLen-1; i++) 106 | if(*(pkcsBlock+i) != 0xff) 107 | break; 108 | 109 | /* separator check */ 110 | 111 | if(pkcsBlock[i++] != 0) 112 | return(RE_DATA); 113 | 114 | *outputLen = modulusLen - i; 115 | 116 | if(*outputLen + 11 > modulusLen) 117 | return(RE_DATA); 118 | 119 | R_memcpy((POINTER)output, (POINTER)&pkcsBlock[i], *outputLen); 120 | 121 | /* Clear sensitive information. */ 122 | 123 | R_memset((POINTER)pkcsBlock, 0, sizeof(pkcsBlock)); 124 | 125 | return(ID_OK); 126 | } 127 | 128 | /* RSA encryption, according to RSADSI's PKCS #1. */ 129 | 130 | int RSAPrivateEncrypt(output, outputLen, input, inputLen, privateKey) 131 | unsigned char *output; /* output block */ 132 | unsigned int *outputLen; /* length of output block */ 133 | unsigned char *input; /* input block */ 134 | unsigned int inputLen; /* length of input block */ 135 | R_RSA_PRIVATE_KEY *privateKey; /* RSA private key */ 136 | { 137 | int status; 138 | unsigned char pkcsBlock[MAX_RSA_MODULUS_LEN]; 139 | unsigned int i, modulusLen; 140 | 141 | modulusLen = (privateKey->bits + 7) / 8; 142 | 143 | if(inputLen + 11 > modulusLen) 144 | return (RE_LEN); 145 | 146 | *pkcsBlock = 0; 147 | 148 | /* block type 1 */ 149 | 150 | *(pkcsBlock+1) = 1; 151 | 152 | for (i = 2; i < modulusLen - inputLen - 1; i++) 153 | *(pkcsBlock+i) = 0xff; 154 | 155 | /* separator */ 156 | 157 | pkcsBlock[i++] = 0; 158 | 159 | R_memcpy((POINTER)&pkcsBlock[i], (POINTER)input, inputLen); 160 | 161 | status = rsaprivatefunc(output, outputLen, pkcsBlock, modulusLen, privateKey); 162 | 163 | /* Clear sensitive information. */ 164 | 165 | R_memset((POINTER)pkcsBlock, 0, sizeof(pkcsBlock)); 166 | 167 | return(status); 168 | } 169 | 170 | /* RSA decryption, according to RSADSI's PKCS #1. */ 171 | 172 | int RSAPrivateDecrypt(output, outputLen, input, inputLen, privateKey) 173 | unsigned char *output; /* output block */ 174 | unsigned int *outputLen; /* length of output block */ 175 | unsigned char *input; /* input block */ 176 | unsigned int inputLen; /* length of input block */ 177 | R_RSA_PRIVATE_KEY *privateKey; /* RSA private key */ 178 | { 179 | int status; 180 | unsigned char pkcsBlock[MAX_RSA_MODULUS_LEN]; 181 | unsigned int i, modulusLen, pkcsBlockLen; 182 | 183 | modulusLen = (privateKey->bits + 7) / 8; 184 | 185 | if(inputLen > modulusLen) 186 | return (RE_LEN); 187 | 188 | status = rsaprivatefunc(pkcsBlock, &pkcsBlockLen, input, inputLen, privateKey); 189 | if(status) 190 | return (status); 191 | 192 | if(pkcsBlockLen != modulusLen) 193 | return (RE_LEN); 194 | 195 | /* We require block type 2. */ 196 | 197 | if((*pkcsBlock != 0) || (*(pkcsBlock+1) != 2)) 198 | return (RE_DATA); 199 | 200 | for(i = 2; i < modulusLen-1; i++) 201 | 202 | /* separator */ 203 | 204 | if (*(pkcsBlock+i) == 0) 205 | break; 206 | 207 | i++; 208 | if(i >= modulusLen) 209 | return(RE_DATA); 210 | 211 | *outputLen = modulusLen - i; 212 | 213 | if(*outputLen + 11 > modulusLen) 214 | return(RE_DATA); 215 | 216 | R_memcpy((POINTER)output, (POINTER)&pkcsBlock[i], *outputLen); 217 | 218 | /* Clear sensitive information. */ 219 | 220 | R_memset((POINTER)pkcsBlock, 0, sizeof(pkcsBlock)); 221 | 222 | return(ID_OK); 223 | } 224 | 225 | /* Raw RSA public-key operation. Output has same length as modulus. 226 | 227 | Requires input < modulus. 228 | */ 229 | 230 | static int rsapublicfunc(output, outputLen, input, inputLen, publicKey) 231 | unsigned char *output; /* output block */ 232 | unsigned int *outputLen; /* length of output block */ 233 | unsigned char *input; /* input block */ 234 | unsigned int inputLen; /* length of input block */ 235 | R_RSA_PUBLIC_KEY *publicKey; /* RSA public key */ 236 | { 237 | NN_DIGIT c[MAX_NN_DIGITS], e[MAX_NN_DIGITS], m[MAX_NN_DIGITS], 238 | n[MAX_NN_DIGITS]; 239 | unsigned int eDigits, nDigits; 240 | 241 | 242 | /* decode the required RSA function input data */ 243 | 244 | NN_Decode(m, MAX_NN_DIGITS, input, inputLen); 245 | NN_Decode(n, MAX_NN_DIGITS, publicKey->modulus, MAX_RSA_MODULUS_LEN); 246 | NN_Decode(e, MAX_NN_DIGITS, publicKey->exponent, MAX_RSA_MODULUS_LEN); 247 | 248 | nDigits = NN_Digits(n, MAX_NN_DIGITS); 249 | eDigits = NN_Digits(e, MAX_NN_DIGITS); 250 | 251 | if(NN_Cmp(m, n, nDigits) >= 0) 252 | return(RE_DATA); 253 | 254 | *outputLen = (publicKey->bits + 7) / 8; 255 | 256 | /* Compute c = m^e mod n. To perform actual RSA calc. */ 257 | 258 | NN_ModExp (c, m, e, eDigits, n, nDigits); 259 | 260 | /* encode output to standard form */ 261 | 262 | NN_Encode (output, *outputLen, c, nDigits); 263 | 264 | /* Clear sensitive information. */ 265 | 266 | R_memset((POINTER)c, 0, sizeof(c)); 267 | R_memset((POINTER)m, 0, sizeof(m)); 268 | 269 | return(ID_OK); 270 | } 271 | 272 | /* Raw RSA private-key operation. Output has same length as modulus. 273 | 274 | Requires input < modulus. 275 | */ 276 | 277 | static int rsaprivatefunc(output, outputLen, input, inputLen, privateKey) 278 | unsigned char *output; /* output block */ 279 | unsigned int *outputLen; /* length of output block */ 280 | unsigned char *input; /* input block */ 281 | unsigned int inputLen; /* length of input block */ 282 | R_RSA_PRIVATE_KEY *privateKey; /* RSA private key */ 283 | { 284 | NN_DIGIT c[MAX_NN_DIGITS], cP[MAX_NN_DIGITS], cQ[MAX_NN_DIGITS], 285 | dP[MAX_NN_DIGITS], dQ[MAX_NN_DIGITS], mP[MAX_NN_DIGITS], 286 | mQ[MAX_NN_DIGITS], n[MAX_NN_DIGITS], p[MAX_NN_DIGITS], q[MAX_NN_DIGITS], 287 | qInv[MAX_NN_DIGITS], t[MAX_NN_DIGITS]; 288 | unsigned int cDigits, nDigits, pDigits; 289 | 290 | /* decode required input data from standard form */ 291 | 292 | NN_Decode(c, MAX_NN_DIGITS, input, inputLen); /* input */ 293 | 294 | /* private key data */ 295 | 296 | NN_Decode(p, MAX_NN_DIGITS, privateKey->prime[0], MAX_RSA_PRIME_LEN); 297 | NN_Decode(q, MAX_NN_DIGITS, privateKey->prime[1], MAX_RSA_PRIME_LEN); 298 | NN_Decode(dP, MAX_NN_DIGITS, privateKey->primeExponent[0], MAX_RSA_PRIME_LEN); 299 | NN_Decode(dQ, MAX_NN_DIGITS, privateKey->primeExponent[1], MAX_RSA_PRIME_LEN); 300 | NN_Decode(n, MAX_NN_DIGITS, privateKey->modulus, MAX_RSA_MODULUS_LEN); 301 | NN_Decode(qInv, MAX_NN_DIGITS, privateKey->coefficient, MAX_RSA_PRIME_LEN); 302 | 303 | /* work out lengths of input components */ 304 | 305 | cDigits = NN_Digits(c, MAX_NN_DIGITS); 306 | pDigits = NN_Digits(p, MAX_NN_DIGITS); 307 | nDigits = NN_Digits(n, MAX_NN_DIGITS); 308 | 309 | 310 | if(NN_Cmp(c, n, nDigits) >= 0) 311 | return(RE_DATA); 312 | 313 | *outputLen = (privateKey->bits + 7) / 8; 314 | 315 | /* Compute mP = cP^dP mod p and mQ = cQ^dQ mod q. (Assumes q has 316 | length at most pDigits, i.e., p > q.) 317 | */ 318 | 319 | NN_Mod(cP, c, cDigits, p, pDigits); 320 | NN_Mod(cQ, c, cDigits, q, pDigits); 321 | 322 | NN_AssignZero(mP, nDigits); 323 | NN_ModExp(mP, cP, dP, pDigits, p, pDigits); 324 | 325 | NN_AssignZero(mQ, nDigits); 326 | NN_ModExp(mQ, cQ, dQ, pDigits, q, pDigits); 327 | 328 | /* Chinese Remainder Theorem: 329 | m = ((((mP - mQ) mod p) * qInv) mod p) * q + mQ. 330 | */ 331 | 332 | if(NN_Cmp(mP, mQ, pDigits) >= 0) { 333 | NN_Sub(t, mP, mQ, pDigits); 334 | }else{ 335 | NN_Sub(t, mQ, mP, pDigits); 336 | NN_Sub(t, p, t, pDigits); 337 | } 338 | 339 | NN_ModMult(t, t, qInv, p, pDigits); 340 | NN_Mult(t, t, q, pDigits); 341 | NN_Add(t, t, mQ, nDigits); 342 | 343 | /* encode output to standard form */ 344 | 345 | NN_Encode (output, *outputLen, t, nDigits); 346 | 347 | /* Clear sensitive information. */ 348 | 349 | R_memset((POINTER)c, 0, sizeof(c)); 350 | R_memset((POINTER)cP, 0, sizeof(cP)); 351 | R_memset((POINTER)cQ, 0, sizeof(cQ)); 352 | R_memset((POINTER)dP, 0, sizeof(dP)); 353 | R_memset((POINTER)dQ, 0, sizeof(dQ)); 354 | R_memset((POINTER)mP, 0, sizeof(mP)); 355 | R_memset((POINTER)mQ, 0, sizeof(mQ)); 356 | R_memset((POINTER)p, 0, sizeof(p)); 357 | R_memset((POINTER)q, 0, sizeof(q)); 358 | R_memset((POINTER)qInv, 0, sizeof(qInv)); 359 | R_memset((POINTER)t, 0, sizeof(t)); 360 | return(ID_OK); 361 | } -------------------------------------------------------------------------------- /crypt/nn.c: -------------------------------------------------------------------------------- 1 | /* 2 | NN.C - natural numbers routines 3 | Copyright(C) 2002 by charry, charry@email.com.cn 4 | RSAEURO - RSA Library compatible with RSAREF(tm) 2.0. 5 | */ 6 | 7 | #include "rsaeuro.h" 8 | #include "nn.h" 9 | 10 | /* internal static functions */ 11 | 12 | static NN_DIGIT subdigitmult PROTO_LIST 13 | ((NN_DIGIT *, NN_DIGIT *, NN_DIGIT, NN_DIGIT *, unsigned int)); 14 | 15 | static void dmult PROTO_LIST ((NN_DIGIT, NN_DIGIT, NN_DIGIT *, NN_DIGIT *)); 16 | 17 | static unsigned int NN_DigitBits PROTO_LIST ((NN_DIGIT)); 18 | 19 | #ifndef USEASM 20 | 21 | /* Decodes character string b into a, where character string is ordered 22 | from most to least significant. 23 | 24 | Lengths: a[digits], b[len]. 25 | Assumes b[i] = 0 for i < len - digits * NN_DIGIT_LEN. (Otherwise most 26 | significant bytes are truncated.) 27 | */ 28 | 29 | void NN_Decode (a, digits, b, len) 30 | NN_DIGIT *a; 31 | unsigned char *b; 32 | unsigned int digits, len; 33 | { 34 | NN_DIGIT t; 35 | unsigned int i, u; 36 | int j; 37 | 38 | /* unsigned/signed bug fix added charry */ 39 | 40 | for (i = 0, j = len - 1; i < digits && j >= 0; i++) { 41 | t = 0; 42 | for (u = 0; j >= 0 && u < NN_DIGIT_BITS; j--, u += 8) 43 | t |= ((NN_DIGIT)b[j]) << u; 44 | a[i] = t; 45 | } 46 | 47 | for (; i < digits; i++) 48 | a[i] = 0; 49 | } 50 | 51 | /* Encodes b into character string a, where character string is ordered 52 | from most to least significant. 53 | 54 | Lengths: a[len], b[digits]. 55 | Assumes NN_Bits (b, digits) <= 8 * len. (Otherwise most significant 56 | digits are truncated.) 57 | */ 58 | 59 | void NN_Encode (a, len, b, digits) 60 | NN_DIGIT *b; 61 | unsigned char *a; 62 | unsigned int digits, len; 63 | { 64 | NN_DIGIT t; 65 | unsigned int i, u; 66 | int j; 67 | 68 | /* unsigned/signed bug fix added charry */ 69 | 70 | for (i = 0, j = len - 1; i < digits && j >= 0; i++) { 71 | t = b[i]; 72 | for (u = 0; j >= 0 && u < NN_DIGIT_BITS; j--, u += 8) 73 | a[j] = (unsigned char)(t >> u); 74 | } 75 | 76 | for (; j >= 0; j--) 77 | a[j] = 0; 78 | } 79 | 80 | /* Assigns a = 0. */ 81 | 82 | void NN_AssignZero (a, digits) 83 | NN_DIGIT *a; 84 | unsigned int digits; 85 | { 86 | if(digits) { 87 | do { 88 | *a++ = 0; 89 | }while(--digits); 90 | } 91 | } 92 | 93 | #endif 94 | 95 | /* Assigns a = 2^b. 96 | 97 | Lengths: a[digits]. 98 | Requires b < digits * NN_DIGIT_BITS. 99 | */ 100 | 101 | void NN_Assign2Exp (a, b, digits) 102 | NN_DIGIT *a; 103 | unsigned int b, digits; 104 | { 105 | NN_AssignZero (a, digits); 106 | 107 | if (b >= digits * NN_DIGIT_BITS) 108 | return; 109 | 110 | a[b / NN_DIGIT_BITS] = (NN_DIGIT)1 << (b % NN_DIGIT_BITS); 111 | } 112 | 113 | /* Computes a = b - c. Returns borrow. 114 | 115 | Lengths: a[digits], b[digits], c[digits]. 116 | */ 117 | 118 | NN_DIGIT NN_Sub (a, b, c, digits) 119 | NN_DIGIT *a, *b, *c; 120 | unsigned int digits; 121 | { 122 | NN_DIGIT temp, borrow = 0; 123 | 124 | if(digits) 125 | do { 126 | 127 | /* Bug fix charry, code below removed, caused bug with 128 | Sun Compiler SC4. 129 | 130 | if((temp = (*b++) - borrow) == MAX_NN_DIGIT) 131 | temp = MAX_NN_DIGIT - *c++; 132 | */ 133 | 134 | temp = *b - borrow; 135 | b++; 136 | if(temp == MAX_NN_DIGIT) { 137 | temp = MAX_NN_DIGIT - *c; 138 | c++; 139 | }else { 140 | 141 | /* Patch to prevent bug for Sun CC */ 142 | 143 | if((temp -= *c) > (MAX_NN_DIGIT - *c)) 144 | borrow = 1; 145 | else 146 | borrow = 0; 147 | c++; 148 | } 149 | *a++ = temp; 150 | }while(--digits); 151 | 152 | return(borrow); 153 | } 154 | 155 | /* Computes a = b * c. 156 | 157 | Lengths: a[2*digits], b[digits], c[digits]. 158 | Assumes digits < MAX_NN_DIGITS. 159 | */ 160 | 161 | void NN_Mult (a, b, c, digits) 162 | NN_DIGIT *a, *b, *c; 163 | unsigned int digits; 164 | { 165 | NN_DIGIT t[2*MAX_NN_DIGITS]; 166 | NN_DIGIT dhigh, dlow, carry; 167 | unsigned int bDigits, cDigits, i, j; 168 | 169 | NN_AssignZero (t, 2 * digits); 170 | 171 | bDigits = NN_Digits (b, digits); 172 | cDigits = NN_Digits (c, digits); 173 | 174 | for (i = 0; i < bDigits; i++) { 175 | carry = 0; 176 | if(*(b+i) != 0) { 177 | for(j = 0; j < cDigits; j++) { 178 | dmult(*(b+i), *(c+j), &dhigh, &dlow); 179 | if((*(t+(i+j)) = *(t+(i+j)) + carry) < carry) 180 | carry = 1; 181 | else 182 | carry = 0; 183 | if((*(t+(i+j)) += dlow) < dlow) 184 | carry++; 185 | carry += dhigh; 186 | } 187 | } 188 | *(t+(i+cDigits)) += carry; 189 | } 190 | 191 | 192 | NN_Assign(a, t, 2 * digits); 193 | } 194 | 195 | /* Computes a = b * 2^c (i.e., shifts left c bits), returning carry. 196 | 197 | Requires c < NN_DIGIT_BITS. 198 | */ 199 | 200 | NN_DIGIT NN_LShift (a, b, c, digits) 201 | NN_DIGIT *a, *b; 202 | unsigned int c, digits; 203 | { 204 | NN_DIGIT temp, carry = 0; 205 | unsigned int t; 206 | 207 | if(c < NN_DIGIT_BITS) 208 | if(digits) { 209 | 210 | t = NN_DIGIT_BITS - c; 211 | 212 | do { 213 | temp = *b++; 214 | *a++ = (temp << c) | carry; 215 | carry = c ? (temp >> t) : 0; 216 | }while(--digits); 217 | } 218 | 219 | return (carry); 220 | } 221 | 222 | /* Computes a = c div 2^c (i.e., shifts right c bits), returning carry. 223 | 224 | Requires: c < NN_DIGIT_BITS. 225 | */ 226 | 227 | NN_DIGIT NN_RShift (a, b, c, digits) 228 | NN_DIGIT *a, *b; 229 | unsigned int c, digits; 230 | { 231 | NN_DIGIT temp, carry = 0; 232 | unsigned int t; 233 | 234 | if(c < NN_DIGIT_BITS) 235 | if(digits) { 236 | 237 | t = NN_DIGIT_BITS - c; 238 | 239 | do { 240 | digits--; 241 | temp = *(b+digits); 242 | *(a+digits) = (temp >> c) | carry; 243 | carry = c ? (temp << t) : 0; 244 | }while(digits); 245 | } 246 | 247 | return (carry); 248 | } 249 | 250 | /* Computes a = c div d and b = c mod d. 251 | 252 | Lengths: a[cDigits], b[dDigits], c[cDigits], d[dDigits]. 253 | Assumes d > 0, cDigits < 2 * MAX_NN_DIGITS, dDigits < MAX_NN_DIGITS. 254 | */ 255 | 256 | void NN_Div (a, b, c, cDigits, d, dDigits) 257 | NN_DIGIT *a, *b, *c, *d; 258 | unsigned int cDigits, dDigits; 259 | { 260 | NN_DIGIT ai, cc[2*MAX_NN_DIGITS+1], dd[MAX_NN_DIGITS], s; 261 | NN_DIGIT t[2], u, v, *ccptr; 262 | NN_HALF_DIGIT aHigh, aLow, cHigh, cLow; 263 | int i; 264 | unsigned int ddDigits, shift; 265 | 266 | ddDigits = NN_Digits (d, dDigits); 267 | if(ddDigits == 0) 268 | return; 269 | 270 | shift = NN_DIGIT_BITS - NN_DigitBits (d[ddDigits-1]); 271 | NN_AssignZero (cc, ddDigits); 272 | cc[cDigits] = NN_LShift (cc, c, shift, cDigits); 273 | NN_LShift (dd, d, shift, ddDigits); 274 | s = dd[ddDigits-1]; 275 | 276 | NN_AssignZero (a, cDigits); 277 | 278 | for (i = cDigits-ddDigits; i >= 0; i--) { 279 | if (s == MAX_NN_DIGIT) 280 | ai = cc[i+ddDigits]; 281 | else { 282 | ccptr = &cc[i+ddDigits-1]; 283 | 284 | s++; 285 | cHigh = (NN_HALF_DIGIT)HIGH_HALF (s); 286 | cLow = (NN_HALF_DIGIT)LOW_HALF (s); 287 | 288 | *t = *ccptr; 289 | *(t+1) = *(ccptr+1); 290 | 291 | if (cHigh == MAX_NN_HALF_DIGIT) 292 | aHigh = (NN_HALF_DIGIT)HIGH_HALF (*(t+1)); 293 | else 294 | aHigh = (NN_HALF_DIGIT)(*(t+1) / (cHigh + 1)); 295 | u = (NN_DIGIT)aHigh * (NN_DIGIT)cLow; 296 | v = (NN_DIGIT)aHigh * (NN_DIGIT)cHigh; 297 | if ((*t -= TO_HIGH_HALF (u)) > (MAX_NN_DIGIT - TO_HIGH_HALF (u))) 298 | t[1]--; 299 | *(t+1) -= HIGH_HALF (u); 300 | *(t+1) -= v; 301 | 302 | while ((*(t+1) > cHigh) || 303 | ((*(t+1) == cHigh) && (*t >= TO_HIGH_HALF (cLow)))) { 304 | if ((*t -= TO_HIGH_HALF (cLow)) > MAX_NN_DIGIT - TO_HIGH_HALF (cLow)) 305 | t[1]--; 306 | *(t+1) -= cHigh; 307 | aHigh++; 308 | } 309 | 310 | if (cHigh == MAX_NN_HALF_DIGIT) 311 | aLow = (NN_HALF_DIGIT)LOW_HALF (*(t+1)); 312 | else 313 | aLow = 314 | (NN_HALF_DIGIT)((TO_HIGH_HALF (*(t+1)) + HIGH_HALF (*t)) / (cHigh + 1)); 315 | u = (NN_DIGIT)aLow * (NN_DIGIT)cLow; 316 | v = (NN_DIGIT)aLow * (NN_DIGIT)cHigh; 317 | if ((*t -= u) > (MAX_NN_DIGIT - u)) 318 | t[1]--; 319 | if ((*t -= TO_HIGH_HALF (v)) > (MAX_NN_DIGIT - TO_HIGH_HALF (v))) 320 | t[1]--; 321 | *(t+1) -= HIGH_HALF (v); 322 | 323 | while ((*(t+1) > 0) || ((*(t+1) == 0) && *t >= s)) { 324 | if ((*t -= s) > (MAX_NN_DIGIT - s)) 325 | t[1]--; 326 | aLow++; 327 | } 328 | 329 | ai = TO_HIGH_HALF (aHigh) + aLow; 330 | s--; 331 | } 332 | 333 | cc[i+ddDigits] -= subdigitmult(&cc[i], &cc[i], ai, dd, ddDigits); 334 | 335 | while (cc[i+ddDigits] || (NN_Cmp (&cc[i], dd, ddDigits) >= 0)) { 336 | ai++; 337 | cc[i+ddDigits] -= NN_Sub (&cc[i], &cc[i], dd, ddDigits); 338 | } 339 | 340 | a[i] = ai; 341 | } 342 | 343 | NN_AssignZero (b, dDigits); 344 | NN_RShift (b, cc, shift, ddDigits); 345 | } 346 | 347 | 348 | /* Computes a = b mod c. 349 | 350 | Lengths: a[cDigits], b[bDigits], c[cDigits]. 351 | Assumes c > 0, bDigits < 2 * MAX_NN_DIGITS, cDigits < MAX_NN_DIGITS. 352 | */ 353 | void NN_Mod (a, b, bDigits, c, cDigits) 354 | NN_DIGIT *a, *b, *c; 355 | unsigned int bDigits, cDigits; 356 | { 357 | NN_DIGIT t[2 * MAX_NN_DIGITS]; 358 | 359 | NN_Div (t, a, b, bDigits, c, cDigits); 360 | } 361 | 362 | /* Computes a = b * c mod d. 363 | 364 | Lengths: a[digits], b[digits], c[digits], d[digits]. 365 | Assumes d > 0, digits < MAX_NN_DIGITS. 366 | */ 367 | void NN_ModMult (a, b, c, d, digits) 368 | NN_DIGIT *a, *b, *c, *d; 369 | unsigned int digits; 370 | { 371 | NN_DIGIT t[2*MAX_NN_DIGITS]; 372 | 373 | NN_Mult (t, b, c, digits); 374 | NN_Mod (a, t, 2 * digits, d, digits); 375 | } 376 | 377 | /* Computes a = b^c mod d. 378 | 379 | Lengths: a[dDigits], b[dDigits], c[cDigits], d[dDigits]. 380 | Assumes d > 0, cDigits > 0, dDigits < MAX_NN_DIGITS. 381 | */ 382 | void NN_ModExp (a, b, c, cDigits, d, dDigits) 383 | NN_DIGIT *a, *b, *c, *d; 384 | unsigned int cDigits, dDigits; 385 | { 386 | NN_DIGIT bPower[3][MAX_NN_DIGITS], ci, t[MAX_NN_DIGITS]; 387 | int i; 388 | unsigned int ciBits, j, s; 389 | 390 | /* Store b, b^2 mod d, and b^3 mod d. */ 391 | 392 | NN_Assign (bPower[0], b, dDigits); 393 | NN_ModMult (bPower[1], bPower[0], b, d, dDigits); 394 | NN_ModMult (bPower[2], bPower[1], b, d, dDigits); 395 | 396 | NN_ASSIGN_DIGIT (t, 1, dDigits); 397 | 398 | cDigits = NN_Digits (c, cDigits); 399 | for (i = cDigits - 1; i >= 0; i--) { 400 | ci = c[i]; 401 | ciBits = NN_DIGIT_BITS; 402 | 403 | /* Scan past leading zero bits of most significant digit. */ 404 | 405 | if (i == (int)(cDigits - 1)) { 406 | while (! DIGIT_2MSB (ci)) { 407 | ci <<= 2; 408 | ciBits -= 2; 409 | } 410 | } 411 | 412 | for (j = 0; j < ciBits; j += 2, ci <<= 2) { 413 | 414 | /* Compute t = t^4 * b^s mod d, where s = two MSB's of ci. */ 415 | 416 | NN_ModMult (t, t, t, d, dDigits); 417 | NN_ModMult (t, t, t, d, dDigits); 418 | if ((s = DIGIT_2MSB (ci)) != 0) 419 | NN_ModMult (t, t, bPower[s-1], d, dDigits); 420 | } 421 | } 422 | 423 | NN_Assign (a, t, dDigits); 424 | } 425 | 426 | /* Compute a = 1/b mod c, assuming inverse exists. 427 | 428 | Lengths: a[digits], b[digits], c[digits]. 429 | Assumes gcd (b, c) = 1, digits < MAX_NN_DIGITS. 430 | */ 431 | 432 | void NN_ModInv (a, b, c, digits) 433 | NN_DIGIT *a, *b, *c; 434 | unsigned int digits; 435 | { 436 | NN_DIGIT q[MAX_NN_DIGITS], t1[MAX_NN_DIGITS], t3[MAX_NN_DIGITS], 437 | u1[MAX_NN_DIGITS], u3[MAX_NN_DIGITS], v1[MAX_NN_DIGITS], 438 | v3[MAX_NN_DIGITS], w[2*MAX_NN_DIGITS]; 439 | int u1Sign; 440 | 441 | /* Apply extended Euclidean algorithm, modified to avoid negative 442 | numbers. 443 | */ 444 | 445 | NN_ASSIGN_DIGIT (u1, 1, digits); 446 | NN_AssignZero (v1, digits); 447 | NN_Assign (u3, b, digits); 448 | NN_Assign (v3, c, digits); 449 | u1Sign = 1; 450 | 451 | while (! NN_Zero (v3, digits)) { 452 | NN_Div (q, t3, u3, digits, v3, digits); 453 | NN_Mult (w, q, v1, digits); 454 | NN_Add (t1, u1, w, digits); 455 | NN_Assign (u1, v1, digits); 456 | NN_Assign (v1, t1, digits); 457 | NN_Assign (u3, v3, digits); 458 | NN_Assign (v3, t3, digits); 459 | u1Sign = -u1Sign; 460 | } 461 | 462 | /* Negate result if sign is negative. */ 463 | 464 | if (u1Sign < 0) 465 | NN_Sub (a, c, u1, digits); 466 | else 467 | NN_Assign (a, u1, digits); 468 | } 469 | 470 | /* Computes a = gcd(b, c). 471 | 472 | Assumes b > c, digits < MAX_NN_DIGITS. 473 | */ 474 | 475 | #define iplus1 ( i==2 ? 0 : i+1 ) /* used by Euclid algorithms */ 476 | #define iminus1 ( i==0 ? 2 : i-1 ) /* used by Euclid algorithms */ 477 | #define g(i) ( &(t[i][0]) ) 478 | 479 | void NN_Gcd(a ,b ,c, digits) 480 | NN_DIGIT *a, *b, *c; 481 | unsigned int digits; 482 | { 483 | short i; 484 | NN_DIGIT t[3][MAX_NN_DIGITS]; 485 | 486 | NN_Assign(g(0), c, digits); 487 | NN_Assign(g(1), b, digits); 488 | 489 | i=1; 490 | 491 | while(!NN_Zero(g(i),digits)) { 492 | NN_Mod(g(iplus1), g(iminus1), digits, g(i), digits); 493 | i = iplus1; 494 | } 495 | 496 | NN_Assign(a , g(iminus1), digits); 497 | } 498 | 499 | /* Returns the significant length of a in bits. 500 | 501 | Lengths: a[digits]. 502 | */ 503 | 504 | unsigned int NN_Bits (a, digits) 505 | NN_DIGIT *a; 506 | unsigned int digits; 507 | { 508 | if ((digits = NN_Digits (a, digits)) == 0) 509 | return (0); 510 | 511 | return ((digits - 1) * NN_DIGIT_BITS + NN_DigitBits (a[digits-1])); 512 | } 513 | 514 | #ifndef USEASM 515 | 516 | /* Returns sign of a - b. */ 517 | 518 | int NN_Cmp (a, b, digits) 519 | NN_DIGIT *a, *b; 520 | unsigned int digits; 521 | { 522 | 523 | if(digits) { 524 | do { 525 | digits--; 526 | if(*(a+digits) > *(b+digits)) 527 | return(1); 528 | if(*(a+digits) < *(b+digits)) 529 | return(-1); 530 | }while(digits); 531 | } 532 | 533 | return (0); 534 | } 535 | 536 | /* Returns nonzero iff a is zero. */ 537 | 538 | int NN_Zero (a, digits) 539 | NN_DIGIT *a; 540 | unsigned int digits; 541 | { 542 | if(digits) { 543 | do { 544 | if(*a++) 545 | return(0); 546 | }while(--digits); 547 | } 548 | 549 | return (1); 550 | } 551 | 552 | /* Assigns a = b. */ 553 | 554 | void NN_Assign (a, b, digits) 555 | NN_DIGIT *a, *b; 556 | unsigned int digits; 557 | { 558 | if(digits) { 559 | do { 560 | *a++ = *b++; 561 | }while(--digits); 562 | } 563 | } 564 | 565 | /* Returns the significant length of a in digits. */ 566 | 567 | unsigned int NN_Digits (a, digits) 568 | NN_DIGIT *a; 569 | unsigned int digits; 570 | { 571 | 572 | if(digits) { 573 | digits--; 574 | 575 | do { 576 | if(*(a+digits)) 577 | break; 578 | }while(digits--); 579 | 580 | return(digits + 1); 581 | } 582 | 583 | return(digits); 584 | } 585 | 586 | /* Computes a = b + c. Returns carry. 587 | 588 | Lengths: a[digits], b[digits], c[digits]. 589 | */ 590 | 591 | NN_DIGIT NN_Add (a, b, c, digits) 592 | NN_DIGIT *a, *b, *c; 593 | unsigned int digits; 594 | { 595 | NN_DIGIT temp, carry = 0; 596 | 597 | if(digits) 598 | do { 599 | if((temp = (*b++) + carry) < carry) 600 | temp = *c++; 601 | else { 602 | 603 | /* Patch to prevent bug for Sun CC */ 604 | 605 | if((temp += *c) < *c) 606 | carry = 1; 607 | else 608 | carry = 0; 609 | c++; 610 | } 611 | *a++ = temp; 612 | }while(--digits); 613 | 614 | return (carry); 615 | } 616 | 617 | #endif 618 | 619 | static NN_DIGIT subdigitmult(a, b, c, d, digits) 620 | NN_DIGIT *a, *b, c, *d; 621 | unsigned int digits; 622 | { 623 | NN_DIGIT borrow, thigh, tlow; 624 | unsigned int i; 625 | 626 | borrow = 0; 627 | 628 | if(c != 0) { 629 | for(i = 0; i < digits; i++) { 630 | dmult(c, d[i], &thigh, &tlow); 631 | if((a[i] = b[i] - borrow) > (MAX_NN_DIGIT - borrow)) 632 | borrow = 1; 633 | else 634 | borrow = 0; 635 | if((a[i] -= tlow) > (MAX_NN_DIGIT - tlow)) 636 | borrow++; 637 | borrow += thigh; 638 | } 639 | } 640 | 641 | return (borrow); 642 | } 643 | 644 | /* Returns the significant length of a in bits, where a is a digit. */ 645 | 646 | static unsigned int NN_DigitBits (a) 647 | NN_DIGIT a; 648 | { 649 | unsigned int i; 650 | 651 | for (i = 0; i < NN_DIGIT_BITS; i++, a >>= 1) 652 | if (a == 0) 653 | break; 654 | 655 | return (i); 656 | } 657 | 658 | /* Computes a * b, result stored in high and low. */ 659 | 660 | static void dmult( a, b, high, low) 661 | NN_DIGIT a, b; 662 | NN_DIGIT *high; 663 | NN_DIGIT *low; 664 | { 665 | NN_HALF_DIGIT al, ah, bl, bh; 666 | NN_DIGIT m1, m2, m, ml, mh, carry = 0; 667 | 668 | al = (NN_HALF_DIGIT)LOW_HALF(a); 669 | ah = (NN_HALF_DIGIT)HIGH_HALF(a); 670 | bl = (NN_HALF_DIGIT)LOW_HALF(b); 671 | bh = (NN_HALF_DIGIT)HIGH_HALF(b); 672 | 673 | *low = (NN_DIGIT) al*bl; 674 | *high = (NN_DIGIT) ah*bh; 675 | 676 | m1 = (NN_DIGIT) al*bh; 677 | m2 = (NN_DIGIT) ah*bl; 678 | m = m1 + m2; 679 | 680 | if(m < m1) 681 | carry = 1L << (NN_DIGIT_BITS / 2); 682 | 683 | ml = (m & MAX_NN_HALF_DIGIT) << (NN_DIGIT_BITS / 2); 684 | mh = m >> (NN_DIGIT_BITS / 2); 685 | 686 | *low += ml; 687 | 688 | if(*low < ml) 689 | carry++; 690 | 691 | *high += carry + mh; 692 | } 693 | 694 | -------------------------------------------------------------------------------- /crypt/des.c: -------------------------------------------------------------------------------- 1 | /* 2 | * FIPS-46-3 compliant Triple-DES implementation 3 | * 4 | * Copyright (C) 2006-2010, Brainspark B.V. 5 | * 6 | * This file is part of PolarSSL (http://www.polarssl.org) 7 | * Lead Maintainer: Paul Bakker 8 | * 9 | * All rights reserved. 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; if not, write to the Free Software Foundation, Inc., 23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 24 | */ 25 | /* 26 | * DES, on which TDES is based, was originally designed by Horst Feistel 27 | * at IBM in 1974, and was adopted as a standard by NIST (formerly NBS). 28 | * 29 | * http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf 30 | */ 31 | 32 | #include "des.h" 33 | 34 | /* 35 | * 32-bit integer manipulation macros (big endian) 36 | */ 37 | #ifndef GET_ULONG_BE 38 | #define GET_ULONG_BE(n,b,i) \ 39 | { \ 40 | (n) = ( (unsigned long) (b)[(i) ] << 24 ) \ 41 | | ( (unsigned long) (b)[(i) + 1] << 16 ) \ 42 | | ( (unsigned long) (b)[(i) + 2] << 8 ) \ 43 | | ( (unsigned long) (b)[(i) + 3] ); \ 44 | } 45 | #endif 46 | 47 | #ifndef PUT_ULONG_BE 48 | #define PUT_ULONG_BE(n,b,i) \ 49 | { \ 50 | (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ 51 | (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ 52 | (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ 53 | (b)[(i) + 3] = (unsigned char) ( (n) ); \ 54 | } 55 | #endif 56 | 57 | /* 58 | * Expanded DES S-boxes 59 | */ 60 | static const unsigned long SB1[64] = 61 | { 62 | 0x01010400, 0x00000000, 0x00010000, 0x01010404, 63 | 0x01010004, 0x00010404, 0x00000004, 0x00010000, 64 | 0x00000400, 0x01010400, 0x01010404, 0x00000400, 65 | 0x01000404, 0x01010004, 0x01000000, 0x00000004, 66 | 0x00000404, 0x01000400, 0x01000400, 0x00010400, 67 | 0x00010400, 0x01010000, 0x01010000, 0x01000404, 68 | 0x00010004, 0x01000004, 0x01000004, 0x00010004, 69 | 0x00000000, 0x00000404, 0x00010404, 0x01000000, 70 | 0x00010000, 0x01010404, 0x00000004, 0x01010000, 71 | 0x01010400, 0x01000000, 0x01000000, 0x00000400, 72 | 0x01010004, 0x00010000, 0x00010400, 0x01000004, 73 | 0x00000400, 0x00000004, 0x01000404, 0x00010404, 74 | 0x01010404, 0x00010004, 0x01010000, 0x01000404, 75 | 0x01000004, 0x00000404, 0x00010404, 0x01010400, 76 | 0x00000404, 0x01000400, 0x01000400, 0x00000000, 77 | 0x00010004, 0x00010400, 0x00000000, 0x01010004 78 | }; 79 | 80 | static const unsigned long SB2[64] = 81 | { 82 | 0x80108020, 0x80008000, 0x00008000, 0x00108020, 83 | 0x00100000, 0x00000020, 0x80100020, 0x80008020, 84 | 0x80000020, 0x80108020, 0x80108000, 0x80000000, 85 | 0x80008000, 0x00100000, 0x00000020, 0x80100020, 86 | 0x00108000, 0x00100020, 0x80008020, 0x00000000, 87 | 0x80000000, 0x00008000, 0x00108020, 0x80100000, 88 | 0x00100020, 0x80000020, 0x00000000, 0x00108000, 89 | 0x00008020, 0x80108000, 0x80100000, 0x00008020, 90 | 0x00000000, 0x00108020, 0x80100020, 0x00100000, 91 | 0x80008020, 0x80100000, 0x80108000, 0x00008000, 92 | 0x80100000, 0x80008000, 0x00000020, 0x80108020, 93 | 0x00108020, 0x00000020, 0x00008000, 0x80000000, 94 | 0x00008020, 0x80108000, 0x00100000, 0x80000020, 95 | 0x00100020, 0x80008020, 0x80000020, 0x00100020, 96 | 0x00108000, 0x00000000, 0x80008000, 0x00008020, 97 | 0x80000000, 0x80100020, 0x80108020, 0x00108000 98 | }; 99 | 100 | static const unsigned long SB3[64] = 101 | { 102 | 0x00000208, 0x08020200, 0x00000000, 0x08020008, 103 | 0x08000200, 0x00000000, 0x00020208, 0x08000200, 104 | 0x00020008, 0x08000008, 0x08000008, 0x00020000, 105 | 0x08020208, 0x00020008, 0x08020000, 0x00000208, 106 | 0x08000000, 0x00000008, 0x08020200, 0x00000200, 107 | 0x00020200, 0x08020000, 0x08020008, 0x00020208, 108 | 0x08000208, 0x00020200, 0x00020000, 0x08000208, 109 | 0x00000008, 0x08020208, 0x00000200, 0x08000000, 110 | 0x08020200, 0x08000000, 0x00020008, 0x00000208, 111 | 0x00020000, 0x08020200, 0x08000200, 0x00000000, 112 | 0x00000200, 0x00020008, 0x08020208, 0x08000200, 113 | 0x08000008, 0x00000200, 0x00000000, 0x08020008, 114 | 0x08000208, 0x00020000, 0x08000000, 0x08020208, 115 | 0x00000008, 0x00020208, 0x00020200, 0x08000008, 116 | 0x08020000, 0x08000208, 0x00000208, 0x08020000, 117 | 0x00020208, 0x00000008, 0x08020008, 0x00020200 118 | }; 119 | 120 | static const unsigned long SB4[64] = 121 | { 122 | 0x00802001, 0x00002081, 0x00002081, 0x00000080, 123 | 0x00802080, 0x00800081, 0x00800001, 0x00002001, 124 | 0x00000000, 0x00802000, 0x00802000, 0x00802081, 125 | 0x00000081, 0x00000000, 0x00800080, 0x00800001, 126 | 0x00000001, 0x00002000, 0x00800000, 0x00802001, 127 | 0x00000080, 0x00800000, 0x00002001, 0x00002080, 128 | 0x00800081, 0x00000001, 0x00002080, 0x00800080, 129 | 0x00002000, 0x00802080, 0x00802081, 0x00000081, 130 | 0x00800080, 0x00800001, 0x00802000, 0x00802081, 131 | 0x00000081, 0x00000000, 0x00000000, 0x00802000, 132 | 0x00002080, 0x00800080, 0x00800081, 0x00000001, 133 | 0x00802001, 0x00002081, 0x00002081, 0x00000080, 134 | 0x00802081, 0x00000081, 0x00000001, 0x00002000, 135 | 0x00800001, 0x00002001, 0x00802080, 0x00800081, 136 | 0x00002001, 0x00002080, 0x00800000, 0x00802001, 137 | 0x00000080, 0x00800000, 0x00002000, 0x00802080 138 | }; 139 | 140 | static const unsigned long SB5[64] = 141 | { 142 | 0x00000100, 0x02080100, 0x02080000, 0x42000100, 143 | 0x00080000, 0x00000100, 0x40000000, 0x02080000, 144 | 0x40080100, 0x00080000, 0x02000100, 0x40080100, 145 | 0x42000100, 0x42080000, 0x00080100, 0x40000000, 146 | 0x02000000, 0x40080000, 0x40080000, 0x00000000, 147 | 0x40000100, 0x42080100, 0x42080100, 0x02000100, 148 | 0x42080000, 0x40000100, 0x00000000, 0x42000000, 149 | 0x02080100, 0x02000000, 0x42000000, 0x00080100, 150 | 0x00080000, 0x42000100, 0x00000100, 0x02000000, 151 | 0x40000000, 0x02080000, 0x42000100, 0x40080100, 152 | 0x02000100, 0x40000000, 0x42080000, 0x02080100, 153 | 0x40080100, 0x00000100, 0x02000000, 0x42080000, 154 | 0x42080100, 0x00080100, 0x42000000, 0x42080100, 155 | 0x02080000, 0x00000000, 0x40080000, 0x42000000, 156 | 0x00080100, 0x02000100, 0x40000100, 0x00080000, 157 | 0x00000000, 0x40080000, 0x02080100, 0x40000100 158 | }; 159 | 160 | static const unsigned long SB6[64] = 161 | { 162 | 0x20000010, 0x20400000, 0x00004000, 0x20404010, 163 | 0x20400000, 0x00000010, 0x20404010, 0x00400000, 164 | 0x20004000, 0x00404010, 0x00400000, 0x20000010, 165 | 0x00400010, 0x20004000, 0x20000000, 0x00004010, 166 | 0x00000000, 0x00400010, 0x20004010, 0x00004000, 167 | 0x00404000, 0x20004010, 0x00000010, 0x20400010, 168 | 0x20400010, 0x00000000, 0x00404010, 0x20404000, 169 | 0x00004010, 0x00404000, 0x20404000, 0x20000000, 170 | 0x20004000, 0x00000010, 0x20400010, 0x00404000, 171 | 0x20404010, 0x00400000, 0x00004010, 0x20000010, 172 | 0x00400000, 0x20004000, 0x20000000, 0x00004010, 173 | 0x20000010, 0x20404010, 0x00404000, 0x20400000, 174 | 0x00404010, 0x20404000, 0x00000000, 0x20400010, 175 | 0x00000010, 0x00004000, 0x20400000, 0x00404010, 176 | 0x00004000, 0x00400010, 0x20004010, 0x00000000, 177 | 0x20404000, 0x20000000, 0x00400010, 0x20004010 178 | }; 179 | 180 | static const unsigned long SB7[64] = 181 | { 182 | 0x00200000, 0x04200002, 0x04000802, 0x00000000, 183 | 0x00000800, 0x04000802, 0x00200802, 0x04200800, 184 | 0x04200802, 0x00200000, 0x00000000, 0x04000002, 185 | 0x00000002, 0x04000000, 0x04200002, 0x00000802, 186 | 0x04000800, 0x00200802, 0x00200002, 0x04000800, 187 | 0x04000002, 0x04200000, 0x04200800, 0x00200002, 188 | 0x04200000, 0x00000800, 0x00000802, 0x04200802, 189 | 0x00200800, 0x00000002, 0x04000000, 0x00200800, 190 | 0x04000000, 0x00200800, 0x00200000, 0x04000802, 191 | 0x04000802, 0x04200002, 0x04200002, 0x00000002, 192 | 0x00200002, 0x04000000, 0x04000800, 0x00200000, 193 | 0x04200800, 0x00000802, 0x00200802, 0x04200800, 194 | 0x00000802, 0x04000002, 0x04200802, 0x04200000, 195 | 0x00200800, 0x00000000, 0x00000002, 0x04200802, 196 | 0x00000000, 0x00200802, 0x04200000, 0x00000800, 197 | 0x04000002, 0x04000800, 0x00000800, 0x00200002 198 | }; 199 | 200 | static const unsigned long SB8[64] = 201 | { 202 | 0x10001040, 0x00001000, 0x00040000, 0x10041040, 203 | 0x10000000, 0x10001040, 0x00000040, 0x10000000, 204 | 0x00040040, 0x10040000, 0x10041040, 0x00041000, 205 | 0x10041000, 0x00041040, 0x00001000, 0x00000040, 206 | 0x10040000, 0x10000040, 0x10001000, 0x00001040, 207 | 0x00041000, 0x00040040, 0x10040040, 0x10041000, 208 | 0x00001040, 0x00000000, 0x00000000, 0x10040040, 209 | 0x10000040, 0x10001000, 0x00041040, 0x00040000, 210 | 0x00041040, 0x00040000, 0x10041000, 0x00001000, 211 | 0x00000040, 0x10040040, 0x00001000, 0x00041040, 212 | 0x10001000, 0x00000040, 0x10000040, 0x10040000, 213 | 0x10040040, 0x10000000, 0x00040000, 0x10001040, 214 | 0x00000000, 0x10041040, 0x00040040, 0x10000040, 215 | 0x10040000, 0x10001000, 0x10001040, 0x00000000, 216 | 0x10041040, 0x00041000, 0x00041000, 0x00001040, 217 | 0x00001040, 0x00040040, 0x10000000, 0x10041000 218 | }; 219 | 220 | /* 221 | * PC1: left and right halves bit-swap 222 | */ 223 | static const unsigned long LHs[16] = 224 | { 225 | 0x00000000, 0x00000001, 0x00000100, 0x00000101, 226 | 0x00010000, 0x00010001, 0x00010100, 0x00010101, 227 | 0x01000000, 0x01000001, 0x01000100, 0x01000101, 228 | 0x01010000, 0x01010001, 0x01010100, 0x01010101 229 | }; 230 | 231 | static const unsigned long RHs[16] = 232 | { 233 | 0x00000000, 0x01000000, 0x00010000, 0x01010000, 234 | 0x00000100, 0x01000100, 0x00010100, 0x01010100, 235 | 0x00000001, 0x01000001, 0x00010001, 0x01010001, 236 | 0x00000101, 0x01000101, 0x00010101, 0x01010101, 237 | }; 238 | 239 | /* 240 | * Initial Permutation macro 241 | */ 242 | #define DES_IP(X,Y) \ 243 | { \ 244 | T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \ 245 | T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \ 246 | T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \ 247 | T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \ 248 | Y = ((Y << 1) | (Y >> 31)) & 0xFFFFFFFF; \ 249 | T = (X ^ Y) & 0xAAAAAAAA; Y ^= T; X ^= T; \ 250 | X = ((X << 1) | (X >> 31)) & 0xFFFFFFFF; \ 251 | } 252 | 253 | /* 254 | * Final Permutation macro 255 | */ 256 | #define DES_FP(X,Y) \ 257 | { \ 258 | X = ((X << 31) | (X >> 1)) & 0xFFFFFFFF; \ 259 | T = (X ^ Y) & 0xAAAAAAAA; X ^= T; Y ^= T; \ 260 | Y = ((Y << 31) | (Y >> 1)) & 0xFFFFFFFF; \ 261 | T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \ 262 | T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \ 263 | T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \ 264 | T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \ 265 | } 266 | 267 | /* 268 | * DES round macro 269 | */ 270 | #define DES_ROUND(X,Y) \ 271 | { \ 272 | T = *SK++ ^ X; \ 273 | Y ^= SB8[ (T ) & 0x3F ] ^ \ 274 | SB6[ (T >> 8) & 0x3F ] ^ \ 275 | SB4[ (T >> 16) & 0x3F ] ^ \ 276 | SB2[ (T >> 24) & 0x3F ]; \ 277 | \ 278 | T = *SK++ ^ ((X << 28) | (X >> 4)); \ 279 | Y ^= SB7[ (T ) & 0x3F ] ^ \ 280 | SB5[ (T >> 8) & 0x3F ] ^ \ 281 | SB3[ (T >> 16) & 0x3F ] ^ \ 282 | SB1[ (T >> 24) & 0x3F ]; \ 283 | } 284 | 285 | #define SWAP(a,b) { unsigned long t = a; a = b; b = t; t = 0; } 286 | 287 | static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8, 288 | 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44, 289 | 47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81, 290 | 82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, 104, 107, 109, 110, 112, 291 | 115, 117, 118, 121, 122, 124, 127, 128, 131, 133, 134, 137, 138, 140, 292 | 143, 145, 146, 148, 151, 152, 155, 157, 158, 161, 162, 164, 167, 168, 293 | 171, 173, 174, 176, 179, 181, 182, 185, 186, 188, 191, 193, 194, 196, 294 | 199, 200, 203, 205, 206, 208, 211, 213, 214, 217, 218, 220, 223, 224, 295 | 227, 229, 230, 233, 234, 236, 239, 241, 242, 244, 247, 248, 251, 253, 296 | 254 }; 297 | 298 | void des_key_set_parity( unsigned char key[DES_KEY_SIZE] ) 299 | { 300 | int i; 301 | 302 | for( i = 0; i < DES_KEY_SIZE; i++ ) 303 | key[i] = odd_parity_table[key[i] / 2]; 304 | } 305 | 306 | /* 307 | * Check the given key's parity, returns 1 on failure, 0 on SUCCESS 308 | */ 309 | int des_key_check_key_parity( const unsigned char key[DES_KEY_SIZE] ) 310 | { 311 | int i; 312 | 313 | for( i = 0; i < DES_KEY_SIZE; i++ ) 314 | if ( key[i] != odd_parity_table[key[i] / 2] ) 315 | return( 1 ); 316 | 317 | return( 0 ); 318 | } 319 | 320 | /* 321 | * Table of weak and semi-weak keys 322 | * 323 | * Source: http://en.wikipedia.org/wiki/Weak_key 324 | * 325 | * Weak: 326 | * Alternating ones + zeros (0x0101010101010101) 327 | * Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE) 328 | * '0xE0E0E0E0F1F1F1F1' 329 | * '0x1F1F1F1F0E0E0E0E' 330 | * 331 | * Semi-weak: 332 | * 0x011F011F010E010E and 0x1F011F010E010E01 333 | * 0x01E001E001F101F1 and 0xE001E001F101F101 334 | * 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01 335 | * 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E 336 | * 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E 337 | * 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1 338 | * 339 | */ 340 | 341 | #define WEAK_KEY_COUNT 16 342 | 343 | static const unsigned char weak_key_table[WEAK_KEY_COUNT][DES_KEY_SIZE] = 344 | { 345 | { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, 346 | { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE }, 347 | { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E }, 348 | { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 }, 349 | 350 | { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E }, 351 | { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 }, 352 | { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 }, 353 | { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 }, 354 | { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE }, 355 | { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 }, 356 | { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 }, 357 | { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E }, 358 | { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE }, 359 | { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E }, 360 | { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE }, 361 | { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 } 362 | }; 363 | 364 | int des_key_check_weak( const unsigned char key[DES_KEY_SIZE] ) 365 | { 366 | int i; 367 | 368 | for( i = 0; i < WEAK_KEY_COUNT; i++ ) 369 | if( memcmp( weak_key_table[i], key, DES_KEY_SIZE) == 0) 370 | return( 1 ); 371 | 372 | return( 0 ); 373 | } 374 | 375 | static void des_setkey( unsigned long SK[32], const unsigned char key[DES_KEY_SIZE] ) 376 | { 377 | int i; 378 | unsigned long X, Y, T; 379 | 380 | GET_ULONG_BE( X, key, 0 ); 381 | GET_ULONG_BE( Y, key, 4 ); 382 | 383 | /* 384 | * Permuted Choice 1 385 | */ 386 | T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4); 387 | T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T ); 388 | 389 | X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2) 390 | | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] ) 391 | | (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6) 392 | | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4); 393 | 394 | Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2) 395 | | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] ) 396 | | (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6) 397 | | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4); 398 | 399 | X &= 0x0FFFFFFF; 400 | Y &= 0x0FFFFFFF; 401 | 402 | /* 403 | * calculate subkeys 404 | */ 405 | for( i = 0; i < 16; i++ ) 406 | { 407 | if( i < 2 || i == 8 || i == 15 ) 408 | { 409 | X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF; 410 | Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF; 411 | } 412 | else 413 | { 414 | X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF; 415 | Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF; 416 | } 417 | 418 | *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000) 419 | | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000) 420 | | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000) 421 | | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000) 422 | | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000) 423 | | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000) 424 | | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400) 425 | | ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100) 426 | | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010) 427 | | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004) 428 | | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001); 429 | 430 | *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000) 431 | | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000) 432 | | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000) 433 | | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000) 434 | | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000) 435 | | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000) 436 | | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000) 437 | | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400) 438 | | ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100) 439 | | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011) 440 | | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002); 441 | } 442 | } 443 | 444 | /* 445 | * DES key schedule (56-bit, encryption) 446 | */ 447 | int des_setkey_enc( des_context *ctx, const unsigned char key[DES_KEY_SIZE] ) 448 | { 449 | des_setkey( ctx->sk, key ); 450 | 451 | return( 0 ); 452 | } 453 | 454 | /* 455 | * DES key schedule (56-bit, decryption) 456 | */ 457 | int des_setkey_dec( des_context *ctx, const unsigned char key[DES_KEY_SIZE] ) 458 | { 459 | int i; 460 | 461 | des_setkey( ctx->sk, key ); 462 | 463 | for( i = 0; i < 16; i += 2 ) 464 | { 465 | SWAP( ctx->sk[i ], ctx->sk[30 - i] ); 466 | SWAP( ctx->sk[i + 1], ctx->sk[31 - i] ); 467 | } 468 | 469 | return( 0 ); 470 | } 471 | 472 | static void des3_set2key( unsigned long esk[96], 473 | unsigned long dsk[96], 474 | const unsigned char key[DES_KEY_SIZE*2] ) 475 | { 476 | int i; 477 | 478 | des_setkey( esk, key ); 479 | des_setkey( dsk + 32, key + 8 ); 480 | 481 | for( i = 0; i < 32; i += 2 ) 482 | { 483 | dsk[i ] = esk[30 - i]; 484 | dsk[i + 1] = esk[31 - i]; 485 | 486 | esk[i + 32] = dsk[62 - i]; 487 | esk[i + 33] = dsk[63 - i]; 488 | 489 | esk[i + 64] = esk[i ]; 490 | esk[i + 65] = esk[i + 1]; 491 | 492 | dsk[i + 64] = dsk[i ]; 493 | dsk[i + 65] = dsk[i + 1]; 494 | } 495 | } 496 | 497 | /* 498 | * Triple-DES key schedule (112-bit, encryption) 499 | */ 500 | int des3_set2key_enc( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 2] ) 501 | { 502 | unsigned long sk[96]; 503 | 504 | des3_set2key( ctx->sk, sk, key ); 505 | memset( sk, 0, sizeof( sk ) ); 506 | 507 | return( 0 ); 508 | } 509 | 510 | /* 511 | * Triple-DES key schedule (112-bit, decryption) 512 | */ 513 | int des3_set2key_dec( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 2] ) 514 | { 515 | unsigned long sk[96]; 516 | 517 | des3_set2key( sk, ctx->sk, key ); 518 | memset( sk, 0, sizeof( sk ) ); 519 | 520 | return( 0 ); 521 | } 522 | 523 | static void des3_set3key( unsigned long esk[96], 524 | unsigned long dsk[96], 525 | const unsigned char key[24] ) 526 | { 527 | int i; 528 | 529 | des_setkey( esk, key ); 530 | des_setkey( dsk + 32, key + 8 ); 531 | des_setkey( esk + 64, key + 16 ); 532 | 533 | for( i = 0; i < 32; i += 2 ) 534 | { 535 | dsk[i ] = esk[94 - i]; 536 | dsk[i + 1] = esk[95 - i]; 537 | 538 | esk[i + 32] = dsk[62 - i]; 539 | esk[i + 33] = dsk[63 - i]; 540 | 541 | dsk[i + 64] = esk[30 - i]; 542 | dsk[i + 65] = esk[31 - i]; 543 | } 544 | } 545 | 546 | /* 547 | * Triple-DES key schedule (168-bit, encryption) 548 | */ 549 | int des3_set3key_enc( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 3] ) 550 | { 551 | unsigned long sk[96]; 552 | 553 | des3_set3key( ctx->sk, sk, key ); 554 | memset( sk, 0, sizeof( sk ) ); 555 | 556 | return( 0 ); 557 | } 558 | 559 | /* 560 | * Triple-DES key schedule (168-bit, decryption) 561 | */ 562 | int des3_set3key_dec( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 3] ) 563 | { 564 | unsigned long sk[96]; 565 | 566 | des3_set3key( sk, ctx->sk, key ); 567 | memset( sk, 0, sizeof( sk ) ); 568 | 569 | return( 0 ); 570 | } 571 | 572 | /* 573 | * DES-ECB block encryption/decryption 574 | */ 575 | int des_crypt_ecb( des_context *ctx, 576 | const unsigned char input[8], 577 | unsigned char output[8] ) 578 | { 579 | int i; 580 | unsigned long X, Y, T, *SK; 581 | 582 | SK = ctx->sk; 583 | 584 | GET_ULONG_BE( X, input, 0 ); 585 | GET_ULONG_BE( Y, input, 4 ); 586 | 587 | DES_IP( X, Y ); 588 | 589 | for( i = 0; i < 8; i++ ) 590 | { 591 | DES_ROUND( Y, X ); 592 | DES_ROUND( X, Y ); 593 | } 594 | 595 | DES_FP( Y, X ); 596 | 597 | PUT_ULONG_BE( Y, output, 0 ); 598 | PUT_ULONG_BE( X, output, 4 ); 599 | 600 | return( 0 ); 601 | } 602 | 603 | /* 604 | * DES-CBC buffer encryption/decryption 605 | */ 606 | int des_crypt_cbc( des_context *ctx, 607 | int mode, 608 | size_t length, 609 | unsigned char iv[8], 610 | const unsigned char *input, 611 | unsigned char *output ) 612 | { 613 | int i; 614 | unsigned char temp[8]; 615 | 616 | if( length % 8 ) 617 | return( POLARSSL_ERR_DES_INVALID_INPUT_LENGTH ); 618 | 619 | if( mode == DES_ENCRYPT ) 620 | { 621 | while( length > 0 ) 622 | { 623 | for( i = 0; i < 8; i++ ) 624 | output[i] = (unsigned char)( input[i] ^ iv[i] ); 625 | 626 | des_crypt_ecb( ctx, output, output ); 627 | memcpy( iv, output, 8 ); 628 | 629 | input += 8; 630 | output += 8; 631 | length -= 8; 632 | } 633 | } 634 | else /* DES_DECRYPT */ 635 | { 636 | while( length > 0 ) 637 | { 638 | memcpy( temp, input, 8 ); 639 | des_crypt_ecb( ctx, input, output ); 640 | 641 | for( i = 0; i < 8; i++ ) 642 | output[i] = (unsigned char)( output[i] ^ iv[i] ); 643 | 644 | memcpy( iv, temp, 8 ); 645 | 646 | input += 8; 647 | output += 8; 648 | length -= 8; 649 | } 650 | } 651 | 652 | return( 0 ); 653 | } 654 | 655 | /* 656 | * 3DES-ECB block encryption/decryption 657 | */ 658 | int des3_crypt_ecb( des3_context *ctx, 659 | const unsigned char input[8], 660 | unsigned char output[8] ) 661 | { 662 | int i; 663 | unsigned long X, Y, T, *SK; 664 | 665 | SK = ctx->sk; 666 | 667 | GET_ULONG_BE( X, input, 0 ); 668 | GET_ULONG_BE( Y, input, 4 ); 669 | 670 | DES_IP( X, Y ); 671 | 672 | for( i = 0; i < 8; i++ ) 673 | { 674 | DES_ROUND( Y, X ); 675 | DES_ROUND( X, Y ); 676 | } 677 | 678 | for( i = 0; i < 8; i++ ) 679 | { 680 | DES_ROUND( X, Y ); 681 | DES_ROUND( Y, X ); 682 | } 683 | 684 | for( i = 0; i < 8; i++ ) 685 | { 686 | DES_ROUND( Y, X ); 687 | DES_ROUND( X, Y ); 688 | } 689 | 690 | DES_FP( Y, X ); 691 | 692 | PUT_ULONG_BE( Y, output, 0 ); 693 | PUT_ULONG_BE( X, output, 4 ); 694 | 695 | return( 0 ); 696 | } 697 | 698 | /* 699 | * 3DES-CBC buffer encryption/decryption 700 | */ 701 | int des3_crypt_cbc( des3_context *ctx, 702 | int mode, 703 | size_t length, 704 | unsigned char iv[8], 705 | const unsigned char *input, 706 | unsigned char *output ) 707 | { 708 | int i; 709 | unsigned char temp[8]; 710 | 711 | if( length % 8 ) 712 | return( POLARSSL_ERR_DES_INVALID_INPUT_LENGTH ); 713 | 714 | if( mode == DES_ENCRYPT ) 715 | { 716 | while( length > 0 ) 717 | { 718 | for( i = 0; i < 8; i++ ) 719 | output[i] = (unsigned char)( input[i] ^ iv[i] ); 720 | 721 | des3_crypt_ecb( ctx, output, output ); 722 | memcpy( iv, output, 8 ); 723 | 724 | input += 8; 725 | output += 8; 726 | length -= 8; 727 | } 728 | } 729 | else /* DES_DECRYPT */ 730 | { 731 | while( length > 0 ) 732 | { 733 | memcpy( temp, input, 8 ); 734 | des3_crypt_ecb( ctx, input, output ); 735 | 736 | for( i = 0; i < 8; i++ ) 737 | output[i] = (unsigned char)( output[i] ^ iv[i] ); 738 | 739 | memcpy( iv, temp, 8 ); 740 | 741 | input += 8; 742 | output += 8; 743 | length -= 8; 744 | } 745 | } 746 | 747 | return( 0 ); 748 | } 749 | --------------------------------------------------------------------------------