/* -------------------------------------------------------------------- hermes Algorithm (c) 2005 Dr. Ulrich Kaiser, (Texas Instruments) Germany UK20050317 initial version, copy from sc.c UK20050318 added visible stream and binary stream UK20050320 added initialization of RandReg UK20050328 added SBOX application to key byte afer init, after 11 rounds added plaintext length added Hermes_encrypt UK20050403 added loop to Hermes_encrypt; added Hermes_decrypt UK20050408 added encrypt/decrypt loopback check; added chisquare test to Hermes_encrypt. UK20050410 added FIPS 140-2 test to Hermes_encrypt UK20050415 added SetKey(); added sensitivity test for SAC checking. UK20050424 added MY_IV_LENGTH to SetLength for algo dependence. added SetPlaintext pattern. UK20050517 started changes in order to close the backdoor: made p1, p2, accu dependent on key; extended state to 23 resp. 37 bytes; defined variables OUTPUTBYTES, OUTPUTBITS; updated SetLength acordingly. UK20050602 corrected setIVlength, 37 max. corrected makesequence() TODO - ----------------------------------------------------------------------- */ #define credits "HERMES Advanced Stream Cipher Ulrich Kaiser (c) 2005 " #include #include #include /* statistical tool suite definitions */ #define CHISQ_95 0.00393214 #define CHISQ_90 0.0157908 #define CHISQ_10 2.70554 #define CHISQ_05 3.84146 /* CUSTOMIZE HERE */ #define LOPC 10 #define HIPC 90 #define EXPERIMENTS 100 #define EXPERIMENTSIZE 50 int TestRounds; float CHISQ_LO, CHISQ_HI; #define K_LENGTH 32 #define S_LENGTH 37 #define S_LENGTH1 23 #define S_LENGTH2 37 #define P_LENGTH 8 #include "ecrypt-sync.h" /* working space for other routines: crunch, init, stream */ u8 k[K_LENGTH]; /* key space */ u8 state[S_LENGTH]; /* cipher state */ u32 parm[P_LENGTH]; /* parameters */ u8 kh[K_LENGTH]; /* key helper */ #define X_LENGTH 37 #define Y_LENGTH 32 unsigned char x[X_LENGTH]; unsigned char y[Y_LENGTH]; /* global definition of number of rounds for initialisation ! */ int MY_INIT_ROUNDS = 10; /* global definition of number of rounds for stream cipher operation ! */ int MY_SC_ROUNDS = 100; /* global definition of number of IV bytes ! */ int MY_IV_LENGTH = S_LENGTH; /* global definition of number of plaintext resp. ciphertext bytes ! */ int MY_PT_LENGTH = 25600; #define PTSIZE 320000 u8 my_plaintext[PTSIZE]; u8 my_ciphertext[PTSIZE]; int MY_PT_PATTERN = 0; /* now dependent on algorithm ..., is set by SetLength */ int KEYBYTES = -1; int KEYBITS = -1; int STATEBYTES = -1; int STATEBITS = -1; int OUTPUTBYTES = -1; int OUTPUTBITS = -1; int algo = -1; /* selects algorithm */ #define ALGO_NOT_VALID "AlgorithmNumber not valid !\n" #define choice "[ Hermes8-80 = 1, Hermes8-128 = 2 ]" /* fail cunters */ int totalfail_runs_test=0; int totalfail_long_runs=0; int totalfail_poker=0; int total_fail_monobit=0; /* ----- random number generator ----- */ unsigned char RandReg[8]; /* output file handle */ FILE *op; /* --------- S-BOXes for SC algorithm -------------- */ /* ---------- AES code definitions ---------- */ typedef unsigned char word8; /* ----- AES encryption SBOX ----- */ word8 S[256] = { 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22, };/* ddt: 32130 255 0 0 0 0 0 */ unsigned char sbox130[256] = {130,150,219,161,127,160,229,198, 99, 26, 22, 63, 74,136,215,201 , 82,195, 3,225,239, 94,129, 80, 18,213,149,245, 7, 57,197,115 ,113,230,116,163,212,133,162,222,105, 60, 19,170,244, 30, 1,137 ,176, 27,185, 42,153, 16,104,202,221, 11,172,190,154,151,103, 71 , 28,187, 2, 88,231,204, 17, 37,228, 73, 44, 31,134,100,144,211 , 89,117,108, 39,227,241,232,247, 20,226,110,254,169, 14,174,119 ,131,152, 55,205, 49,164,142, 43,132, 12, 98,224,135,157,114, 83 , 78,236,111, 23,147, 70, 47,252,189, 32, 41,124,120, 58,102, 33 ,234,184,158,177,140,121,246,180,175, 45,101,233,168,138,203,188 , 15, 97,183,196, 59,250, 54, 6,148,207, 72,118,206, 86, 48,112 ,199, 36, 96,145, 75, 85,220,186,106,217, 34,240, 87,178, 69, 65 ,238, 91,179,159,249,146,107,214, 56,141, 10,243,125,165, 8, 29 , 52, 13,253,193, 66, 21,126, 50, 77,251,143, 84,192, 25, 9, 79 , 93, 46, 81, 0, 38, 4, 35, 5,194, 95,128,242,122,156,109, 90 ,248,166, 61, 76,167, 67,210,155,139,255, 24, 40, 53, 62,216,218 ,173,181,200, 68,191,223,171, 64,209, 92,123,237,182,235, 51,208 };/* ddt: 22166 4629 400 4 0 0 0 0 */ unsigned char sboxAF[256] = {0xAF, 0x1B, 0xDD, 0xBC, 0x30, 0xEB, 0xF0, 0x56, 0xC1, 0x08, 0x93, 0x36, 0x03, 0xCB, 0x81, 0x80, 0x43, 0x2F, 0xDF, 0x2D, 0x26, 0x05, 0x0A, 0xF8, 0x7D, 0x21, 0xE0, 0xC4, 0x06, 0xD5, 0xA6, 0xE8, 0x8E, 0x70, 0xDC, 0xA4, 0x6D, 0x23, 0xAC, 0x18, 0x40, 0x00, 0x64, 0x0E, 0xF6, 0x79, 0xB5, 0x1F, 0x5D, 0x9A, 0x3B, 0xFA, 0x48, 0x5F, 0x74, 0xA1, 0x8D, 0xD3, 0x5C, 0x4E, 0x9E, 0x14, 0x25, 0xEF, 0xD6, 0xC9, 0x3F, 0xC5, 0xA0, 0x10, 0x50, 0xFB, 0x31, 0xF4, 0x17, 0x88, 0xAB, 0x32, 0x76, 0x3E, 0x15, 0x2A, 0x3D, 0xA9, 0x52, 0x20, 0xC3, 0xFC, 0x7B, 0x49, 0x3A, 0x6E, 0xB7, 0x1D, 0xAD, 0xAA, 0x5A, 0x0D, 0x35, 0x38, 0xC8, 0xF5, 0xF3, 0xB3, 0x8F, 0xE6, 0x13, 0x55, 0x33, 0x8A, 0xC0, 0x67, 0x2E, 0xE7, 0x82, 0x8C, 0x09, 0xCF, 0x1E, 0x97, 0x28, 0x07, 0xBA, 0x4D, 0x42, 0x04, 0x73, 0x41, 0x5B, 0xB1, 0xF9, 0xE5, 0xF7, 0x6C, 0xD8, 0x12, 0x8B, 0x84, 0xCC, 0xB0, 0x69, 0x37, 0xAE, 0x6F, 0xE2, 0xDB, 0x0C, 0x86, 0x29, 0x78, 0x34, 0x7C, 0x1A, 0x85, 0x27, 0xA3, 0x9B, 0x92, 0xE3, 0xBD, 0x59, 0x63, 0x66, 0x19, 0xCA, 0x5E, 0xFF, 0x75, 0x72, 0x24, 0x4F, 0x47, 0x61, 0x11, 0x0B, 0xBE, 0xA7, 0x16, 0x3C, 0xB2, 0xFD, 0x7F, 0x44, 0x99, 0x6B, 0x98, 0x22, 0x46, 0x4A, 0x1C, 0x02, 0x6A, 0x51, 0x39, 0x60, 0x4B, 0x57, 0x01, 0x2C, 0xE1, 0xEE, 0x83, 0x89, 0xDA, 0x58, 0x0F, 0xBB, 0x2B, 0xD2, 0xD4, 0x62, 0x9F, 0x90, 0x7E, 0xDE, 0xB8, 0x4C, 0xCD, 0x68, 0xA8, 0xF2, 0x54, 0xE9, 0xE4, 0xF1, 0xEA, 0xD7, 0x77, 0x9D, 0x96, 0xEC, 0xFE, 0xB9, 0x91, 0xBF, 0xD1, 0xD9, 0xA2, 0x95, 0xED, 0xA5, 0xC2, 0x7A, 0xC6, 0xC7, 0x45, 0x94, 0xB6, 0x65, 0xD0, 0xCE, 0x9C, 0x71, 0x87, 0xB4, 0x53 };/* ddt: 19763 4917 854 106 9 2 0 */ /* ---------------------- bad s-box --------------------- */ unsigned char sboxBAD[256] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 128, 127, 126, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, 114, 113, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 160, 159, 158, 157, 156, 155, 154, 153, 152, 151, 150, 149, 148, 147, 146, 145, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 192, 191, 190, 189, 188, 187, 186, 185, 184, 183, 182, 181, 180, 179, 178, 177, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 224, 223, 222, 221, 220, 219, 218, 217, 216, 215, 214, 213, 212, 211, 210, 209, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 0, 255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, }; /************ This is the 8-bit algorithm under test ***************/ /************ This is the 8-bit algorithm under test ***************/ /************ This is the 8-bit algorithm under test ***************/ /* * DESCRIPTION OF ALGORITHM * * accu is one byte * s-box is a table with 256 bytes, i.e. 8 bit input and 8 bit output * * A state byte and a key byte and the previous result (accu) * are EXORed. Then the s-box function is applied. The output is * fed into accu and into the oldest state byte. * Number of initial rounds: >= 4 * Number of sub-rounds : 20 (Hermes8-80) or 32 (Hermes8-128) * * Confusion by: S-Box, non-linear boolean function * Diffusion by: Accu overwriting state byte * * * Notation * * Hermes8-80 * State register x consists of 20 bytes x[19]..x[0]. * Key register k consists of 10 bytes k[9]..k[0]. * or * Hermes8-128 * State register x consists of 32 bytes x[31]..x[0]. * Key register k consists of 16 bytes k[15]..k[0]. * */ /* ALGO1 ALGO2 */ void dump_state_key( int nx, int nk ) { int j; fprintf(op, "State: 0x \n"); for( j=0; j= nx ) po = po - nx; } } /* dump_key_hex( nk ); */ } /* stream_Hermes8 ------------------------------------------------ */ /* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */ /* -------------------- support for ECRYPT APIs --------------------- */ /* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */ void print_ciphertext_hex( u32 length ) { u32 j; fprintf(op, "\n"); fprintf(op, " printing ciphertext now .... \n" ); for(j=0; j expected value %d \n", n ); fprintf(op, "===> expected value %d \n", n ); chisqu = 0.0; for( index=0; index<256; index++ ) /* calculate Chi^2 */ { count = hist[index]; chisqu = chisqu + (count-n)*(count-n)/n ; } /* v=255, alpha=10% ==> x=284.366 */ printf("===> chisqu = %9.2f chisqu = %9.2f 284.336 ) { printf("====> ERROR: chisqu = %6.2f > 284.336 \n", chisqu ); fprintf(op, "====> ERROR: chisqu = %6.2f > 284.336 \n", chisqu ); } }/* ciphertext_histogram -------------------------------- */ void print_plaintext( u32 length ) { u32 j; fprintf(op, "\n"); fprintf(op, " printing plaintext now .... \n" ); for(j=0; jstate[j] );} fprintf(op,"\n"); fprintf(op, "Key:0x \n"); for( j=0; jk[j] );} fprintf(op,"\n"); }/* ECRYPT_dump_state_key ------------------------------------ */ void ECRYPT_dump_state_hex( ECRYPT_ctx* ctxx, int nx ) { int j; fprintf(op, "State: 0x \n"); for( j=0; jstate[j] );} fprintf(op, "\n"); }/* ECRYPT_dump_state_hex ------------------------------------ */ void ECRYPT_dump_key_hex( ECRYPT_ctx* ctxx, int nk ) { int j; fprintf(op, "Key:0x \n"); for( j=0; jk[j] );} fprintf(op, "\n"); }/* ECRYPT_dump_key_hex ------------------------------------ */ void dump_IV( u8* x, int nx ) { int j; fprintf(op, "IV: 0x \n"); for( j=0; jk[j] = key[j]; } ctx->parm[5] = kb; ctx->parm[6] = ivsize / 8; for( j=0; jk[j] ); } printf(" ECRYPT_keysetup done. \n"); for( j=0; jk[j] ); } fprintf(op, " ECRYPT_keysetup done. \n"); }/* ECRYPT_keysetup ------------------------------------------ */ /** loads iv[] into state[], runs initial rounds in order to hide IV and KEY from first key stream output. @param ctx ptr to record @param iv ptr to array with initial value IV */ void ECRYPT_ivsetup( ECRYPT_ctx* ctx, const u8* iv ) { u16 ivb; /* IV size in bytes. */ u16 round; /* round counter */ u16 nk; /* number of key bytes */ u16 nx; /* number of state bytes */ u16 p1; /* pointer to actual state byte */ u16 p2; /* pointer to actual key byte */ u8 accu; u16 src; /* sub-round counter */ u16 nrounds; /* number of rounds to run */ u16 j; /* little helpers */ u16 p3, p4; /* scratch */ u8 tmp; /* scratch */ /* fill IV into state[] */ ivb = ctx->parm[6]; for( j=0; jstate[j] = iv[j]; } for( j=0; jstate[j] ); } printf(" ECRYPT_ivsetup done. \n"); for( j=0; jstate[j] ); } fprintf(op, " ECRYPT_ivsetup done. \n"); /* ----------------- start of algorithm ----------------- */ /* fprintf(op, "Hermes8_init started...\n"); */ nrounds = MY_INIT_ROUNDS; /* number of rounds, i.e. outer loop count !! */ nk = ctx->parm[5]; /* kb */ nx = STATEBYTES; /* state size in bytes */ p1 = ( k[0] ^ k[1] ^ k[2] ) % nx ; p2 = ( k[3] ^ k[4] ^ k[5] ) % nk ; accu = k[6] ^ k[7] ^ k[8] ; #define KEY_STEP3 7 src = ( k[9] ^ k[0] ^ k[3] ) % KEY_STEP3; for( round=1; round <= nrounds; round++ ) { #include "hermes_core.h" }/* for round */ ctx->parm[0] = accu; ctx->parm[1] = p1; ctx->parm[2] = p2; ctx->parm[3] = src; ctx->parm[4] = MY_INIT_ROUNDS; printf( "INIT accu=0x%2x p1=%d p2=%d src=%d round=%d done.\n", ctx->parm[0],ctx->parm[1],ctx->parm[2],ctx->parm[3],ctx->parm[4] ); /* fprintf(op, "INIT accu=%d p1=%d p2=%d src=%d round=%d done.\n", ctx->parm[0],ctx->parm[1],ctx->parm[2],ctx->parm[3],ctx->parm[4] ); */ for( j=0; jstate[j] ); } printf(" ECRYPT_initialization done. \n\n"); for( j=0; jstate[j] ); } fprintf(op, " ECRYPT_initialization done. \n\n"); }/* ECRYPT_ivsetup ------------------------------------------ */ /** Encrypts a certain number of bytes of the plaintext. @param in ctx ptr to record @param in plaintext ptr to array with plaintext @param out ciphertext ptr to array with ciphertext @param in msglen number of bytes to process */ void ECRYPT_encrypt_bytes( ECRYPT_ctx* ctx, const u8* plaintext, u8* ciphertext, u32 msglen) /* Message length in bytes. */ { u32 round; u16 nx; /* number of state bytes */ u16 nk; /* number of key bytes */ u16 p1; /* pointer to actual state byte */ u16 p2; /* pointer to actual key byte */ u16 src; /* sub-round counter */ u8 accu; u16 po; /* output pointer */ u16 p3, p4; /* scratch */ u8 tmp; /* scratch */ u32 m, n, pc; /* little helpers */ u16 j; /* little helpers */ u32 maxloops; /* loops needed to process msglen bytes */ /* ----------------- start of algorithm ----------------- */ accu = ctx->parm[0] & 0x00FF; p1 = ctx->parm[1]; p2 = ctx->parm[2]; src = ctx->parm[3]; round = ctx->parm[4]; nk = ctx->parm[5]; nx = ctx->parm[6]; fprintf(op,"STREAM start accu=0x%2x p1=%d p2=%d scr=%d round=%d \n", accu, p1, p2, src, round ); printf("STREAM start accu=0x%2x p1=%d p2=%d scr=%d round=%d \n", accu, p1, p2, src, round ); maxloops = (u32)( msglen / OUTPUTBYTES + 1.0 ); pc = 0; for( n=0; nstate[po]; po = po + 2; if( po >= nx ) po = po - nx; } pc = pc + OUTPUTBYTES; }/* for n */ /* printf(" accu=%d p1=%d p2=%d src=%d round=%d \n", accu, p1, p2, src, round ); */ /* avoid further usage of this routine !!! */ ctx->parm[1] = 9999; ctx->parm[2] = 9999; /* show resulting state in GUI */ for(j=0; j<=STATEBYTES; j++){ y[j] = ctx->state[j]; } }/* ECRYPT_encrypt_bytes ------------------------------------------ */ /** Decrypts a certain number of bytes of the plaintext. @param in ctx ptr to record @param in ciphertext ptr to array with ciphertext @param out plaintext ptr to array with plaintext @param in msglen number of bytes to process */ void ECRYPT_decrypt_bytes( ECRYPT_ctx* ctx, const u8* ciphertext, u8* plaintext, u32 msglen) /* Message length in bytes. */ { u32 round; u16 nx; /* number of state bytes */ u16 nk; /* number of key bytes */ u16 p1; /* pointer to actual state byte */ u16 p2; /* pointer to actual key byte */ u16 src; /* sub-round counter */ u8 accu; u16 po; /* output pointer */ u16 p3, p4; /* scratch */ u8 tmp; /* scratch */ u32 n, pc; /* little helpers */ u16 j, m; /* little helpers */ u32 maxloops; /* loops needed to process msglen bytes */ /* fprintf(op, "Hermes8_stream started...\n"); */ /* ----------------- start of algorithm ----------------- */ accu = ctx->parm[0] & 0x00FF; p1 = ctx->parm[1]; p2 = ctx->parm[2]; src = ctx->parm[3]; round = ctx->parm[4]; nk = ctx->parm[5]; nx = ctx->parm[6]; fprintf(op,"STREAM start accu=%2x hex p1=%d p2=%d round=%d \n", accu, p1, p2, round ); printf("STREAM start accu=%2x hex p1=%d p2=%d round=%d \n", accu, p1, p2, round ); maxloops = (u32)( msglen / OUTPUTBYTES + 0.5 ); pc = 0; for( n=0; nstate[po]; po = po + 2; if( po >= nx ) po = po - nx; } pc = pc + OUTPUTBYTES; }/* for n */ /* printf(" accu=%d p1=%d p2=%d src=%d round=%d \n", accu, p1, p2, src, round ); */ /* avoid further usage of this routine !!! */ ctx->parm[1] = 9999; ctx->parm[2] = 9999; /* show resulting state in GUI */ for(j=0; j<=STATEBYTES; j++){ y[j] = ctx->state[j]; } } /* ECRYPT_decrypt_bytes ------------------------------------------ */ /** Generates key stream.... @param in ctx ptr to record @param out keystream ptr to array with key stream @param in length number of bytes to process */ void ECRYPT_keystream_bytes( /* based on ECRYPT_encrypt_bytes */ ECRYPT_ctx* ctx, u8* keystream, u32 length) /* Length of keystream in bytes. */ { u32 round; u16 nx; /* number of state bytes */ u16 nk; /* number of key bytes */ u16 p1; /* pointer to actual state byte */ u16 p2; /* pointer to actual key byte */ u16 src; /* sub-round counter */ u8 accu; u16 p3, p4; /* scratch */ u8 tmp; /* scratch */ u32 n, pc; /* little helpers */ u16 j, m; /* little helpers */ u32 maxloops; /* loops needed to process msglen bytes */ /* ----------------- start of algorithm ----------------- */ accu = ctx->parm[0] & 0x00FF; p1 = ctx->parm[1]; p2 = ctx->parm[2]; src = ctx->parm[3]; round = ctx->parm[4]; nk = ctx->parm[5]; nx = ctx->parm[6]; fprintf(op,"STREAM accu=%3d p1=%d p2=%d src=%d round=%d \n", accu, p1, p2, src, round ); printf("STREAM accu=%3d p1=%d p2=%d src=%d round=%d \n", accu, p1, p2, src, round ); maxloops = (u32)( length / OUTPUTBYTES + 0.5 ); pc = 0; for( n=0; nstate[j]; } */ for( j=0; jstate[j]; } pc = pc + OUTPUTBYTES; }/* for n */ } /* ECRYPT_keystream_bytes ------------------------------------------ */ /* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */ /* ---------------- wrappers for ECRYPT APIs ------------------------- */ /* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */ /** Encryption of plaintext of length pt_length Uses: ECRYPT_keysetup( &ctx, k, key_length*8, iv_length*8); ECRYPT_ivsetup( &ctx, x ); ECRYPT_encrypt_bytes( &ctx, plaintext, ciphertext, msg_length ); - @input x @input k @input algo @input plaintext @input pt_length - @global ciphertext */ void Hermes_encrypt( u8 x[], u8 k[], int algo, const u8* plaintext, u8* ciphertext, u32 pt_length ) { u32 key_length; u32 iv_length; u32 msg_length; ECRYPT_ctx ctx; /* create data structure */ msg_length = pt_length; key_length = 10; iv_length = S_LENGTH1; if( algo == 2 ){ key_length = 16; iv_length = S_LENGTH2;} printf("\n"); printf("Test of ECRYPT_* procedures \n"); printf(" key length = %5d \n", key_length ); printf(" iv length = %5d \n", iv_length ); printf(" pt length = %5d \n", pt_length ); /* Call the ECRYPT API subroutine */ ECRYPT_keysetup( &ctx, k, key_length*8, iv_length*8); printf( "==> accu=%d p1=%d p2=%d round=%d kb=%d ivb=%d done.\n", ctx.parm[0],ctx.parm[1],ctx.parm[2],ctx.parm[3],ctx.parm[4],ctx.parm[5]); /* Call the ECRYPT API subroutine */ ECRYPT_ivsetup( &ctx, x ); printf( "==> accu=%d p1=%d p2=%d round=%d kb=%d ivb=%d done.\n", ctx.parm[0],ctx.parm[1],ctx.parm[2],ctx.parm[3],ctx.parm[4],ctx.parm[5]); /* Call the ECRYPT API subroutine */ ECRYPT_encrypt_bytes( &ctx, plaintext, ciphertext, msg_length ); printf( "==> accu=%d p1=%d p2=%d round=%d kb=%d ivb=%d done.\n", ctx.parm[0],ctx.parm[1],ctx.parm[2],ctx.parm[3],ctx.parm[4],ctx.parm[5]); /* print_ciphertext( msg_length ); */ ciphertext_histogram( msg_length ); ECRYPT_dump_state_key( &ctx, iv_length, key_length ); ECRYPT_dump_key_hex( &ctx, key_length ); printf("\n"); }/* Hermes_encrypt ----------------------------------------------------------- */ /** Decryption of ciphertext of length pt_length Uses: ECRYPT_keysetup( &ctx, k, key_length*8, iv_length*8); ECRYPT_ivsetup( &ctx, x ); ECRYPT_decrypt_bytes( &ctx, ciphertext, plaintext, msg_length ); - @input x @input k @input algo @input ciphertext @input pt_length - @global plaintext */ void Hermes_decrypt( u8 x[], u8 k[], int algo, const u8* ciphertext, u8* plaintext, u32 pt_length ) { u32 key_length; u32 iv_length; u32 msg_length; ECRYPT_ctx ctx; /* create data structure */ msg_length = pt_length; key_length = 10; iv_length = S_LENGTH1; if( algo == 2 ){ key_length = 16; iv_length = S_LENGTH2;} printf("\n"); printf("Test of ECRYPT_* procedures \n"); printf(" key length = %5d \n", key_length ); printf(" iv length = %5d \n", iv_length ); printf(" pt length = %5d \n", pt_length ); /* Call the ECRYPT API subroutine */ ECRYPT_keysetup( &ctx, k, key_length*8, iv_length*8); printf( "==> accu=%d p1=%d p2=%d round=%d kb=%d ivb=%d done.\n", ctx.parm[0],ctx.parm[1],ctx.parm[2],ctx.parm[3],ctx.parm[4],ctx.parm[5]); /* Call the ECRYPT API subroutine */ ECRYPT_ivsetup( &ctx, x ); printf( "==> accu=%d p1=%d p2=%d round=%d kb=%d ivb=%d done.\n", ctx.parm[0],ctx.parm[1],ctx.parm[2],ctx.parm[3],ctx.parm[4],ctx.parm[5]); /* Call the ECRYPT API subroutine */ ECRYPT_decrypt_bytes( &ctx, ciphertext, plaintext, msg_length ); printf( "==> accu=%d p1=%d p2=%d round=%d kb=%d ivb=%d done.\n", ctx.parm[0],ctx.parm[1],ctx.parm[2],ctx.parm[3],ctx.parm[4],ctx.parm[5]); print_plaintext( msg_length ); ECRYPT_dump_state_key( &ctx, iv_length, key_length ); printf("\n"); }/* Hermes_decrypt ----------------------------------------------------------- */ /** Perform loops of encryption and decryption and check if the original plaintest is recovered again. - @input x @input k @input algo @input pt_length - @global plaintext @global ciphertext */ void Hermes_EncryptDecrypt( u8 x[], u8 k[], int algo, u32 pt_length ) { int j, n, loops=15; u8 pt[PTSIZE]; int FAILS = 0; u32 my_ptlength; /* u8 key[K_LENGTH]; for(j=0; j=0; j-- ) { fprintf(op, "%02x", x[j] ); } fprintf(op, " "); for( j=n-1; j>=0; j-- ) BinPrnt( x[j] ); fprintf(op, " \n"); } /* PRINT CHAR X IN BINARY */ void BinPrint( unsigned char x ) { int j; for (j=0;j<8;j++){ if (x & 0x80) cputs("1"); else cputs("o"); x <<= 1; } } /* DISPLAY REGISTER CONTENTS ON CONSOLE */ void ShowReg( char *msg, unsigned char *x, int n ){ int j; cputs(msg); for (j=n-1;j>=0;j--){ printf("%02x",x[j]); } cputs(" "); for (j=n-1;j>=0;j--) BinPrint(x[j]); } /* INTEGER CORRESPONDING TO HEX SYMBOL */ int HexVal(char ch){ int k; ch=toupper(ch); if (ch>='A'){ k=ch-'A'+10; } else{ k=ch-'0'; } return k; } /* HexVal --------------------------------- */ /* SET REGISTER x (n BYTES) ACCORDING TO STRING s REPRESENTING HEX VALUE */ void SetReg( unsigned char *x, int n, char *s ) { int j,k,i; for (j=0;j=0) && (i