Skip to content

Commit

Permalink
Add support for SHA-512/224 and SHA-512/256
Browse files Browse the repository at this point in the history
Signed-off-by: Ingo Franzki <[email protected]>
  • Loading branch information
ifranzki authored and p-steuer committed Aug 20, 2018
1 parent 56cad1a commit 90446f2
Show file tree
Hide file tree
Showing 9 changed files with 364 additions and 3 deletions.
91 changes: 91 additions & 0 deletions include/ica_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ typedef ica_adapter_handle_t ICA_ADAPTER_HANDLE;
#define RSA_KEY_GEN_ME 92
#define RSA_KEY_GEN_CRT 93
#define SHA512_DRNG 94
#define SHA512_224 95
#define SHA512_256 96

/*
* Key length for DES/3DES encryption/decryption
Expand Down Expand Up @@ -156,6 +158,8 @@ typedef ica_adapter_handle_t ICA_ADAPTER_HANDLE;
#define SHA256_HASH_LENGTH 32
#define SHA384_HASH_LENGTH 48
#define SHA512_HASH_LENGTH 64
#define SHA512_224_HASH_LENGTH SHA224_HASH_LENGTH
#define SHA512_256_HASH_LENGTH SHA256_HASH_LENGTH
#define SHA3_224_HASH_LENGTH SHA224_HASH_LENGTH
#define SHA3_256_HASH_LENGTH SHA256_HASH_LENGTH
#define SHA3_384_HASH_LENGTH SHA384_HASH_LENGTH
Expand Down Expand Up @@ -715,6 +719,93 @@ unsigned int ica_sha512(unsigned int message_part,
sha512_context_t *sha512_context,
unsigned char *output_data);

/**
* Perform secure hash on input data using the SHA-512/224 algorithm.
*
* Required HW Support
* KIMD-SHA-512, or KLMD-SHA-512
*
* @param message_part
* The message chaining state. Must be one of the following:
* SHA_MSG_PART_ONLY - A single hash operation
* SHA_MSG_PART_FIRST - The first part
* SHA_MSG_PART_MIDDLE - The middle part
* SHA_MSG_PART_FINAL - The last part
* @param input_length
* The byte length of the input data to be SHA-512/224 hashed and must be greater
* than zero.
* Note: For SHA_MSG_PART_FIRST and SHA_MSG_PART_MIDDLE calls, the byte length
* must be a multiple of 128 i.e., SHA-512 block size.
* @param input_data
* Pointer to the input data.
* @param sha512_context
* Pointer to the SHA-512 context structure used to store intermediate values
* needed when chaining is used. The contents are ignored for message part
* SHA_MSG_PART_ONLY and SHA_MSG_PART_FIRST. This structure must
* contain the returned value of the preceding call to ica_sha512_224 for message
* part SHA_MSG_PART_MIDDLE and SHA_MSG_PART_FINAL. For message part
* SHA_MSG_PART_FIRST and SHA_MSG_PART_FINAL, the returned value can
* be used for a chained call of ica_sha512_224. Therefore, the application must
* not modify the contents of this structure in between chained calls.
* @param output_data
* Pointer to the buffer to contain the resulting hash data. The resulting
* output data will have a length of SHA512_224_HASH_LENGTH. Make sure buffer has
* at least this size.
*
* @return 0 if successful.
* EINVAL if at least one invalid parameter is given
* EIO if the operation fails. This should never happen.
*/
ICA_EXPORT
unsigned int ica_sha512_224(unsigned int message_part,
uint64_t input_length,
unsigned char *input_data,
sha512_context_t *sha512_context,
unsigned char *output_data);

