void bitclient_generateTxHash(uint32 nonce1, uint32 userExtraNonceLength, uint8* userExtraNonce, uint32 coinBase1Length, uint8* coinBase1, uint32 coinBase2Length, uint8* coinBase2, uint8* txHash) { stream_t* streamTXData = streamEx_fromDynamicMemoryRange(1024*32); stream_writeData(streamTXData, coinBase1, coinBase1Length); stream_writeData(streamTXData, &nonce1, 4); stream_writeData(streamTXData, userExtraNonce, userExtraNonceLength); stream_writeData(streamTXData, coinBase2, coinBase2Length); sint32 transactionDataLength = 0; uint8* transactionData = (uint8*)streamEx_map(streamTXData, &transactionDataLength); // special case, we can use the hash of the transaction #if 0 int i; printf("Merkle:\n"); for(i=0; i < transactionDataLength; i++){ printf("%2.2x ", transactionData[i]); } printf("\n"); #endif uint8 hashOut[32]; sha256_context sctx; sha256_starts(&sctx); sha256_update(&sctx, transactionData, transactionDataLength); sha256_finish(&sctx, hashOut); sha256_starts(&sctx); sha256_update(&sctx, hashOut, 32); sha256_finish(&sctx, txHash); free(transactionData); stream_destroy(streamTXData); }
static void calculate_hmac(uint8_t key[32], char* buf, size_t len, uint8_t res[32]){ int i; uint8_t hmacbuf[32]; uint8_t hmac_keybuf[64]; sha256_context sc; for (i = 0; i < 32; i++){ hmac_keybuf[i] = key[i] ^ 0x36; } memset(hmac_keybuf + 32, 0x36, 32); sha256_starts(&sc); sha256_update(&sc, hmac_keybuf, 32); sha256_update(&sc, buf, len); sha256_finish(&sc, hmacbuf); for (i = 0; i < 32; i++){ hmac_keybuf[i] = key[i] ^ 0x5c; } memset(hmac_keybuf + 32, 0x5c, 32); sha256_starts(&sc); sha256_update(&sc, hmac_keybuf, 32); sha256_update(&sc, hmacbuf, 32); sha256_finish(&sc, res); }
void do_gpu_sha(){ int i; uint32_t digest[8*STRIDE]; uint32_t block[20*STRIDE] = {0}; block[(72/4)*STRIDE] = 0x9FEF014; block[(76/4)*STRIDE] = 0x2a400100; sha256cl_context ctx; sha256_init(0,&ctx); sha256_starts(0,&ctx); sha256_update(0,&ctx,block,80); sha256_finish(0,&ctx,digest); for(i=0; i < 8; i++) printf("%8.8X",D_REF(digest,7-i,0)); printf("\n"); sha256_starts(0,&ctx); sha256_update(0,&ctx,digest,32); sha256_finish(0,&ctx,digest); for(i=0; i < 8; i++) printf("%8.8X",D_REF(digest,7-i,0)); printf("\n"); }
void testHash() { unsigned char Digest[32]; sha256_context ctx; sha256_init( &ctx ); sha256_starts( &ctx, 0 ); sha256_update( &ctx, sha256_test_buf[0], sha256_test_buflen[0] ); sha256_finish( &ctx, Digest ); print_buffer(Digest, sizeof(Digest)); memset(Digest, 0, sizeof(Digest)); uint8 buffer[1]; sha256_init( &ctx ); sha256_starts( &ctx, 0 ); buffer[0] = 'a'; sha256_update( &ctx, buffer, 1 ); buffer[0] = 'b'; sha256_update( &ctx, buffer, 1 ); buffer[0] = 'c'; sha256_update( &ctx, buffer, 1 ); buffer[0] = '\0'; sha256_update( &ctx, buffer, 1 ); sha256_finish( &ctx, Digest ); print_buffer(Digest, sizeof(Digest)); }
void hmac_sha256_finish(hmac_sha256_ctx *ctx, unsigned char *mac, unsigned int mac_size) { unsigned char digest_inside[SHA256_DIGEST_SIZE]; unsigned char mac_temp[SHA256_DIGEST_SIZE]; sha256_finish(&ctx->ctx_inside, digest_inside); sha256_update(&ctx->ctx_outside, digest_inside, SHA256_DIGEST_SIZE); sha256_finish(&ctx->ctx_outside, mac_temp); memcpy(mac, mac_temp, mac_size); }
int deriv_passwd(unsigned char *key, char *password, unsigned char *salt, int salt_len, unsigned int iterations) { int ret; unsigned int i; unsigned char hash[32]; sha256_context ctx; /* *** Init *** */ ret = 1; // error i = 0; /* *** Check args *** */ if((key == NULL) || (password == NULL) || (salt == NULL) || (salt_len <= 0) || (iterations == 0)) goto cleanup; /* *** Get H0 *** */ sha256_starts(&ctx, 0); sha256_update(&ctx, (unsigned char *)password, strlen(password)); sha256_update(&ctx, salt, salt_len); sha256_update(&ctx, (unsigned char *)&i, sizeof(int)); sha256_finish(&ctx, hash); //hash == HO /* *** Hi *** */ for(i = 1; i < iterations; i++) { sha256_starts(&ctx, 0); sha256_update(&ctx, hash, 32); sha256_update(&ctx, (unsigned char *)password, strlen(password)); sha256_update(&ctx, salt, salt_len); sha256_update(&ctx, (unsigned char *)&i, sizeof(int)); sha256_finish(&ctx, hash); } memcpy(key, hash, 32); ret = 0; // success cleanup: memset(&ctx, 0x00, sizeof(sha256_context)); memset(hash, 0x00, 32); return ret; }
static void yarrow_iterate(quint8 *digest) { quint8 v0[SHA256_DIGEST_SIZE]; unsigned i; memcpy(v0, digest, SHA256_DIGEST_SIZE); /* When hashed inside the loop, i should run from 1 to * YARROW_RESEED_ITERATIONS */ for (i = 0; ++i < YARROW_RESEED_ITERATIONS; ) { quint8 count[4]; sha256_context hash; sha256_starts(&hash); /* Hash v_i | v_0 | i */ WRITE_UINT32(count, i); sha256_update(&hash, digest, SHA256_DIGEST_SIZE); sha256_update(&hash, v0, sizeof(v0)); sha256_update(&hash, count, sizeof(count)); sha256_finish(&hash,digest); } }
SHA256_DIGEST sha256(const void *message, size_t message_len) { SHA256_CTX ctxt; sha256_init(&ctxt); sha256_update(&ctxt, message, message_len); return sha256_finish(&ctxt); }
void verify_sha256_digest(void) { struct sha256_region *ptr, *end; sha256_digest_t digest; int i; sha256_context ctx; sha256_starts(&ctx); end = &sha256_regions[sizeof(sha256_regions)/sizeof(sha256_regions[0])]; for(ptr = sha256_regions; ptr < end; ptr++) { sha256_update(&ctx, (uint8_t *)((uintptr_t)ptr->start), ptr->len); } sha256_finish(&ctx, digest); if (memcmp(digest, sha256_digest, sizeof(digest)) != 0) { printf("sha256 digests do not match :(\n"); printf(" digest: "); for(i = 0; i < sizeof(digest); i++) { printf("%hhx ", digest[i]); } printf("\n"); printf("sha256_digest: "); for(i = 0; i < sizeof(sha256_digest); i++) { printf("%hhx ", sha256_digest[i]); } printf("\n"); for(;;) { /* loop forever */ } } }
static void calc_sha256(BYTE* buffer32, const uint8* text, size_t size) { sha256_context ctx; sha256_starts(&ctx); sha256_update(&ctx, (uint8*)text, size); sha256_finish(&ctx, buffer32); }
static void rpmb_hmac(unsigned char *key, unsigned char *buff, int len, unsigned char *output) { sha256_context ctx; int i; unsigned char k_ipad[SHA256_BLOCK_SIZE]; unsigned char k_opad[SHA256_BLOCK_SIZE]; sha256_starts(&ctx); /* According to RFC 4634, the HMAC transform looks like: SHA(K XOR opad, SHA(K XOR ipad, text)) where K is an n byte key. ipad is the byte 0x36 repeated blocksize times opad is the byte 0x5c repeated blocksize times and text is the data being protected. */ for (i = 0; i < RPMB_SZ_MAC; i++) { k_ipad[i] = key[i] ^ 0x36; k_opad[i] = key[i] ^ 0x5c; } /* remaining pad bytes are '\0' XOR'd with ipad and opad values */ for ( ; i < SHA256_BLOCK_SIZE; i++) { k_ipad[i] = 0x36; k_opad[i] = 0x5c; } sha256_update(&ctx, k_ipad, SHA256_BLOCK_SIZE); sha256_update(&ctx, buff, len); sha256_finish(&ctx, output); /* Init context for second pass */ sha256_starts(&ctx); /* start with outer pad */ sha256_update(&ctx, k_opad, SHA256_BLOCK_SIZE); /* then results of 1st hash */ sha256_update(&ctx, output, RPMB_SZ_MAC); /* finish up 2nd pass */ sha256_finish(&ctx, output); }
static int hash_finish_sha256(struct hash_algo *algo, void *ctx, void *dest_buf, int size) { if (size < algo->digest_size) return -1; sha256_finish((sha256_context *)ctx, dest_buf); free(ctx); return 0; }
void sha256_calculate(const struct image_region region[], int region_count, uint8_t *checksum) { sha256_context ctx; uint32_t i; i = 0; sha256_starts(&ctx); for (i = 0; i < region_count; i++) sha256_update(&ctx, region[i].data, region[i].size); sha256_finish(&ctx, checksum); }
void set_keys(uint8_t master_key[32]){ sha256_context sh; uint8_t buf[32]; sha256_starts(&sh); sha256_update(&sh, "H", 1); sha256_update(&sh, master_key, 32); sha256_finish(&sh, hmac_key); sha256_starts(&sh); sha256_update(&sh, "R", 1); sha256_update(&sh, master_key, 32); sha256_finish(&sh, recordid_key); sha256_starts(&sh); sha256_update(&sh, "E", 1); sha256_update(&sh, master_key, 32); sha256_finish(&sh, buf); aes_set_key(&aes, buf, 256); }
void bitclient_calculateMerkleRoot(uint8* txHashes, uint32 numberOfTxHashes, uint8* merkleRoot) { if(numberOfTxHashes <= 0 ) { printf("bitclient_calculateMerkleRoot: Block has zero transactions (not even coinbase)\n"); memset(merkleRoot, 0, 32); return; } { // generate transaction data memcpy(merkleRoot, txHashes, 32); } if( numberOfTxHashes > 1 ) { // build merkle root tree uint8 hashData[64]; for(uint32 i=1; i<numberOfTxHashes; i++) { memcpy(hashData, merkleRoot, 32); memcpy(hashData+32,txHashes+i*32, 32); #if 0 printf("Merkle: %d\n", i); for(uint32 j=0; j < 64; j++){ printf("%2.2x ", hashData[j]); } printf("\n"); #endif uint8 hashOut[32]; sha256_context sha256_ctx; sha256_starts(&sha256_ctx); sha256_update(&sha256_ctx, hashData, 32*2); sha256_finish(&sha256_ctx, hashOut); sha256_starts(&sha256_ctx); sha256_update(&sha256_ctx, hashOut, 32); sha256_finish(&sha256_ctx, merkleRoot); } } }
uint8_t do_sha(){ uint8_t block[80] = {0}; uint8_t digest[32]; uint8_t digest2[32]; block[72] = 1; //*(uint32_t*)&block[72] = 0x9FEF014; //*(uint32_t*)&block[76] = 0x2a400100; //2a400100 sha256_context ctx; sha256_starts(&ctx); sha256_update(&ctx,block,80); sha256_finish(&ctx,digest); sha256_starts(&ctx); sha256_update(&ctx,digest,32); sha256_finish(&ctx,digest2); #if 1 int i; for(i=0; i < 32; i++){ printf("%2.2X",digest[31-i]); } printf("\n"); for(i=0; i < 32; i++){ printf("%2.2X",digest2[31-i]); } printf("\n"); #endif return digest[0]; }
static int utils_sha256 (lua_State *L) { unsigned char digest [32]; // get text to hash size_t textLength; const char * text = luaL_checklstring (L, 1, &textLength); sha256_context ctx; sha256_starts (&ctx); sha256_update (&ctx, (UC *) text, textLength); sha256_finish (&ctx, digest); lua_pushlstring (L, digest, sizeof digest); return 1; // number of result fields } // end of utils_sha256
static int sceSha256Digest(u32 data, int dataLen, u32 digestPtr) { if (!Memory::IsValidAddress(data) || !Memory::IsValidAddress(digestPtr) || !Memory::IsValidAddress(data + dataLen)) { ERROR_LOG(HLE, "sceSha256Digest(data=%08x, len=%d, digest=%08x) - bad address(es)", data, dataLen, digestPtr); return -1; } INFO_LOG(HLE, "sceSha256Digest(data=%08x, len=%d, digest=%08x)", data, dataLen, digestPtr); // Already checked above... u8 *digest = Memory::GetPointerUnchecked(digestPtr); sha256_context ctx; sha256_starts(&ctx); sha256_update(&ctx, Memory::GetPointerUnchecked(data), dataLen); sha256_finish(&ctx, digest); return 0; }
//Fills in hash and returns the size of the file size_t CFileManager::GetSHA256FromFile( const char * filename, unsigned char * input ){ FILE * fFile = fopen( filename, "rb" ); if( fFile == NULL ){ return 0; } sha256_context * hash = (sha256_context*)calloc( 1, sizeof( sha256_context ) ); char buffer[100]; int nSize=0; size_t nTotal=0; if( hash == NULL ){ fclose( fFile ); return 0; } //start sha256_starts( hash ); //crypt while( !feof( fFile ) ){ nTotal++; buffer[nSize]=fgetc( fFile ); nSize++; if( nSize == 100 ){ sha256_update( hash, (unsigned char*)buffer, nSize ); nSize = 0; } } if( nSize > 0 ){ sha256_update( hash, (unsigned char*)buffer, nSize-1 ); nSize = 0; } //finish sha256_finish( hash, input ); free( hash ); fclose( fFile ); return nTotal-1; }
static void update_purgatory(struct kexec_info *info) { static const uint8_t null_buf[256]; sha256_context ctx; sha256_digest_t digest; struct sha256_region region[SHA256_REGIONS]; int i, j; /* Don't do anything if we are not using purgatory */ if (!info->rhdr.e_shdr) { return; } arch_update_purgatory(info); memset(region, 0, sizeof(region)); sha256_starts(&ctx); /* Compute a hash of the loaded kernel */ for(j = i = 0; i < info->nr_segments; i++) { unsigned long nullsz; /* Don't include purgatory in the checksum. The stack * in the bss will definitely change, and the .data section * will also change when we poke the sha256_digest in there. * A very clever/careful person could probably improve this. */ if (info->segment[i].mem == (void *)info->rhdr.rel_addr) { continue; } sha256_update(&ctx, info->segment[i].buf, info->segment[i].bufsz); nullsz = info->segment[i].memsz - info->segment[i].bufsz; while(nullsz) { unsigned long bytes = nullsz; if (bytes > sizeof(null_buf)) { bytes = sizeof(null_buf); } sha256_update(&ctx, null_buf, bytes); nullsz -= bytes; } region[j].start = info->segment[i].mem; region[j].len = info->segment[i].memsz; j++; } sha256_finish(&ctx, digest); elf_rel_set_symbol(&info->rhdr, "sha256_regions", ®ion, sizeof(region)); elf_rel_set_symbol(&info->rhdr, "sha256_digest", &digest, sizeof(digest)); }
static void yarrow_fast_reseed(struct yarrow256_ctx *ctx) { quint8 digest[SHA256_DIGEST_SIZE]; unsigned i; #if YARROW_DEBUG fprintf(stderr, "yarrow_fast_reseed\n"); #endif /* We feed two block of output using the current key into the pool * before emptying it. */ if (ctx->seeded) { quint8 blocks[AES_BLOCK_SIZE * 2]; yarrow_generate_block(ctx, blocks); yarrow_generate_block(ctx, blocks + AES_BLOCK_SIZE); sha256_update(&ctx->pools[YARROW_FAST],blocks,sizeof(blocks)); } sha256_finish(&ctx->pools[YARROW_FAST],digest); /* Iterate */ yarrow_iterate(digest); aes_encrypt_key256(digest,&ctx->key); /* Derive new counter value */ memset(ctx->counter, 0, sizeof(ctx->counter)); //aes_encrypt(&ctx->key, sizeof(ctx->counter), ctx->counter, ctx->counter); aes_ecb_encrypt(ctx->counter,ctx->counter,sizeof(ctx->counter),&ctx->key); /* Reset estimates. */ for (i = 0; i<ctx->nsources; i++) ctx->sources[i].estimate[YARROW_FAST] = 0; /* New seed file. */ /* FIXME: Extract this into a function of its own. */ for (i = 0; i < sizeof(ctx->seed_file); i+= AES_BLOCK_SIZE) yarrow_generate_block(ctx, ctx->seed_file + i); yarrow_gate(ctx); }
EFI_STATUS efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) { EFI_STATUS efi_status; EFI_FILE *file; UINTN DataSize; void *buffer; sha256_context ctx; UINT8 hash[SHA256_DIGEST_SIZE]; int i; InitializeLib(image, systab); efi_status = simple_file_open(image, loader, &file, EFI_FILE_MODE_READ); if (efi_status != EFI_SUCCESS) { Print(L"Failed to open %s\n", loader); return efi_status; } efi_status = simple_file_read_all(file, &DataSize, &buffer); if (efi_status != EFI_SUCCESS) { Print(L"Failed to read %s\n", loader); goto out_close_file; } sha256_starts(&ctx); sha256_update(&ctx, buffer, DataSize); sha256_finish(&ctx, hash); for (i = 0; i < SHA256_DIGEST_SIZE; i++) { Print(L"%02x", hash[i]); } Print(L"\n"); for (i = 0; i < SHA256_DIGEST_SIZE; i++) { if (hash[i] != check[i]) { Print(L"Not matched!\n"); } } FreePool(buffer); out_close_file: simple_file_close(file); return efi_status; }
/* genera tutte le chiavi wpa possibili per ssid-series-macAddr specificati */ int generateKeys(unsigned long int ssid, unsigned long int series, unsigned char *macAddr) { int i; for(serial = userOptions.startSerial; serial < userOptions.endSerial; serial++) /* per ogni serial... */ { if(cycle % PRINT_RATE == 0) { printProgress(); } sprintf(seriesXserial, "%05dX%07d", series, serial); /* crea la stringa serie-X-seriale */ /* calcola l'hash SHA256(fixedPadding + serie-X-seriale + MAC) */ sha256_starts(shaCtx); sha256_update(shaCtx, fixedPadding, sizeof(fixedPadding)); sha256_update(shaCtx, seriesXserial, SERIESXSERIAL_SIZE); sha256_update(shaCtx, macAddr, MAC_SIZE); sha256_finish(shaCtx, hash); /* converte l'hash in caratteri ASCII */ for(i = 0; i < WPA_SIZE; i++) wpa[i] = charset[hash[i]]; if(userOptions.opMode == FINDKEY) /* stiamo cercando una chiave particolare */ { if(isWpaCorrect() == TRUE) { return KEYFOUND; } } else if(userOptions.opMode == GENFILE) /* stiamo generando il dizionario */ { if(writeWpaToBuffer() == FAILURE) { lastErr = FILE_ERR; return FAILURE; } } cycle++; } return SUCCESS; }
static void yarrow_slow_reseed(struct yarrow256_ctx *ctx) { quint8 digest[SHA256_DIGEST_SIZE]; unsigned i; #if YARROW_DEBUG fprintf(stderr, "yarrow_slow_reseed\n"); #endif /* Get digest of the slow pool*/ sha256_finish(&ctx->pools[YARROW_SLOW], digest); /* Feed it into the fast pool */ sha256_update(&ctx->pools[YARROW_FAST],digest, sizeof(digest)); yarrow_fast_reseed(ctx); /* Reset estimates. */ for (i = 0; i<ctx->nsources; i++) ctx->sources[i].estimate[YARROW_SLOW] = 0; }
Ti::TiValue TiUtilsModule::sha256(Ti::TiValue value) { Ti::TiValue val; QString str = value.toString(); unsigned char *key = NULL; key = (unsigned char*)qstrdup(str.toLocal8Bit().constData()); unsigned char hash[32]; sha256_context ctx; sha256_starts(&ctx); sha256_update(&ctx, key, str.length()); sha256_finish(&ctx, hash); QByteArray result = QByteArray(reinterpret_cast<const char *>(hash)).toHex(); // for some reason we're getting 4 extra characters QString returnString = QString(result); returnString.remove(returnString.length() - 4, 4); val.setString(returnString); return val; }
static void sha256_finish_wrap( void *ctx, unsigned char *output ) { sha256_finish( (sha256_context *) ctx, output ); }
u32 NcchPadgen() { u32 result; NcchInfo *info = (NcchInfo*)0x20316000; SeedInfo *seedinfo = (SeedInfo*)0x20400000; if (DebugFileOpen("/slot0x25KeyX.bin")) { u8 slot0x25KeyX[16] = {0}; if (!DebugFileRead(&slot0x25KeyX, 16, 0)) { FileClose(); return 1; } FileClose(); setup_aeskeyX(0x25, slot0x25KeyX); } else { Debug("7.x game decryption will fail on less than 7.x!"); } if (DebugFileOpen("/seeddb.bin")) { if (!DebugFileRead(seedinfo, 16, 0)) { FileClose(); return 1; } if (!seedinfo->n_entries || seedinfo->n_entries > MAX_ENTRIES) { Debug("Too many/few seeddb entries."); return 1; } if (!DebugFileRead(seedinfo->entries, seedinfo->n_entries * sizeof(SeedInfoEntry), 16)) { FileClose(); return 1; } FileClose(); } else { // Debug("Warning, didn't open seeddb.bin"); Debug("9.x seed crypto game decryption will fail!"); } if (!DebugFileOpen("/ncchinfo.bin")) return 1; if (!DebugFileRead(info, 16, 0)) { FileClose(); return 1; } if (!info->n_entries || info->n_entries > MAX_ENTRIES) { Debug("Too many/few entries in ncchinfo.bin"); return 1; } if (info->ncch_info_version != 0xF0000004) { Debug("Wrong version ncchinfo.bin"); return 1; } if (!DebugFileRead(info->entries, info->n_entries * sizeof(NcchInfoEntry), 16)) { FileClose(); return 1; } FileClose(); Debug("Number of entries: %i", info->n_entries); for(u32 i = 0; i < info->n_entries; i++) { Debug("Creating pad number: %i. Size (MB): %i", i+1, info->entries[i].size_mb); PadInfo padInfo = {.setKeyY = 1, .size_mb = info->entries[i].size_mb}; memcpy(padInfo.CTR, info->entries[i].CTR, 16); memcpy(padInfo.filename, info->entries[i].filename, 112); if (info->entries[i].uses7xCrypto && info->entries[i].usesSeedCrypto) { u8 keydata[32]; memcpy(keydata, info->entries[i].keyY, 16); u32 found_seed = 0; for (u32 j = 0; j < seedinfo->n_entries; j++) { if (seedinfo->entries[j].titleId == info->entries[i].titleId) { found_seed = 1; memcpy(&keydata[16], seedinfo->entries[j].external_seed, 16); break; } } if (!found_seed) { Debug("Failed to find seed in seeddb.bin"); return 0; } u8 sha256sum[32]; sha256_context shactx; sha256_starts(&shactx); sha256_update(&shactx, keydata, 32); sha256_finish(&shactx, sha256sum); memcpy(padInfo.keyY, sha256sum, 16); } else memcpy(padInfo.keyY, info->entries[i].keyY, 16); if(info->entries[i].uses7xCrypto == 0xA) // won't work on an Old 3DS padInfo.keyslot = 0x18; else if(info->entries[i].uses7xCrypto >> 8 == 0xDEC0DE) // magic value to manually specify keyslot padInfo.keyslot = info->entries[i].uses7xCrypto & 0x3F; else if(info->entries[i].uses7xCrypto) padInfo.keyslot = 0x25; else padInfo.keyslot = 0x2C; Debug("Using keyslot: %02X", padInfo.keyslot); result = CreatePad(&padInfo); if (!result) Debug("Done!"); else return 1; } return 0; }
static void SHA256_Final(unsigned char digest[32], SHA256_CTX *ctx) { sha256_finish(ctx, digest); }
/* Restore the checksum before writing */ hdr->prolog_checksum = checksum_ref; printf("Image checksum...OK!\n"); return 0; } #elif defined(CONFIG_ARMADA_3700) /* Armada 3700 */ static int check_image_header(void) { struct common_tim_data *hdr = (struct common_tim_data *)get_load_addr(); int image_num; u8 hash_160_output[SHA1_SUM_LEN]; u8 hash_256_output[SHA256_SUM_LEN]; sha1_context hash1_text; sha256_context hash256_text; u8 *hash_output; u32 hash_algorithm_id; u32 image_size_to_hash; u32 flash_entry_addr; u32 *hash_value; u32 internal_hash[HASH_SUM_LEN]; const u8 *buff; u32 num_of_image = hdr->num_images; u32 version = hdr->version; u32 trusted = hdr->trusted; /* bubt checksum validation only supports nontrusted images */ if (trusted == 1) { printf("bypass image validation, "); printf("only untrusted image is supported now\n"); return 0; } /* only supports image version 3.5 and 3.6 */ if (version != IMAGE_VERSION_3_5_0 && version != IMAGE_VERSION_3_6_0) { printf("Error: Unsupported Image version = 0x%08x\n", version); return -ENOEXEC; } /* validate images hash value */ for (image_num = 0; image_num < num_of_image; image_num++) { struct mvebu_image_info *info = (struct mvebu_image_info *)(get_load_addr() + sizeof(struct common_tim_data) + image_num * sizeof(struct mvebu_image_info)); hash_algorithm_id = info->hash_algorithm_id; image_size_to_hash = info->image_size_to_hash; flash_entry_addr = info->flash_entry_addr; hash_value = info->hash; buff = (const u8 *)(get_load_addr() + flash_entry_addr); if (image_num == 0) { /* * The first image includes hash values in its content. * For hash calculation, we need to save the original * hash values to a local variable that will be * copied back for comparsion and set all zeros to * the orignal hash values for calculating new value. * First image original format : * x...x (datum1) x...x(orig. hash values) x...x(datum2) * Replaced first image format : * x...x (datum1) 0...0(hash values) x...x(datum2) */ memcpy(internal_hash, hash_value, sizeof(internal_hash)); memset(hash_value, 0, sizeof(internal_hash)); } if (image_size_to_hash == 0) { printf("Warning: Image_%d hash checksum is disabled, ", image_num); printf("skip the image validation.\n"); continue; } switch (hash_algorithm_id) { case SHA1_SUM_LEN: sha1_starts(&hash1_text); sha1_update(&hash1_text, buff, image_size_to_hash); sha1_finish(&hash1_text, hash_160_output); hash_output = hash_160_output; break; case SHA256_SUM_LEN: sha256_starts(&hash256_text); sha256_update(&hash256_text, buff, image_size_to_hash); sha256_finish(&hash256_text, hash_256_output); hash_output = hash_256_output; break; default: printf("Error: Unsupported hash_algorithm_id = %d\n", hash_algorithm_id); return -ENOEXEC; } if (image_num == 0) memcpy(hash_value, internal_hash, sizeof(internal_hash)); if (memcmp(hash_value, hash_output, hash_algorithm_id) != 0) { printf("Error: Image_%d checksum is not correct\n", image_num); return -ENOEXEC; } } printf("Image checksum...OK!\n"); return 0; }
SEXP digest(SEXP Txt, SEXP Algo, SEXP Length, SEXP Skip, SEXP Leave_raw) { FILE *fp=0; char *txt; int algo = INTEGER_VALUE(Algo); int length = INTEGER_VALUE(Length); int skip = INTEGER_VALUE(Skip); int leaveRaw = INTEGER_VALUE(Leave_raw); SEXP result = NULL; char output[128+1], *outputp = output; /* 33 for md5, 41 for sha1, 65 for sha256, 128 for sha512; plus trailing NULL */ int nChar; int output_length = -1; if (IS_RAW(Txt)) { /* Txt is either RAW */ txt = (char*) RAW(Txt); nChar = LENGTH(Txt); } else { /* or a string */ txt = (char*) STRING_VALUE(Txt); nChar = strlen(txt); } if (skip>0) { if (skip>=nChar) nChar=0; else { nChar -= skip; txt += skip; } } if (length>=0 && length<nChar) nChar = length; switch (algo) { case 1: { /* md5 case */ md5_context ctx; output_length = 16; unsigned char md5sum[16]; int j; md5_starts( &ctx ); md5_update( &ctx, (uint8 *) txt, nChar); md5_finish( &ctx, md5sum ); memcpy(output, md5sum, 16); if (!leaveRaw) for(j = 0; j < 16; j++) sprintf(output + j * 2, "%02x", md5sum[j]); break; } case 2: { /* sha1 case */ int j; sha1_context ctx; output_length = 20; unsigned char sha1sum[20]; sha1_starts( &ctx ); sha1_update( &ctx, (uint8 *) txt, nChar); sha1_finish( &ctx, sha1sum ); memcpy(output, sha1sum, 20); if (!leaveRaw) for( j = 0; j < 20; j++ ) sprintf( output + j * 2, "%02x", sha1sum[j] ); break; } case 3: { /* crc32 case */ unsigned long val, l; l = nChar; val = digest_crc32(0L, 0, 0); val = digest_crc32(val, (unsigned char*) txt, (unsigned) l); sprintf(output, "%2.2x", (unsigned int) val); break; } case 4: { /* sha256 case */ int j; sha256_context ctx; output_length = 32; unsigned char sha256sum[32]; sha256_starts( &ctx ); sha256_update( &ctx, (uint8 *) txt, nChar); sha256_finish( &ctx, sha256sum ); memcpy(output, sha256sum, 32); if(!leaveRaw) for( j = 0; j < 32; j++ ) sprintf( output + j * 2, "%02x", sha256sum[j] ); break; } case 5: { /* sha2-512 case */ int j; SHA512_CTX ctx; output_length = SHA512_DIGEST_LENGTH; uint8_t sha512sum[output_length], *d = sha512sum; SHA512_Init(&ctx); SHA512_Update(&ctx, (uint8 *) txt, nChar); // Calling SHA512_Final, because SHA512_End will already // convert the hash to a string, and we also want RAW SHA512_Final(sha512sum, &ctx); memcpy(output, sha512sum, output_length); // adapted from SHA512_End if(!leaveRaw) { for (j = 0; j < output_length; j++) { *outputp++ = sha2_hex_digits[(*d & 0xf0) >> 4]; *outputp++ = sha2_hex_digits[*d & 0x0f]; d++; } *outputp = (char)0; } break; } case 101: { /* md5 file case */ int j; md5_context ctx; output_length = 16; unsigned char buf[1024]; unsigned char md5sum[16]; if (!(fp = fopen(txt,"rb"))) { error("Cannot open input file: %s", txt); return(NULL); } if (skip > 0) fseek(fp, skip, SEEK_SET); md5_starts( &ctx ); if (length>=0) { while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0 && length>0) { if (nChar>length) nChar=length; md5_update( &ctx, buf, nChar ); length -= nChar; } } else { while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0) md5_update( &ctx, buf, nChar ); } fclose(fp); md5_finish( &ctx, md5sum ); memcpy(output, md5sum, 16); if (!leaveRaw) for(j = 0; j < 16; j++) sprintf(output + j * 2, "%02x", md5sum[j]); break; } case 102: { /* sha1 file case */ int j; sha1_context ctx; output_length = 20; unsigned char buf[1024]; unsigned char sha1sum[20]; if (!(fp = fopen(txt,"rb"))) { error("Cannot open input file: %s", txt); return(NULL); } if (skip > 0) fseek(fp, skip, SEEK_SET); sha1_starts ( &ctx ); if (length>=0) { while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0 && length>0) { if (nChar>length) nChar=length; sha1_update( &ctx, buf, nChar ); length -= nChar; } } else { while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0) sha1_update( &ctx, buf, nChar ); } fclose(fp); sha1_finish ( &ctx, sha1sum ); memcpy(output, sha1sum, 20); if(!leaveRaw) for( j = 0; j < 20; j++ ) sprintf( output + j * 2, "%02x", sha1sum[j] ); break; } case 103: { /* crc32 file case */ unsigned char buf[1024]; unsigned long val; if (!(fp = fopen(txt,"rb"))) { error("Cannot open input file: %s", txt); return(NULL); } if (skip > 0) fseek(fp, skip, SEEK_SET); val = digest_crc32(0L, 0, 0); if (length>=0) { while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0 && length>0) { if (nChar>length) nChar=length; val = digest_crc32(val , buf, (unsigned) nChar); length -= nChar; } } else { while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0) val = digest_crc32(val , buf, (unsigned) nChar); } fclose(fp); sprintf(output, "%2.2x", (unsigned int) val); break; } case 104: { /* sha256 file case */ int j; sha256_context ctx; output_length = 32; unsigned char buf[1024]; unsigned char sha256sum[32]; if (!(fp = fopen(txt,"rb"))) { error("Cannot open input file: %s", txt); return(NULL); } if (skip > 0) fseek(fp, skip, SEEK_SET); sha256_starts ( &ctx ); if (length>=0) { while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0 && length>0) { if (nChar>length) nChar=length; sha256_update( &ctx, buf, nChar ); length -= nChar; } } else { while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0) sha256_update( &ctx, buf, nChar ); } fclose(fp); sha256_finish ( &ctx, sha256sum ); memcpy(output, sha256sum, 32); if(!leaveRaw) for( j = 0; j < 32; j++ ) sprintf( output + j * 2, "%02x", sha256sum[j] ); break; } case 105: { /* sha2-512 file case */ int j; SHA512_CTX ctx; output_length = SHA512_DIGEST_LENGTH; uint8_t sha512sum[output_length], *d = sha512sum; unsigned char buf[1024]; if (!(fp = fopen(txt,"rb"))) { error("Cannot open input file: %s", txt); return(NULL); } if (skip > 0) fseek(fp, skip, SEEK_SET); SHA512_Init(&ctx); if (length>=0) { while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0 && length>0) { if (nChar>length) nChar=length; SHA512_Update( &ctx, buf, nChar ); length -= nChar; } } else { while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0) SHA512_Update( &ctx, buf, nChar ); } fclose(fp); // Calling SHA512_Final, because SHA512_End will already // convert the hash to a string, and we also want RAW SHA512_Final(sha512sum, &ctx); memcpy(output, sha512sum, output_length); // adapted from SHA512_End if(!leaveRaw) { for (j = 0; j < output_length; j++) { *outputp++ = sha2_hex_digits[(*d & 0xf0) >> 4]; *outputp++ = sha2_hex_digits[*d & 0x0f]; d++; } *outputp = (char)0; } break; } default: { error("Unsupported algorithm code"); return(NULL); } } if (leaveRaw && output_length > 0) { PROTECT(result=allocVector(RAWSXP, output_length)); memcpy(RAW(result), output, output_length); } else { PROTECT(result=allocVector(STRSXP, 1)); SET_STRING_ELT(result, 0, mkChar(output)); } UNPROTECT(1); return result; }