Files
GmSSL/vendor/liboqs/src/kex_ntru/ntru_crypto_hash.c
zhaoxiaomeng 53af3b51ae quantum init
2018-01-04 13:40:59 +08:00

308 lines
9.1 KiB
C

/******************************************************************************
* NTRU Cryptography Reference Source Code
*
* Copyright (C) 2009-2016 Security Innovation (SI)
*
* SI has dedicated the work to the public domain by waiving all of its rights
* to the work worldwide under copyright law, including all related and
* neighboring rights, to the extent allowed by law.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* You can copy, modify, distribute and perform the work, even for commercial
* purposes, all without asking permission. You should have received a copy of
* the creative commons license (CC0 1.0 universal) along with this program.
* See the license file for more information.
*
*
*********************************************************************************/
/******************************************************************************
*
* File: ntru_crypto_hash.c
*
* Contents: Routines implementing the hash object abstraction.
*
*****************************************************************************/
#include "ntru_crypto.h"
#include "ntru_crypto_hash.h"
typedef uint32_t (*NTRU_CRYPTO_HASH_INIT_FN)(
void *c);
typedef uint32_t (*NTRU_CRYPTO_HASH_UPDATE_FN)(
void *c,
void const *data,
uint32_t len);
typedef uint32_t (*NTRU_CRYPTO_HASH_FINAL_FN)(
void *c,
void *md);
typedef uint32_t (*NTRU_CRYPTO_HASH_DIGEST_FN)(
void const *data,
uint32_t len,
void *md);
typedef struct _NTRU_CRYPTO_HASH_ALG_PARAMS {
uint8_t algid;
uint16_t block_length;
uint16_t digest_length;
NTRU_CRYPTO_HASH_INIT_FN init;
NTRU_CRYPTO_HASH_UPDATE_FN update;
NTRU_CRYPTO_HASH_FINAL_FN final;
NTRU_CRYPTO_HASH_DIGEST_FN digest;
} NTRU_CRYPTO_HASH_ALG_PARAMS;
static NTRU_CRYPTO_HASH_ALG_PARAMS const algs_params[] = {
{
NTRU_CRYPTO_HASH_ALGID_SHA1,
SHA_1_BLK_LEN,
SHA_1_MD_LEN,
(NTRU_CRYPTO_HASH_INIT_FN) SHA_1_INIT_FN,
(NTRU_CRYPTO_HASH_UPDATE_FN) SHA_1_UPDATE_FN,
(NTRU_CRYPTO_HASH_FINAL_FN) SHA_1_FINAL_FN,
(NTRU_CRYPTO_HASH_DIGEST_FN) SHA_1_DIGEST_FN,
},
{
NTRU_CRYPTO_HASH_ALGID_SHA256,
SHA_256_BLK_LEN,
SHA_256_MD_LEN,
(NTRU_CRYPTO_HASH_INIT_FN) SHA_256_INIT_FN,
(NTRU_CRYPTO_HASH_UPDATE_FN) SHA_256_UPDATE_FN,
(NTRU_CRYPTO_HASH_FINAL_FN) SHA_256_FINAL_FN,
(NTRU_CRYPTO_HASH_DIGEST_FN) SHA_256_DIGEST_FN,
},
};
static int const numalgs = (sizeof(algs_params) / sizeof(algs_params[0]));
/* get_alg_params
*
* Return a pointer to the hash algorithm parameters for the hash algorithm
* specified, by looking for algid in the global algs_params table.
* If not found, return NULL.
*/
static NTRU_CRYPTO_HASH_ALG_PARAMS const *
get_alg_params(
NTRU_CRYPTO_HASH_ALGID algid) /* in - the hash algorithm to find */
{
int i;
for (i = 0; i < numalgs; i++) {
if (algs_params[i].algid == algid) {
return &algs_params[i];
}
}
return NULL;
}
/* ntru_crypto_hash_set_alg
*
* Sets the hash algorithm for the hash context. This must be called before
* any calls to ntru_crypto_hash_block_length(),
* ntru_crypto_hash_digest_length(), or ntru_crypto_hash_init() are made.
*
* Returns NTRU_CRYPTO_HASH_OK on success.
* Returns NTRU_CRYPTO_HASH_BAD_ALG if the specified algorithm is not supported.
*/
uint32_t
ntru_crypto_hash_set_alg(
NTRU_CRYPTO_HASH_ALGID algid, /* in - hash algorithm to be used */
NTRU_CRYPTO_HASH_CTX *c) /* in/out - pointer to the hash context */
{
if (!c) {
HASH_RET(NTRU_CRYPTO_HASH_BAD_PARAMETER);
}
c->alg_params = get_alg_params(algid);
if (!c->alg_params) {
HASH_RET(NTRU_CRYPTO_HASH_BAD_ALG);
}
HASH_RET(NTRU_CRYPTO_HASH_OK);
}
/* ntru_crypto_hash_block_length
*
* Gets the number of bytes in an input block for the hash algorithm
* specified in the hash context. The hash algorithm must have been set
* in the hash context with a call to ntru_crypto_hash_set_alg() prior to
* calling this function.
*
* Returns NTRU_CRYPTO_HASH_OK on success.
* Returns NTRU_CRYPTO_HASH_BAD_PARAMETER if inappropriate NULL pointers are
* passed.
* Returns NTRU_CRYPTO_HASH_BAD_ALG if the algorithm has not been set.
*/
uint32_t
ntru_crypto_hash_block_length(
NTRU_CRYPTO_HASH_CTX *c, /* in - pointer to the hash context */
uint16_t *blk_len) /* out - address for block length in bytes */
{
if (!c || !blk_len) {
HASH_RET(NTRU_CRYPTO_HASH_BAD_PARAMETER);
}
if (!c->alg_params) {
HASH_RET(NTRU_CRYPTO_HASH_BAD_ALG);
}
*blk_len = c->alg_params->block_length;
HASH_RET(NTRU_CRYPTO_HASH_OK);
}
/* ntru_crypto_hash_digest_length
*
* Gets the number of bytes needed to hold the message digest for the
* hash algorithm specified in the hash context. The algorithm must have
* been set in the hash context with a call to ntru_crypto_hash_set_alg() prior
* to calling this function.
*
* Returns NTRU_CRYPTO_HASH_OK on success.
* Returns NTRU_CRYPTO_HASH_BAD_PARAMETER if inappropriate NULL pointers are
* passed.
* Returns NTRU_CRYPTO_HASH_BAD_ALG if the algorithm has not been set.
*/
uint32_t
ntru_crypto_hash_digest_length(
NTRU_CRYPTO_HASH_CTX const *c, /* in - pointer to the hash context */
uint16_t *md_len) /* out - addr for digest length in bytes */
{
if (!c || !md_len) {
HASH_RET(NTRU_CRYPTO_HASH_BAD_PARAMETER);
}
if (!c->alg_params) {
HASH_RET(NTRU_CRYPTO_HASH_BAD_ALG);
}
*md_len = c->alg_params->digest_length;
HASH_RET(NTRU_CRYPTO_HASH_OK);
}
/* ntru_crypto_hash_init
*
* This routine performs standard initialization of the hash state.
*
* Returns NTRU_CRYPTO_HASH_OK on success.
* Returns NTRU_CRYPTO_HASH_FAIL with corrupted context.
* Returns NTRU_CRYPTO_HASH_BAD_PARAMETER if inappropriate NULL pointers are
* passed.
* Returns NTRU_CRYPTO_HASH_BAD_ALG if the algorithm has not been set.
*/
uint32_t
ntru_crypto_hash_init(
NTRU_CRYPTO_HASH_CTX *c) /* in/out - pointer to hash context */
{
if (!c) {
HASH_RET(NTRU_CRYPTO_HASH_BAD_PARAMETER);
}
if (!c->alg_params) {
HASH_RET(NTRU_CRYPTO_HASH_BAD_ALG);
}
return c->alg_params->init(&c->alg_ctx);
}
/* ntru_crypto_hash_update
*
* This routine processes input data and updates the hash calculation.
*
* Returns NTRU_CRYPTO_HASH_OK on success.
* Returns NTRU_CRYPTO_HASH_FAIL with corrupted context.
* Returns NTRU_CRYPTO_HASH_BAD_PARAMETER if inappropriate NULL pointers are
* passed.
* Returns NTRU_CRYPTO_HASH_OVERFLOW if too much text has been fed to the
* hash algorithm. The size limit is dependent on the hash algorithm,
* and not all algorithms have this limit.
* Returns NTRU_CRYPTO_HASH_BAD_ALG if the algorithm has not been set.
*/
uint32_t
ntru_crypto_hash_update(
NTRU_CRYPTO_HASH_CTX *c, /* in/out - pointer to hash context */
uint8_t const *data, /* in - pointer to input data */
uint32_t data_len) /* in - number of bytes of input data */
{
if (!c || (data_len && !data)) {
HASH_RET(NTRU_CRYPTO_HASH_BAD_PARAMETER);
}
if (!c->alg_params) {
HASH_RET(NTRU_CRYPTO_HASH_BAD_ALG);
}
return c->alg_params->update(&c->alg_ctx, data, data_len);
}
/* ntru_crypto_hash_final
*
* This routine completes the hash calculation and returns the message digest.
*
* Returns NTRU_CRYPTO_HASH_OK on success.
* Returns NTRU_CRYPTO_HASH_FAIL with corrupted context.
* Returns NTRU_CRYPTO_HASH_BAD_PARAMETER if inappropriate NULL pointers are
* passed.
* Returns NTRU_CRYPTO_HASH_BAD_ALG if the algorithm has not been set.
*/
uint32_t
ntru_crypto_hash_final(
NTRU_CRYPTO_HASH_CTX *c, /* in/out - pointer to hash context */
uint8_t *md) /* out - address for message digest */
{
if (!c || !md) {
HASH_RET(NTRU_CRYPTO_HASH_BAD_PARAMETER);
}
if (!c->alg_params) {
HASH_RET(NTRU_CRYPTO_HASH_BAD_ALG);
}
return c->alg_params->final(&c->alg_ctx, md);
}
/* ntru_crypto_hash_digest
*
* This routine computes a message digest. It is assumed that the
* output buffer md is large enough to hold the output (see
* ntru_crypto_hash_digest_length)
*
* Returns NTRU_CRYPTO_HASH_OK on success.
* Returns NTRU_CRYPTO_HASH_FAIL with corrupted context.
* Returns NTRU_CRYPTO_HASH_BAD_PARAMETER if inappropriate NULL pointers are
* passed.
* Returns NTRU_CRYPTO_HASH_OVERFLOW if too much text has been fed to the
* hash algorithm. The size limit is dependent on the hash algorithm,
* and not all algorithms have this limit.
* Returns NTRU_CRYPTO_HASH_BAD_ALG if the specified algorithm is not supported.
*/
uint32_t
ntru_crypto_hash_digest(
NTRU_CRYPTO_HASH_ALGID algid, /* in - the hash algorithm to use */
uint8_t const *data, /* in - pointer to input data */
uint32_t data_len, /* in - number of bytes of input data */
uint8_t *md) /* out - address for message digest */
{
NTRU_CRYPTO_HASH_ALG_PARAMS const *alg_params = get_alg_params(algid);
if (!alg_params) {
HASH_RET(NTRU_CRYPTO_HASH_BAD_ALG);
}
if ((data_len && !data) || !md) {
HASH_RET(NTRU_CRYPTO_HASH_BAD_PARAMETER);
}
return alg_params->digest(data, data_len, md);
}