// caller must free b->out if it's not NULL static OAES_RET _do_base64_decode(do_block *b) { OAES_CTX * ctx = NULL; OAES_RET _rc = OAES_RET_SUCCESS; if( NULL == b ) return OAES_RET_ARG1; b->out = NULL; b->out_len = 0; _rc = oaes_base64_decode( (const char *) b->in, b->in_len, b->out, &(b->out_len) ); if( OAES_RET_SUCCESS != _rc ) { fprintf(stderr, "Error: Failed to decrypt.\n"); oaes_free(&ctx); return _rc; } b->out = (uint8_t *) calloc(b->out_len, sizeof(uint8_t)); if( NULL == b->out ) { fprintf(stderr, "Error: Failed to allocate memory.\n"); oaes_free(&ctx); return OAES_RET_MEM; } _rc = oaes_base64_decode( (const char *) b->in, b->in_len, b->out, &(b->out_len) ); return _rc; }
// caller must free b->out if it's not NULL static OAES_RET _do_aes_decrypt(do_block *b) { OAES_CTX * ctx = NULL; OAES_RET _rc = OAES_RET_SUCCESS; if( NULL == b ) return OAES_RET_ARG1; ctx = oaes_alloc(); if( NULL == ctx ) { fprintf(stderr, "Error: Failed to initialize OAES.\n"); return OAES_RET_MEM; } if( _is_ecb ) if( OAES_RET_SUCCESS != oaes_set_option( ctx, OAES_OPTION_ECB, NULL ) ) fprintf(stderr, "Error: Failed to set OAES options.\n"); oaes_key_import_data( ctx, _key_data, _key_data_len ); b->out = NULL; b->out_len = 0; _rc = oaes_decrypt( ctx, b->in, b->in_len, b->out, &(b->out_len) ); if( OAES_RET_SUCCESS != _rc ) { fprintf(stderr, "Error: Failed to decrypt.\n"); oaes_free(&ctx); return _rc; } b->out = (uint8_t *) calloc(b->out_len, sizeof(uint8_t)); if( NULL == b->out ) { fprintf(stderr, "Error: Failed to allocate memory.\n"); oaes_free(&ctx); return OAES_RET_MEM; } _rc = oaes_decrypt( ctx, b->in, b->in_len, b->out, &(b->out_len) ); if( OAES_RET_SUCCESS != oaes_free(&ctx) ) fprintf(stderr, "Error: Failed to uninitialize OAES.\n"); return _rc; }
~AES() { if( !m_ctx ) return; OAES_RET ret = oaes_free( &m_ctx ); if( ret != OAES_RET_SUCCESS ) { LOG_PRINTF_ERROR(( "oaes_free() failed: %d", (int)ret )); } }
int main(int argc, char** argv) { size_t _i = 0, _j = 0; size_t _read_len = 0; char *_file_in = NULL, *_file_out = NULL, *_file_k = NULL; int _op = 0; FILE *_f_in = stdin, *_f_out = stdout, *_f_k = NULL; do_block _b[OAES_THREADS]; fprintf( stderr, "\n" "*******************************************************************************\n" "* OpenAES %-10s *\n" "* Copyright (c) 2013, Nabil S. Al Ramli, www.nalramli.com *\n" "*******************************************************************************\n\n", OAES_VERSION ); // pad the key for( _j = 0; _j < 32; _j++ ) _key_data[_j] = _j + 1; if( argc < 2 ) { usage( argv[0] ); return EXIT_FAILURE; } if( 0 == strcmp( argv[1], "gen-key" ) ) { OAES_CTX *_oaes = NULL; uint8_t _buf[16384]; size_t _buf_len = sizeof(_buf); OAES_RET _rc = OAES_RET_SUCCESS; _i++; _i++; // key_length _i++; // key_file if( _i >= argc ) { fprintf( stderr, "Error: No value specified for '%s'.\n", argv[1] ); usage( argv[0] ); return EXIT_FAILURE; } _key_data_len = atoi( argv[_i - 1] ); _file_k = argv[_i]; _oaes = oaes_alloc(); if( NULL == _oaes ) { fprintf(stderr, "Error: Failed to initialize OAES.\n"); return OAES_RET_MEM; } switch( _key_data_len ) { case 128: _rc = oaes_key_gen_128(_oaes); break; case 192: _rc = oaes_key_gen_192(_oaes); break; case 256: _rc = oaes_key_gen_256(_oaes); break; default: fprintf( stderr, "Error: Invalid value [%s] specified for '%s'.\n", argv[_i - 1], argv[_i - 2] ); oaes_free(&_oaes); return EXIT_FAILURE; } if( OAES_RET_SUCCESS != _rc ) { fprintf( stderr, "Error: Failed to generate OAES %lu bit key.\n", _key_data_len ); oaes_free(&_oaes); return EXIT_FAILURE; } if( OAES_RET_SUCCESS != oaes_key_export(_oaes, _buf, &_buf_len) ) { fprintf( stderr, "Error: Failed to retrieve key length %lu.\n", _key_data_len ); oaes_free(&_oaes); return EXIT_FAILURE; } oaes_free(&_oaes); if( 0 == access(_file_k, 00) ) { fprintf(stderr, "Error: '%s' already exists.\n", _file_k); return EXIT_FAILURE; } _f_k = fopen(_file_k, "wb"); if( NULL == _f_k ) { fprintf(stderr, "Error: Failed to open '%s' for writing.\n", _file_k); return EXIT_FAILURE; } fwrite(_buf, sizeof(uint8_t), _buf_len, _f_k); fclose(_f_k); return EXIT_SUCCESS; } else if( 0 == strcmp( argv[1], "base64-enc" ) ) { _op = 0; _read_len = OAES_BASE64_LEN_ENC; } else if( 0 == strcmp( argv[1], "base64-dec" ) ) { _op = 1; _read_len = OAES_BASE64_LEN_DEC; } else if( 0 == strcmp( argv[1], "aes-enc" ) ) { _op = 2; _read_len = OAES_AES_LEN_ENC; } else if( 0 == strcmp( argv[1], "aes-dec" ) ) { _op = 3; _read_len = OAES_AES_LEN_DEC; } else { fprintf(stderr, "Error: Unknown command '%s'.", argv[1]); usage( argv[0] ); return EXIT_FAILURE; } for( _i = 2; _i < argc; _i++ ) { int _found = 0; if( 0 == strcmp( argv[_i], "--ecb" ) ) { _found = 1; _is_ecb = 1; } if( 0 == strcmp( argv[_i], "--key" ) ) { uint8_t *_buf = NULL; size_t _buf_len = 0; _found = 1; _i++; // base64_encoded_key_data if( _i >= argc ) { fprintf(stderr, "Error: No value specified for '%s'.\n", argv[_i - 1]); usage( argv[0] ); return EXIT_FAILURE; } if( oaes_base64_decode(argv[_i], strlen(argv[_i]), NULL, &_buf_len) ) { fprintf(stderr, "Error: Invalid value for '%s'.\n", argv[_i - 1]); usage( argv[0] ); return EXIT_FAILURE; } _buf = (uint8_t *) calloc(_buf_len, sizeof(uint8_t)); if( NULL == _buf ) { fprintf(stderr, "Error: Failed to allocate memory.\n"); return EXIT_FAILURE; } if( oaes_base64_decode(argv[_i], strlen(argv[_i]), _buf, &_buf_len) ) { free(_buf); fprintf(stderr, "Error: Invalid value for '%s'.\n", argv[_i - 1]); usage( argv[0] ); return EXIT_FAILURE; } _key_data_len = _buf_len; if( 16 >= _key_data_len ) _key_data_len = 16; else if( 24 >= _key_data_len ) _key_data_len = 24; else _key_data_len = 32; memcpy(_key_data, _buf, __min(32, _buf_len)); for( _j = 0; _j < _buf_len; _j++ ) { _key_data[_j % 32] ^= _buf[_j]; } free(_buf); } if( 0 == strcmp( argv[_i], "--key-file" ) ) { OAES_CTX *_ctx = NULL; uint8_t _buf[16384]; size_t _read = 0; _found = 1; _i++; // key_file if( _i >= argc ) { fprintf(stderr, "Error: No value specified for '%s'.\n", argv[_i - 1]); usage( argv[0] ); return EXIT_FAILURE; } _file_k = argv[_i]; _ctx = oaes_alloc(); if( NULL == _ctx ) { fprintf(stderr, "Error: Failed to initialize OAES.\n"); return OAES_RET_MEM; } _f_k = fopen(_file_k, "rb"); if( NULL == _f_k ) { fprintf(stderr, "Error: Failed to open '%s' for reading.\n", _file_k); oaes_free(&_ctx); return EXIT_FAILURE; } _read = fread(_buf, sizeof(uint8_t), sizeof(_buf), _f_k); fclose(_f_k); if( OAES_RET_SUCCESS != oaes_key_import(_ctx, _buf, _read) ) { fprintf(stderr, "Error: Failed to import '%s'.\n", _file_k); oaes_free(&_ctx); return EXIT_FAILURE; } _key_data_len = sizeof(_key_data); if( OAES_RET_SUCCESS != oaes_key_export_data(_ctx, _key_data, &_key_data_len) ) { fprintf(stderr, "Error: Failed to export '%s' data.\n", _file_k); oaes_free(&_ctx); return EXIT_FAILURE; } oaes_free(&_ctx); } if( 0 == strcmp( argv[_i], "--in" ) ) { _found = 1; _i++; // path_in if( _i >= argc ) { fprintf(stderr, "Error: No value specified for '%s'.\n", argv[_i - 1]); usage( argv[0] ); return EXIT_FAILURE; } _file_in = argv[_i]; } if( 0 == strcmp( argv[_i], "--out" ) ) { _found = 1; _i++; // path_out if( _i >= argc ) { fprintf(stderr, "Error: No value specified for '%s'.\n", argv[_i - 1]); usage( argv[0] ); return EXIT_FAILURE; } _file_out = argv[_i]; } if( 0 == _found ) { fprintf(stderr, "Error: Invalid option '%s'.\n", argv[_i]); usage( argv[0] ); return EXIT_FAILURE; } } switch(_op) { case 0: case 1: break; case 2: case 3: if( 0 == _key_data_len ) { char _key_data_ent[8193] = ""; uint8_t *_buf = NULL; size_t _buf_len = 0; fprintf(stderr, "Enter base64-encoded key: "); scanf("%8192s", _key_data_ent); if( oaes_base64_decode( _key_data_ent, strlen(_key_data_ent), NULL, &_buf_len ) ) { fprintf(stderr, "Error: Invalid value for '%s'.\n", argv[_i - 1]); usage( argv[0] ); return EXIT_FAILURE; } _buf = (uint8_t *) calloc(_buf_len, sizeof(uint8_t)); if( NULL == _buf ) { fprintf(stderr, "Error: Failed to allocate memory.\n"); return EXIT_FAILURE; } if( oaes_base64_decode( _key_data_ent, strlen(_key_data_ent), _buf, &_buf_len ) ) { free(_buf); fprintf(stderr, "Error: Invalid value for '%s'.\n", argv[_i - 1]); usage( argv[0] ); return EXIT_FAILURE; } _key_data_len = _buf_len; if( 16 >= _key_data_len ) _key_data_len = 16; else if( 24 >= _key_data_len ) _key_data_len = 24; else _key_data_len = 32; memcpy(_key_data, _buf, __min(32, _buf_len)); for( _j = 0; _j < _buf_len; _j++ ) { _key_data[_j % 32] ^= _buf[_j]; } free(_buf); } break; default: break; } if( _file_in ) { _f_in = fopen(_file_in, "rb"); if( NULL == _f_in ) { fprintf(stderr, "Error: Failed to open '%s' for reading.\n", _file_in); return EXIT_FAILURE; } } else { if( setmode(fileno(stdin), 0x8000) < 0 ) fprintf(stderr,"Error: Failed in setmode().\n"); _f_in = stdin; } if( _file_out ) { if( 0 == access(_file_out, 00) ) { fprintf(stderr, "Error: '%s' already exists.\n", _file_out); return EXIT_FAILURE; } _f_out = fopen(_file_out, "wb"); if( NULL == _f_out ) { fprintf(stderr, "Error: Failed to open '%s' for writing.\n", _file_out); if( _file_in ) fclose(_f_in); return EXIT_FAILURE; } } else { if( setmode(fileno(stdout), 0x8000) < 0 ) fprintf(stderr, "Error: Failed in setmode().\n"); _f_out = stdout; } _i = 0; while( _b[_i].in_len = fread(_b[_i].in, sizeof(uint8_t), _read_len, _f_in) ) { switch(_op) { case 0: _b[_i].id = start_thread(_do_base64_encode, &(_b[_i])); if( NULL == _b[_i].id ) fprintf(stderr, "Error: Failed to start encryption.\n"); break; case 1: _b[_i].id = start_thread(_do_base64_decode, &(_b[_i])); if( NULL == _b[_i].id ) fprintf(stderr, "Error: Failed to start decryption.\n"); break; case 2: _b[_i].id = start_thread(_do_aes_encrypt, &(_b[_i])); if( NULL == _b[_i].id ) fprintf(stderr, "Error: Failed to start encryption.\n"); break; case 3: _b[_i].id = start_thread(_do_aes_decrypt, &(_b[_i])); if( NULL == _b[_i].id ) fprintf(stderr, "Error: Failed to start decryption.\n"); break; default: break; } if( OAES_THREADS == _i + 1 ) { for( _j = 0; _j < OAES_THREADS; _j++ ) { if( _b[_j].id ) { join_thread(_b[_j].id); _b[_j].id = 0; if( _b[_j].out ) { fwrite(_b[_j].out, sizeof(uint8_t), _b[_j].out_len, _f_out); free(_b[_j].out); _b[_j].out = NULL; } } } } _i = (_i + 1) % OAES_THREADS; } for( _j = 0; _j < _i; _j++ ) { if( _b[_j].id ) { join_thread(_b[_j].id); _b[_j].id = 0; if( _b[_j].out ) { fwrite(_b[_j].out, sizeof(uint8_t), _b[_j].out_len, _f_out); free(_b[_j].out); _b[_j].out = NULL; } } } if( _file_in ) fclose(_f_in); if( _file_out ) fclose(_f_out); fprintf(stderr, "done.\n"); return (EXIT_SUCCESS); }
void cryptonight_hash(const char* input, char* output, uint32_t len) { uint8_t long_state[MEMORY]; union cn_slow_hash_state state; uint8_t text[INIT_SIZE_BYTE]; uint8_t a[AES_BLOCK_SIZE]; uint8_t b[AES_BLOCK_SIZE]; uint8_t c[AES_BLOCK_SIZE]; uint8_t d[AES_BLOCK_SIZE]; size_t i, j; uint8_t aes_key[AES_KEY_SIZE]; OAES_CTX* aes_ctx; hash_process(&state.hs, (const uint8_t*) input, len); memcpy(text, state.init, INIT_SIZE_BYTE); memcpy(aes_key, state.hs.b, AES_KEY_SIZE); aes_ctx = oaes_alloc(); oaes_key_import_data(aes_ctx, aes_key, AES_KEY_SIZE); for (i = 0; i < MEMORY / INIT_SIZE_BYTE; i++) { for (j = 0; j < INIT_SIZE_BLK; j++) { oaes_pseudo_encrypt_ecb(aes_ctx, &text[AES_BLOCK_SIZE * j]); } memcpy(&long_state[i * INIT_SIZE_BYTE], text, INIT_SIZE_BYTE); } for (i = 0; i < 16; i++) { a[i] = state.k[i] ^ state.k[32 + i]; b[i] = state.k[16 + i] ^ state.k[48 + i]; } for (i = 0; i < ITER / 2; i++) { /* Dependency chain: address -> read value ------+ * written value <-+ hard function (AES or MUL) <+ * next address <-+ */ /* Iteration 1 */ j = e2i(a, MEMORY / AES_BLOCK_SIZE); copy_block(c, &long_state[j * AES_BLOCK_SIZE]); oaes_encryption_round(a, c); xor_blocks(b, c); swap_blocks(b, c); copy_block(&long_state[j * AES_BLOCK_SIZE], c); assert(j == e2i(a, MEMORY / AES_BLOCK_SIZE)); swap_blocks(a, b); /* Iteration 2 */ j = e2i(a, MEMORY / AES_BLOCK_SIZE); copy_block(c, &long_state[j * AES_BLOCK_SIZE]); mul(a, c, d); sum_half_blocks(b, d); swap_blocks(b, c); xor_blocks(b, c); copy_block(&long_state[j * AES_BLOCK_SIZE], c); swap_blocks(a, b); } memcpy(text, state.init, INIT_SIZE_BYTE); oaes_key_import_data(aes_ctx, &state.hs.b[32], AES_KEY_SIZE); for (i = 0; i < MEMORY / INIT_SIZE_BYTE; i++) { for (j = 0; j < INIT_SIZE_BLK; j++) { xor_blocks(&text[j * AES_BLOCK_SIZE], &long_state[i * INIT_SIZE_BYTE + j * AES_BLOCK_SIZE]); oaes_pseudo_encrypt_ecb(aes_ctx, &text[j * AES_BLOCK_SIZE]); } } memcpy(state.init, text, INIT_SIZE_BYTE); hash_permutation(&state.hs); /*memcpy(hash, &state, 32);*/ extra_hashes[state.hs.b[0] & 3](&state, 200, output); oaes_free(&aes_ctx); }
void cryptonight_hash_ctx_aes_ni(void* output, const void* input, size_t len, struct cryptonight_ctx* ctx) { hash_process(&ctx->state.hs, (const uint8_t*) input, len); ctx->aes_ctx = (oaes_ctx*) oaes_alloc(); size_t i, j; memcpy(ctx->text, ctx->state.init, INIT_SIZE_BYTE); oaes_key_import_data(ctx->aes_ctx, ctx->state.hs.b, AES_KEY_SIZE); for (i = 0; likely(i < MEMORY); i += INIT_SIZE_BYTE) { fast_aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 0], ctx->aes_ctx->key->exp_data); fast_aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 1], ctx->aes_ctx->key->exp_data); fast_aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 2], ctx->aes_ctx->key->exp_data); fast_aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 3], ctx->aes_ctx->key->exp_data); fast_aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 4], ctx->aes_ctx->key->exp_data); fast_aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 5], ctx->aes_ctx->key->exp_data); fast_aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 6], ctx->aes_ctx->key->exp_data); fast_aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 7], ctx->aes_ctx->key->exp_data); memcpy(&ctx->long_state[i], ctx->text, INIT_SIZE_BYTE); } xor_blocks_dst(&ctx->state.k[0], &ctx->state.k[32], ctx->a); xor_blocks_dst(&ctx->state.k[16], &ctx->state.k[48], ctx->b); for (i = 0; likely(i < ITER / 4); ++i) { /* Dependency chain: address -> read value ------+ * written value <-+ hard function (AES or MUL) <+ * next address <-+ */ /* Iteration 1 */ j = e2i(ctx->a); fast_aesb_single_round(&ctx->long_state[j], ctx->c, ctx->a); xor_blocks_dst(ctx->c, ctx->b, &ctx->long_state[j]); /* Iteration 2 */ mul_sum_xor_dst(ctx->c, ctx->a, &ctx->long_state[e2i(ctx->c)]); /* Iteration 3 */ j = e2i(ctx->a); fast_aesb_single_round(&ctx->long_state[j], ctx->b, ctx->a); xor_blocks_dst(ctx->b, ctx->c, &ctx->long_state[j]); /* Iteration 4 */ mul_sum_xor_dst(ctx->b, ctx->a, &ctx->long_state[e2i(ctx->b)]); } memcpy(ctx->text, ctx->state.init, INIT_SIZE_BYTE); oaes_key_import_data(ctx->aes_ctx, &ctx->state.hs.b[32], AES_KEY_SIZE); for (i = 0; likely(i < MEMORY); i += INIT_SIZE_BYTE) { xor_blocks(&ctx->text[0 * AES_BLOCK_SIZE], &ctx->long_state[i + 0 * AES_BLOCK_SIZE]); fast_aesb_pseudo_round_mut(&ctx->text[0 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data); xor_blocks(&ctx->text[1 * AES_BLOCK_SIZE], &ctx->long_state[i + 1 * AES_BLOCK_SIZE]); fast_aesb_pseudo_round_mut(&ctx->text[1 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data); xor_blocks(&ctx->text[2 * AES_BLOCK_SIZE], &ctx->long_state[i + 2 * AES_BLOCK_SIZE]); fast_aesb_pseudo_round_mut(&ctx->text[2 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data); xor_blocks(&ctx->text[3 * AES_BLOCK_SIZE], &ctx->long_state[i + 3 * AES_BLOCK_SIZE]); fast_aesb_pseudo_round_mut(&ctx->text[3 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data); xor_blocks(&ctx->text[4 * AES_BLOCK_SIZE], &ctx->long_state[i + 4 * AES_BLOCK_SIZE]); fast_aesb_pseudo_round_mut(&ctx->text[4 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data); xor_blocks(&ctx->text[5 * AES_BLOCK_SIZE], &ctx->long_state[i + 5 * AES_BLOCK_SIZE]); fast_aesb_pseudo_round_mut(&ctx->text[5 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data); xor_blocks(&ctx->text[6 * AES_BLOCK_SIZE], &ctx->long_state[i + 6 * AES_BLOCK_SIZE]); fast_aesb_pseudo_round_mut(&ctx->text[6 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data); xor_blocks(&ctx->text[7 * AES_BLOCK_SIZE], &ctx->long_state[i + 7 * AES_BLOCK_SIZE]); fast_aesb_pseudo_round_mut(&ctx->text[7 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data); } memcpy(ctx->state.init, ctx->text, INIT_SIZE_BYTE); hash_permutation(&ctx->state.hs); /*memcpy(hash, &state, 32);*/ extra_hashes[ctx->state.hs.b[0] & 3](&ctx->state, 200, output); oaes_free((OAES_CTX **) &ctx->aes_ctx); }
/* M.close(aes_ctx) releases resources associated with AES context. */ static int api_close( lua_State *L) { OAES_CTX *ctx = checkctx( L, 1); oaes_free( & ctx); return 0; }
int main(int argc, char** argv) { size_t _i; OAES_CTX * ctx = NULL; uint8_t *_encbuf, *_decbuf, *_key_data = NULL, *_bin_data = NULL; size_t _encbuf_len, _decbuf_len, _buf_len; size_t _key_data_len = 0, _bin_data_len = 0; char *_buf; short _is_ecb = 0, _is_bin = 0; char * _text = NULL, * _key_text = NULL; int _key_len = 128; uint8_t _iv[OAES_BLOCK_SIZE] = ""; uint8_t _pad = 0; if( argc < 2 ) { usage( argv[0] ); return EXIT_FAILURE; } for( _i = 1; _i < argc; _i++ ) { int _found = 0; if( 0 == strcmp( argv[_i], "-nostep" ) ) { _found = 1; _is_step = 0; } if( 0 == strcmp( argv[_i], "-ecb" ) ) { _found = 1; _is_ecb = 1; } if( 0 == strcmp( argv[_i], "-bin" ) ) { _found = 1; _is_bin = 1; } if( 0 == strcmp( argv[_i], "-key" ) ) { _found = 1; _i++; // len if( _i >= argc ) { printf("Error: No value specified for '-%s'.\n", "key"); usage( argv[0] ); return EXIT_FAILURE; } _key_len = atoi( argv[_i] ); switch( _key_len ) { case 128: case 192: case 256: break; default: _key_text = argv[_i]; if( to_binary( NULL, &_key_data_len, _key_text ) ) { printf( "Error: Invalid value [%s] specified for '-%s'.\n", argv[_i], "key" ); return EXIT_FAILURE; } switch( _key_data_len ) { case 16: case 24: case 32: break; default: printf("Error: key_data [%s] specified for '-%s' has an invalid " "size.\n", argv[_i], "key"); usage( argv[0] ); return EXIT_FAILURE; } } } if( 0 == _found ) { if( _text ) { printf("Error: Invalid option '%s'.\n", argv[_i]); usage( argv[0] ); return EXIT_FAILURE; } else { _text = argv[_i]; if( _is_bin && to_binary( NULL, &_bin_data_len, _text ) ) { printf( "Error: Invalid value [%s] specified for '-%s'.\n", argv[_i], "bin" ); return EXIT_FAILURE; } } } } if( NULL == _text ) { usage( argv[0] ); return EXIT_FAILURE; } if( _is_step ) printf( "\nEnabling step mode, press Return to step.\n\n" ); if( _is_bin ) { _bin_data = (uint8_t *) calloc(_bin_data_len, sizeof(uint8_t)); if( NULL == _bin_data ) { printf( "Error: Failed to allocate memory.\n" ); return EXIT_FAILURE; } if( to_binary( _bin_data, &_bin_data_len, _text ) ) { printf( "Error: Could not load data [%s].\n", _text); free( _bin_data ); return EXIT_FAILURE; } } else { oaes_sprintf( NULL, &_buf_len, (const uint8_t *)_text, strlen(_text)); _buf = (char *) calloc(_buf_len, sizeof(char)); printf( "\n***** plaintext *****\n" ); if( _buf ) { oaes_sprintf( _buf, &_buf_len, (const uint8_t *)_text, strlen( _text ) ); printf( "%s", _buf ); } printf( "\n**********************\n" ); free( _buf ); } ctx = oaes_alloc(); if( NULL == ctx ) { printf("Error: Failed to initialize OAES.\n"); if( _bin_data ) free( _bin_data ); return EXIT_FAILURE; } if( OAES_RET_SUCCESS != oaes_set_option( ctx, OAES_OPTION_STEP_ON, step_cb ) ) printf("Error: Failed to set OAES options.\n"); if( _is_ecb ) if( OAES_RET_SUCCESS != oaes_set_option( ctx, OAES_OPTION_ECB, NULL ) ) printf("Error: Failed to set OAES options.\n"); if( _key_text ) { _key_data = (uint8_t *) calloc(_key_data_len, sizeof(uint8_t)); if( NULL == _key_data ) { printf( "Error: Failed to allocate memory.\n" ); if( _bin_data ) free( _bin_data ); return EXIT_FAILURE; } if( to_binary( _key_data, &_key_data_len, _key_text ) ) { printf( "Error: Could not load key [%s].\n", _key_text); free( _key_data ); return EXIT_FAILURE; } oaes_key_import_data( ctx, _key_data, _key_data_len ); } else switch( _key_len ) { case 128: if( OAES_RET_SUCCESS != oaes_key_gen_128(ctx) ) printf("Error: Failed to generate OAES %d bit key.\n", _key_len); break; case 192: if( OAES_RET_SUCCESS != oaes_key_gen_192(ctx) ) printf("Error: Failed to generate OAES %d bit key.\n", _key_len); break; case 256: if( OAES_RET_SUCCESS != oaes_key_gen_256(ctx) ) printf("Error: Failed to generate OAES %d bit key.\n", _key_len); break; default: break; } if( _bin_data ) { if( OAES_RET_SUCCESS != oaes_encrypt( ctx, _bin_data, _bin_data_len, NULL, &_encbuf_len, NULL, NULL ) ) printf("Error: Failed to retrieve required buffer size for encryption.\n"); _encbuf = (uint8_t *) calloc(_encbuf_len, sizeof(uint8_t)); if( NULL == _encbuf ) { printf( "Error: Failed to allocate memory.\n" ); if( _key_data ) free( _key_data ); free( _bin_data ); return EXIT_FAILURE; } printf( "\n" ); if( OAES_RET_SUCCESS != oaes_encrypt( ctx, _bin_data, _bin_data_len, _encbuf, &_encbuf_len, _iv, &_pad ) ) printf("Error: Encryption failed.\n"); printf( "\n**********************\n\n" ); } else { if( OAES_RET_SUCCESS != oaes_encrypt( ctx, (const uint8_t *)_text, strlen( _text ), NULL, &_encbuf_len, NULL, NULL ) ) printf("Error: Failed to retrieve required buffer size for encryption.\n"); _encbuf = (uint8_t *) calloc(_encbuf_len, sizeof(uint8_t)); if( NULL == _encbuf ) { printf( "Error: Failed to allocate memory.\n" ); if( _key_data ) free( _key_data ); return EXIT_FAILURE; } printf( "\n" ); if( OAES_RET_SUCCESS != oaes_encrypt( ctx, (const uint8_t *)_text, strlen( _text ), _encbuf, &_encbuf_len, _iv, &_pad )) printf("Error: Encryption failed.\n"); printf( "\n**********************\n\n" ); } if( OAES_RET_SUCCESS != oaes_decrypt( ctx, _encbuf, _encbuf_len, NULL, &_decbuf_len, NULL, NULL ) ) printf("Error: Failed to retrieve required buffer size for encryption.\n"); _decbuf = (uint8_t *) calloc(_decbuf_len, sizeof(uint8_t)); if( NULL == _decbuf ) { printf( "Error: Failed to allocate memory.\n" ); if( _key_data ) free( _key_data ); if( _bin_data ) free( _bin_data ); free( _encbuf ); return EXIT_FAILURE; } if( OAES_RET_SUCCESS != oaes_decrypt( ctx, _encbuf, _encbuf_len, _decbuf, &_decbuf_len, _iv, _pad ) ) printf("Error: Decryption failed.\n"); if( OAES_RET_SUCCESS != oaes_free( &ctx ) ) printf("Error: Failed to uninitialize OAES.\n"); oaes_sprintf( NULL, &_buf_len, _encbuf, _encbuf_len ); _buf = (char *) calloc(_buf_len, sizeof(char)); printf( "\n***** cyphertext *****\n" ); if( _buf ) { oaes_sprintf( _buf, &_buf_len, _encbuf, _encbuf_len ); printf( "%s", _buf ); } printf( "\n**********************\n" ); free( _buf ); oaes_sprintf( NULL, &_buf_len, _decbuf, _decbuf_len ); _buf = (char *) calloc(_buf_len, sizeof(char)); printf( "\n***** plaintext *****\n" ); if( _buf ) { oaes_sprintf( _buf, &_buf_len, _decbuf, _decbuf_len ); printf( "%s", _buf ); } printf( "\n**********************\n\n" ); free( _buf ); free( _encbuf ); free( _decbuf ); if( _key_data ) free( _key_data ); if( _bin_data ) free( _bin_data ); return (EXIT_SUCCESS); }
int main(int argc, char** argv) { size_t _i; OAES_CTX * ctx = NULL; uint8_t *_encbuf, *_decbuf; size_t _encbuf_len, _decbuf_len, _buf_len; char *_buf; short _is_ecb = 0; char * _text = NULL; int _key_len = 128; if( argc < 2 ) { usage( argv[0] ); return EXIT_FAILURE; } for( _i = 1; _i < argc; _i++ ) { int _found = 0; if( 0 == strcmp( argv[_i], "-ecb" ) ) { _found = 1; _is_ecb = 1; } if( 0 == strcmp( argv[_i], "-key" ) ) { _found = 1; _i++; // len if( _i >= argc ) { printf("Error: No value specified for '-%s'.\n", "key"); usage( argv[0] ); return EXIT_FAILURE; } _key_len = atoi( argv[_i] ); switch( _key_len ) { case 128: case 192: case 256: break; default: printf("Error: Invalid value [%d] specified for '-%s'.\n", _key_len, "key"); usage( argv[0] ); return EXIT_FAILURE; } } if( 0 == _found ) { if( _text ) { printf("Error: Invalid option '%s'.\n", argv[_i]); usage( argv[0] ); return EXIT_FAILURE; } else { _text = (char *) calloc(strlen( argv[_i] ) + 1, sizeof(char)); if( NULL == _text ) { printf("Error: Failed to allocate memory.\n", argv[_i]); return EXIT_FAILURE; } strcpy( _text, argv[_i] ); } } } if( NULL == _text ) { usage( argv[0] ); return EXIT_FAILURE; } oaes_sprintf( NULL, &_buf_len, (const uint8_t *)_text, strlen( _text ) ); _buf = (char *) calloc(_buf_len, sizeof(char)); printf( "\n***** plaintext *****\n" ); if( _buf ) { oaes_sprintf( _buf, &_buf_len, (const uint8_t *)_text, strlen( _text ) ); printf( "%s", _buf ); } printf( "\n**********************\n" ); free( _buf ); ctx = oaes_alloc(); if( NULL == ctx ) { printf("Error: Failed to initialize OAES.\n"); free( _text ); return EXIT_FAILURE; } if( _is_ecb ) if( OAES_RET_SUCCESS != oaes_set_option( ctx, OAES_OPTION_ECB, NULL ) ) printf("Error: Failed to set OAES options.\n"); switch( _key_len ) { case 128: if( OAES_RET_SUCCESS != oaes_key_gen_128(ctx) ) printf("Error: Failed to generate OAES %d bit key.\n", _key_len); break; case 192: if( OAES_RET_SUCCESS != oaes_key_gen_192(ctx) ) printf("Error: Failed to generate OAES %d bit key.\n", _key_len); break; case 256: if( OAES_RET_SUCCESS != oaes_key_gen_256(ctx) ) printf("Error: Failed to generate OAES %d bit key.\n", _key_len); break; default: break; } if( OAES_RET_SUCCESS != oaes_encrypt( ctx, (const uint8_t *)_text, strlen( _text ), NULL, &_encbuf_len ) ) printf("Error: Failed to retrieve required buffer size for encryption.\n"); _encbuf = (uint8_t *) calloc( _encbuf_len, sizeof(uint8_t) ); if( NULL == _encbuf ) { printf( "Error: Failed to allocate memory.\n" ); free( _text ); return EXIT_FAILURE; } if( OAES_RET_SUCCESS != oaes_encrypt( ctx, (const uint8_t *)_text, strlen( _text ), _encbuf, &_encbuf_len ) ) printf("Error: Encryption failed.\n"); if( OAES_RET_SUCCESS != oaes_decrypt( ctx, _encbuf, _encbuf_len, NULL, &_decbuf_len ) ) printf("Error: Failed to retrieve required buffer size for encryption.\n"); _decbuf = (uint8_t *) calloc( _decbuf_len, sizeof(uint8_t) ); if( NULL == _decbuf ) { printf( "Error: Failed to allocate memory.\n" ); free( _text ); free( _encbuf ); return EXIT_FAILURE; } if( OAES_RET_SUCCESS != oaes_decrypt( ctx, _encbuf, _encbuf_len, _decbuf, &_decbuf_len ) ) printf("Error: Decryption failed.\n"); if( OAES_RET_SUCCESS != oaes_free( &ctx ) ) printf("Error: Failed to uninitialize OAES.\n"); oaes_sprintf( NULL, &_buf_len, _encbuf, _encbuf_len ); _buf = (char *) calloc(_buf_len, sizeof(char)); printf( "\n***** cyphertext *****\n" ); if( _buf ) { oaes_sprintf( _buf, &_buf_len, _encbuf, _encbuf_len ); printf( "%s", _buf ); } printf( "\n**********************\n" ); free( _buf ); oaes_sprintf( NULL, &_buf_len, _decbuf, _decbuf_len ); _buf = (char *) calloc(_buf_len, sizeof( char)); printf( "\n***** plaintext *****\n" ); if( _buf ) { oaes_sprintf( _buf, &_buf_len, _decbuf, _decbuf_len ); printf( "%s", _buf ); } printf( "\n**********************\n\n" ); free( _buf ); free( _encbuf ); free( _decbuf ); free( _text ); return (EXIT_SUCCESS); }
void cryptonight_hash(const char* input, char* output, uint32_t len, int variant, uint64_t height) { struct cryptonight_ctx *ctx = alloca(sizeof(struct cryptonight_ctx)); hash_process(&ctx->state.hs, (const uint8_t*) input, len); memcpy(ctx->text, ctx->state.init, INIT_SIZE_BYTE); memcpy(ctx->aes_key, ctx->state.hs.b, AES_KEY_SIZE); ctx->aes_ctx = (oaes_ctx*) oaes_alloc(); size_t i, j; VARIANT1_INIT(); VARIANT2_INIT(ctx->b, ctx->state); VARIANT4_RANDOM_MATH_INIT(ctx->state); oaes_key_import_data(ctx->aes_ctx, ctx->aes_key, AES_KEY_SIZE); for (i = 0; i < MEMORY / INIT_SIZE_BYTE; i++) { for (j = 0; j < INIT_SIZE_BLK; j++) { aesb_pseudo_round(&ctx->text[AES_BLOCK_SIZE * j], &ctx->text[AES_BLOCK_SIZE * j], ctx->aes_ctx->key->exp_data); } memcpy(&ctx->long_state[i * INIT_SIZE_BYTE], ctx->text, INIT_SIZE_BYTE); } for (i = 0; i < 16; i++) { ctx->a[i] = ctx->state.k[i] ^ ctx->state.k[32 + i]; ctx->b[i] = ctx->state.k[16 + i] ^ ctx->state.k[48 + i]; } for (i = 0; i < ITER / 2; i++) { /* Dependency chain: address -> read value ------+ * written value <-+ hard function (AES or MUL) <+ * next address <-+ */ /* Iteration 1 */ j = e2i(ctx->a); aesb_single_round(&ctx->long_state[j * AES_BLOCK_SIZE], ctx->c, ctx->a); VARIANT2_SHUFFLE_ADD(ctx->long_state, j * AES_BLOCK_SIZE, ctx->a, ctx->b, ctx->c); xor_blocks_dst(ctx->c, ctx->b, &ctx->long_state[j * AES_BLOCK_SIZE]); VARIANT1_1((uint8_t*)&ctx->long_state[j * AES_BLOCK_SIZE]); /* Iteration 2 */ j = e2i(ctx->c); uint64_t* dst = (uint64_t*)&ctx->long_state[j * AES_BLOCK_SIZE]; uint64_t t[2]; t[0] = dst[0]; t[1] = dst[1]; VARIANT2_INTEGER_MATH(t, ctx->c); copy_block(ctx->a1, ctx->a); VARIANT4_RANDOM_MATH(ctx->a, t, r, ctx->b, ctx->b + AES_BLOCK_SIZE); uint64_t hi; uint64_t lo = mul128(((uint64_t*)ctx->c)[0], t[0], &hi); VARIANT2_2(); VARIANT2_SHUFFLE_ADD(ctx->long_state, j * AES_BLOCK_SIZE, ctx->a1, ctx->b, ctx->c); ((uint64_t*)ctx->a)[0] += hi; ((uint64_t*)ctx->a)[1] += lo; dst[0] = ((uint64_t*)ctx->a)[0]; dst[1] = ((uint64_t*)ctx->a)[1]; ((uint64_t*)ctx->a)[0] ^= t[0]; ((uint64_t*)ctx->a)[1] ^= t[1]; VARIANT1_2((uint8_t*)&ctx->long_state[j * AES_BLOCK_SIZE]); copy_block(ctx->b + AES_BLOCK_SIZE, ctx->b); copy_block(ctx->b, ctx->c); } memcpy(ctx->text, ctx->state.init, INIT_SIZE_BYTE); oaes_key_import_data(ctx->aes_ctx, &ctx->state.hs.b[32], AES_KEY_SIZE); for (i = 0; i < MEMORY / INIT_SIZE_BYTE; i++) { for (j = 0; j < INIT_SIZE_BLK; j++) { xor_blocks(&ctx->text[j * AES_BLOCK_SIZE], &ctx->long_state[i * INIT_SIZE_BYTE + j * AES_BLOCK_SIZE]); aesb_pseudo_round(&ctx->text[j * AES_BLOCK_SIZE], &ctx->text[j * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data); } } memcpy(ctx->state.init, ctx->text, INIT_SIZE_BYTE); hash_permutation(&ctx->state.hs); /*memcpy(hash, &state, 32);*/ extra_hashes[ctx->state.hs.b[0] & 3](&ctx->state, 200, output); oaes_free((OAES_CTX **) &ctx->aes_ctx); }
void cn_slow_hash(const void *data, size_t length, char *hash) { uint8_t long_state[MEMORY]; union cn_slow_hash_state state; uint8_t text[INIT_SIZE_BYTE]; uint8_t a[AES_BLOCK_SIZE]; uint8_t b[AES_BLOCK_SIZE]; uint8_t c[AES_BLOCK_SIZE]; uint8_t d[AES_BLOCK_SIZE]; size_t i, j; uint8_t aes_key[AES_KEY_SIZE]; oaes_ctx *aes_ctx; hash_process(&state.hs, data, length); memcpy(text, state.init, INIT_SIZE_BYTE); memcpy(aes_key, state.hs.b, AES_KEY_SIZE); aes_ctx = (oaes_ctx *) oaes_alloc(); oaes_key_import_data(aes_ctx, aes_key, AES_KEY_SIZE); for (i = 0; i < MEMORY / INIT_SIZE_BYTE; i++) { for (j = 0; j < INIT_SIZE_BLK; j++) { aesb_pseudo_round(&text[AES_BLOCK_SIZE * j], &text[AES_BLOCK_SIZE * j], aes_ctx->key->exp_data); } memcpy(&long_state[i * INIT_SIZE_BYTE], text, INIT_SIZE_BYTE); } for (i = 0; i < 16; i++) { a[i] = state.k[ i] ^ state.k[32 + i]; b[i] = state.k[16 + i] ^ state.k[48 + i]; } for (i = 0; i < ITER / 2; i++) { /* Dependency chain: address -> read value ------+ * written value <-+ hard function (AES or MUL) <+ * next address <-+ */ /* Iteration 1 */ j = e2i(a, MEMORY / AES_BLOCK_SIZE); copy_block(c, &long_state[j * AES_BLOCK_SIZE]); aesb_single_round(c, c, a); xor_blocks(b, c); swap_blocks(b, c); copy_block(&long_state[j * AES_BLOCK_SIZE], c); //assert(j == e2i(a, MEMORY / AES_BLOCK_SIZE)); swap_blocks(a, b); /* Iteration 2 */ j = e2i(a, MEMORY / AES_BLOCK_SIZE); copy_block(c, &long_state[j * AES_BLOCK_SIZE]); mul(a, c, d); sum_half_blocks(b, d); swap_blocks(b, c); xor_blocks(b, c); copy_block(&long_state[j * AES_BLOCK_SIZE], c); //assert(j == e2i(a, MEMORY / AES_BLOCK_SIZE)); swap_blocks(a, b); } memcpy(text, state.init, INIT_SIZE_BYTE); oaes_key_import_data(aes_ctx, &state.hs.b[32], AES_KEY_SIZE); for (i = 0; i < MEMORY / INIT_SIZE_BYTE; i++) { for (j = 0; j < INIT_SIZE_BLK; j++) { xor_blocks(&text[j * AES_BLOCK_SIZE], &long_state[i * INIT_SIZE_BYTE + j * AES_BLOCK_SIZE]); aesb_pseudo_round(&text[AES_BLOCK_SIZE * j], &text[AES_BLOCK_SIZE * j], aes_ctx->key->exp_data); } } memcpy(state.init, text, INIT_SIZE_BYTE); hash_permutation(&state.hs); extra_hashes[state.hs.b[0] & 3](&state, 200, hash); oaes_free((OAES_CTX **) &aes_ctx); }