mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-09-25 23:04:10 +08:00
308 lines
9.1 KiB
C
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);
|
|
}
|