/* * Copyright (c) 2004 Simon Marechal * simon.marechal@thales-security.com */ #include #include "arch.h" #include "misc.h" #include "common.h" #include "formats.h" #include "des.h" #define FORMAT_LABEL "oracle" #define FORMAT_NAME "Oracle" #define ALGORITHM_NAME "oracle" #define BENCHMARK_COMMENT "" #define BENCHMARK_LENGTH -1 #define PLAINTEXT_LENGTH 16 #define BINARY_SIZE 8 #define SALT_SIZE 32 #define CIPHERTEXT_LENGTH (BINARY_SIZE + SALT_SIZE) #define MIN_KEYS_PER_CRYPT 1 #define MAX_KEYS_PER_CRYPT 1 static struct fmt_tests oracle_tests[] = { {"O$SIMON#4F8BC1809CB2AF77", "A"}, {"O$SIMON#183D72325548EF11", "THALES2" }, {"O$SIMON#C4EB3152E17F24A4", "TST" }, {"O$SYSTEM#9EEDFA0AD26C6D52", "THALES" }, {NULL} }; #if ARCH_LITTLE_ENDIAN #define ENDIAN_SHIFT_L << 8 #define ENDIAN_SHIFT_R >> 8 #else #define ENDIAN_SHIFT_L #define ENDIAN_SHIFT_R #endif //stores the ciphertext for value currently being tested static char crypt_key[BINARY_SIZE+1]; static unsigned char cur_salt[128 + 1]; //current salt static unsigned char cur_key[128 + 1]; //current salt static unsigned char deskey[8]; static unsigned char salt_iv[8]; static DES_key_schedule desschedule1; static DES_key_schedule desschedule2; static int salt_length; static int key_length; static int valid(char *ciphertext) { int i; int l; /* * 2 cases * 1 - it comes from the disk, and does not have O$ + salt * 2 - it comes from memory, and has got O$ + salt + # + blah */ if (!memcmp(ciphertext, "O$", 2)) { l = strlen(ciphertext) - PLAINTEXT_LENGTH; if(ciphertext[l-1]!='#') return 0; } else { if(strlen(ciphertext)!=PLAINTEXT_LENGTH) return 0; l = 0; } for (i = l; i < l + PLAINTEXT_LENGTH; i++){ if (!( (('0' <= ciphertext[i])&&(ciphertext[i] <= '9')) || (('a' <= ciphertext[i])&&(ciphertext[i] <= 'f')) || (('A' <= ciphertext[i])&&(ciphertext[i] <= 'F')))) return 0; } return 1; } static void oracle_init(void) { deskey[0] = 0x01; deskey[1] = 0x23; deskey[2] = 0x45; deskey[3] = 0x67; deskey[4] = 0x89; deskey[5] = 0xab; deskey[6] = 0xcd; deskey[7] = 0xef; my_des_set_key(&deskey, &desschedule1); } static void oracle_set_salt(void *salt, int count) { salt_length = 0; memset(salt_iv, 0, 8); while ( (((unsigned short *)cur_salt)[salt_length] = ((unsigned char *)salt)[salt_length] ENDIAN_SHIFT_L )) salt_length++; //this optimization is for Bob the Butcher only /* if(salt_length > 4) { salt_offset = (salt_length & (~3))*2; my_des_ncbc_encrypt(cur_salt, salt_offset, &desschedule1, salt_iv); }*/ } static void oracle_set_key(char *key, int index) { key_length = 0; while( (((unsigned short *)cur_key)[key_length] = key[key_length] ENDIAN_SHIFT_L )) key_length++; } static char *oracle_get_key(int index) { static unsigned char out[PLAINTEXT_LENGTH]; unsigned int i; for(i=0;i