/* This program is released under the Common Public License V1.0
*
* You should have received a copy of Common Public License V1.0 along with
* with this program.
*
* Copyright IBM Corp. 2016
*
*/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <ica_api.h>
/* The name of the file to calcualte the SHA256 hash from */
#define FILE_NAME "example_sha256.c"
/* Size of the chunks in which the file is read.
* Must be a multiple of 64 bytes.
*/
#define CHUNK_SIZE 1024
/* Prints hex values to standard out. */
static void dump_data(unsigned char *data, unsigned long length);
/* Prints a description of the return value to standard out. */
static int handle_ica_error(int rc);
int main(int argc, char **argv)
{
int rc;
/* This is the buffer where the SHA256 hash is generated into.
* For SHA256, it needs to be 32 bytes in size (SHA256_HASH_LENGTH).
*/
unsigned char sha_result[SHA256_HASH_LENGTH];
/* The file will be read in several chunks into this buffer.
* The chunks will be the input to the ica_sha256 function which
* we call for each chunk.
*/
unsigned char sha_input[CHUNK_SIZE];
/* This is the SHA 256 context. It stores intermediate values
* needed when chaining multiple chunks (as we do).
*/
sha256_context_t context;
/* Open the file in binary mode and read its content in chunks */
FILE *f;
f = fopen(FILE_NAME,"r");
if (f==NULL)
return handle_ica_error(errno);
int len;
unsigned long total_size = 0;
while(!feof(f)) {
/* read a chunk of data */
len = fread(sha_input, 1, CHUNK_SIZE, f);
if (total_size == 0) {
/* this is the first chunk */
rc = ica_sha256(SHA_MSG_PART_FIRST,
len, sha_input,
&context,
sha_result);
}
else if (!feof(f)) {
/* add this chunk to the hash */
rc = ica_sha256(SHA_MSG_PART_MIDDLE,
len, sha_input,
&context,
sha_result);
}
else {
/* this is the last chunk */
rc = ica_sha256(SHA_MSG_PART_FINAL,
len, sha_input,
&context,
sha_result);
}
total_size += len;
if (rc)
break;
}
/* close the file */
fclose(f);
/* Error handling (if necessary). */
if (rc)
return handle_ica_error(rc);
/* Dump the generated hash to standard output, just for
* a visual control.
*
* Note: You can verify the displayed hash using command
* 'sha256sum example_sha256.c'
*/
printf("SHA256 hash of file '%s' (%u bytes):\n", FILE_NAME, total_size);
dump_data(sha_result, sizeof(sha_result));
}
static void dump_data(unsigned char *data, unsigned long length)
{
unsigned char *ptr;
int i;
for (ptr = data, i = 1; ptr < (data+length); ptr++, i++) {
printf("0x%02x ", *ptr);
if ((i % 16) == 0)
printf("\n");
}
if (i % 16)
printf("\n");
}
static int handle_ica_error(int rc)
{
switch (rc) {
case 0:
printf("OK\n");
break;
case EINVAL:
printf("Incorrect parameter.\n");
break;
case EPERM:
printf("Operation not permitted by Hardware (CPACF).\n");
break;
case EIO:
printf("I/O error.\n");
break;
default:
printf("unknown error.\n");
}
return rc;
}