/**
* Perform secure hash on input data using the SHA-512/256 algorithm.
*
* Required HW Support
* KIMD-SHA-512, or KLMD-SHA-512
*
* @param message_part
* The message chaining state. Must be one of the following:
* SHA_MSG_PART_ONLY - A single hash operation
* SHA_MSG_PART_FIRST - The first part
* SHA_MSG_PART_MIDDLE - The middle part
* SHA_MSG_PART_FINAL - The last part
* @param input_length
* The byte length of the input data to be SHA-512/256 hashed and must be greater
* than zero.
* Note: For SHA_MSG_PART_FIRST and SHA_MSG_PART_MIDDLE calls, the byte length
* must be a multiple of 128 i.e., SHA-512 block size.
* @param input_data
* Pointer to the input data.
* @param sha512_context
* Pointer to the SHA-512 context structure used to store intermediate values
* needed when chaining is used. The contents are ignored for message part
* SHA_MSG_PART_ONLY and SHA_MSG_PART_FIRST. This structure must
* contain the returned value of the preceding call to ica_sha512_256 for message
* part SHA_MSG_PART_MIDDLE and SHA_MSG_PART_FINAL. For message part
* SHA_MSG_PART_FIRST and SHA_MSG_PART_FINAL, the returned value can
* be used for a chained call of ica_sha512_256. Therefore, the application must
* not modify the contents of this structure in between chained calls.
* @param output_data
* Pointer to the buffer to contain the resulting hash data. The resulting
* output data will have a length of SHA512_256_HASH_LENGTH. Make sure buffer has
* at least this size.
*
* @return 0 if successful.
* EINVAL if at least one invalid parameter is given
* EIO if the operation fails. This should never happen.
*/ICA_EXPORT
unsigned int ica_sha512_256(unsigned int message_part,
uint64_t input_length,
unsigned char *input_data,
sha512_context_t *sha512_context,
unsigned char *output_data);

ICA_EXPORT
unsigned int ica_sha3_224(unsigned int message_part,
unsigned int input_length,
Expand Down
7 changes: 7 additions & 0 deletions libica.map
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,10 @@ LIBICA_3.3.0 {
ica_mp_sqr512;
local: *;
} LIBICA_3.2.0;

LIBICA_3.4.0 {
global:
ica_sha512_224;
ica_sha512_256;
local: *;
} LIBICA_3.3.0;
78 changes: 78 additions & 0 deletions src/ica_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,84 @@ unsigned int ica_sha512(unsigned int message_part,
(uint64_t *) &sha512_context->runningLengthHigh);
}

unsigned int ica_sha512_224(unsigned int message_part,
uint64_t input_length,
unsigned char *input_data,
sha512_context_t *sha512_context,
unsigned char *output_data)
{
unsigned int rc;

#ifdef ICA_FIPS
if (fips >> 1)
return EACCES;
#endif /* ICA_FIPS */

/* check for obvious errors in parms */
if ((input_data == NULL) ||
(sha512_context == NULL) ||
(output_data == NULL))
return EINVAL;

/* make sure some message part is specified */
rc = check_message_part(message_part);
if (rc)
return rc;

/*
* for FIRST or MIDDLE calls the input
* data length must be a multiple of 128 bytes.
*/
if (input_length & 0x7f &&
(message_part == SHA_MSG_PART_FIRST ||
message_part == SHA_MSG_PART_MIDDLE))
return EINVAL;

return s390_sha512_224((unsigned char *)&sha512_context->sha512Hash,
input_data, input_length, output_data, message_part,
(uint64_t *) &sha512_context->runningLengthLow,
(uint64_t *) &sha512_context->runningLengthHigh);
}

unsigned int ica_sha512_256(unsigned int message_part,
uint64_t input_length,
unsigned char *input_data,
sha512_context_t *sha512_context,
unsigned char *output_data)
{
unsigned int rc;

#ifdef ICA_FIPS
if (fips >> 1)
return EACCES;
#endif /* ICA_FIPS */

/* check for obvious errors in parms */
if ((input_data == NULL) ||
(sha512_context == NULL) ||
(output_data == NULL))
return EINVAL;

/* make sure some message part is specified */
rc = check_message_part(message_part);
if (rc)
return rc;

/*
* for FIRST or MIDDLE calls the input
* data length must be a multiple of 128 bytes.
*/
if (input_length & 0x7f &&
(message_part == SHA_MSG_PART_FIRST ||
message_part == SHA_MSG_PART_MIDDLE))
return EINVAL;

return s390_sha512_256((unsigned char *)&sha512_context->sha512Hash,
input_data, input_length, output_data, message_part,
(uint64_t *) &sha512_context->runningLengthLow,
(uint64_t *) &sha512_context->runningLengthHigh);
}

unsigned int ica_sha3_224(unsigned int message_part,
unsigned int input_length,
unsigned char *input_data,
Expand Down
2 changes: 2 additions & 0 deletions src/icainfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ static struct crypt_pair crypt_map[] = {
{"SHA-256", SHA256},
{"SHA-384", SHA384},
{"SHA-512", SHA512},
{"SHA-512/224", SHA512_224},
{"SHA-512/256", SHA512_256},
{"SHA3-224", SHA3_224},
{"SHA3-256", SHA3_256},
{"SHA3-384", SHA3_384},
Expand Down
4 changes: 4 additions & 0 deletions src/include/icastats.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ typedef enum stats_fields {
ICA_STATS_SHA256,
ICA_STATS_SHA384,
ICA_STATS_SHA512,
ICA_STATS_SHA512_224,
ICA_STATS_SHA512_256,
ICA_STATS_SHA3_224,
ICA_STATS_SHA3_256,
ICA_STATS_SHA3_384,
Expand Down Expand Up @@ -84,6 +86,8 @@ typedef enum stats_fields {
"SHA-256", \
"SHA-384", \
"SHA-512", \
"SHA-512/224", \
"SHA-512/256", \
"SHA3-224", \
"SHA3-256", \
"SHA3-384", \
Expand Down
4 changes: 3 additions & 1 deletion src/include/s390_crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,9 @@ typedef enum {
SHA_3_512,
SHAKE_128,
SHAKE_256,
GHASH
GHASH,
SHA_512_224,
SHA_512_256
} kimd_functions_t;

typedef enum {
Expand Down
31 changes: 30 additions & 1 deletion src/include/s390_sha.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,22 @@ static unsigned char SHA_512_DEFAULT_IV[] = {
0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, 0x6b, 0x5b, 0xe0, 0xcd, 0x19,
0x13, 0x7e, 0x21, 0x79 };

static unsigned char SHA_512_224_DEFAULT_IV[] = {
0x8C, 0x3D, 0x37, 0xC8, 0x19, 0x54, 0x4D, 0xA2, 0x73, 0xE1, 0x99, 0x66,
0x89, 0xDC, 0xD4, 0xD6, 0x1D, 0xFA, 0xB7, 0xAE, 0x32, 0xFF, 0x9C, 0x82,
0x67, 0x9D, 0xD5, 0x14, 0x58, 0x2F, 0x9F, 0xCF, 0x0F, 0x6D, 0x2B, 0x69,
0x7B, 0xD4, 0x4D, 0xA8, 0x77, 0xE3, 0x6F, 0x73, 0x04, 0xC4, 0x89, 0x42,
0x3F, 0x9D, 0x85, 0xA8, 0x6A, 0x1D, 0x36, 0xC8, 0x11, 0x12, 0xE6, 0xAD,
0x91, 0xD6, 0x92, 0xA1 };

static unsigned char SHA_512_256_DEFAULT_IV[] = {
0x22, 0x31, 0x21, 0x94, 0xFC, 0x2B, 0xF7, 0x2C, 0x9F, 0x55, 0x5F, 0xA3,
0xC8, 0x4C, 0x64, 0xC2, 0x23, 0x93, 0xB8, 0x6B, 0x6F, 0x53, 0xB1, 0x51,
0x96, 0x38, 0x77, 0x19, 0x59, 0x40, 0xEA, 0xBD, 0x96, 0x28, 0x3E, 0xE2,
0xA8, 0x8E, 0xFF, 0xE3, 0xBE, 0x5E, 0x1E, 0x25, 0x53, 0x86, 0x39, 0x92,
0x2B, 0x01, 0x99, 0xFC, 0x2C, 0x85, 0xB8, 0xAA, 0x0E, 0xB7, 0x2D, 0xDC,
0x81, 0xC5, 0x2C, 0xA2 };

static unsigned char SHA_3_DEFAULT_IV[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Expand Down Expand Up @@ -82,7 +98,10 @@ static const SHA_CONSTANTS sha_constants[] = {
{S390_CRYPTO_SHA_3_384, 48, 200, 104, SHA_3_DEFAULT_IV},
{S390_CRYPTO_SHA_3_512, 64, 200, 72, SHA_3_DEFAULT_IV},
{S390_CRYPTO_SHAKE_128, 0, 200, 168, SHA_3_DEFAULT_IV},
{S390_CRYPTO_SHAKE_256, 0, 200, 136, SHA_3_DEFAULT_IV}
{S390_CRYPTO_SHAKE_256, 0, 200, 136, SHA_3_DEFAULT_IV},
{ 0, 0, 0, 0, NULL }, /* Dummy line for GHASH */
{S390_CRYPTO_SHA_512, 28, 64, 128, SHA_512_224_DEFAULT_IV},
{S390_CRYPTO_SHA_512, 32, 64, 128, SHA_512_256_DEFAULT_IV},
};

int s390_sha1(unsigned char *iv, unsigned char *input_data,
Expand All @@ -107,6 +126,16 @@ int s390_sha512(unsigned char *iv, unsigned char *input_data,
unsigned int message_part, uint64_t *running_length_lo,
uint64_t *running_length_hi);

int s390_sha512_224(unsigned char *iv, unsigned char *input_data,
uint64_t input_length, unsigned char *output_data,
unsigned int message_part, uint64_t *running_length_lo,
uint64_t *running_length_hi);

int s390_sha512_256(unsigned char *iv, unsigned char *input_data,
uint64_t input_length, unsigned char *output_data,
unsigned int message_part, uint64_t *running_length_lo,
uint64_t *running_length_hi);

int s390_sha3_224(unsigned char *iv, unsigned char *input_data,
unsigned int input_length, unsigned char *output_data,
unsigned int message_part, uint64_t *running_length);
Expand Down
6 changes: 5 additions & 1 deletion src/s390_crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ s390_supported_function_t s390_kimd_functions[] = {
{SHA_3_512, S390_CRYPTO_SHA_3_512, &sha3_switch},
{SHAKE_128, S390_CRYPTO_SHAKE_128, &sha3_switch},
{SHAKE_256, S390_CRYPTO_SHAKE_256, &sha3_switch},
{GHASH, S390_CRYPTO_GHASH, &msa4_switch}
{GHASH, S390_CRYPTO_GHASH, &msa4_switch},
{SHA_512_224, S390_CRYPTO_SHA_512, &sha512_switch},
{SHA_512_256, S390_CRYPTO_SHA_512, &sha512_switch}
};

s390_supported_function_t s390_kmc_functions[] = {
Expand Down Expand Up @@ -298,6 +300,8 @@ libica_func_list_element_int icaList[] = {
{SHA256, KIMD, SHA_256, ICA_FLAG_SW, 0},
{SHA384, KIMD, SHA_512, ICA_FLAG_SW, 0},
{SHA512, KIMD, SHA_512, ICA_FLAG_SW, 0},
{SHA512_224, KIMD, SHA_512_224, ICA_FLAG_SW, 0},
{SHA512_256, KIMD, SHA_512_256, ICA_FLAG_SW, 0},
{SHA3_224, KIMD, SHA_3_224, 0, 0},
{SHA3_256, KIMD, SHA_3_256, 0, 0},
{SHA3_384, KIMD, SHA_3_384, 0, 0},
Expand Down
Loading

0 comments on commit 90446f2

Please sign in to comment.