mirror of
https://github.com/cryb-to/cryb-to.git
synced 2024-12-22 12:31:07 +00:00
Import sha256 from libcperciva
Import md2, md4, sha384 and sha512 from XySSL
This commit is contained in:
parent
0d22f2f203
commit
593125c353
22 changed files with 4056 additions and 29 deletions
|
@ -10,6 +10,8 @@ cryb_HEADERS = \
|
|||
hmac.h \
|
||||
hotp.h \
|
||||
mac.h \
|
||||
md2.h \
|
||||
md4.h \
|
||||
md5.h \
|
||||
oath.h \
|
||||
oath_constants.h \
|
||||
|
@ -18,6 +20,9 @@ cryb_HEADERS = \
|
|||
rfc3986.h \
|
||||
rfc4648.h \
|
||||
sha1.h \
|
||||
sha256.h \
|
||||
sha384.h \
|
||||
sha512.h \
|
||||
to.h \
|
||||
totp.h \
|
||||
version.h
|
||||
|
|
141
include/cryb/md2.h
Normal file
141
include/cryb/md2.h
Normal file
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2007 Christophe Devine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Cryb$
|
||||
*/
|
||||
|
||||
#ifndef CRYB_MD2_H_INCLUDED
|
||||
#define CRYB_MD2_H_INCLUDED
|
||||
|
||||
#define MD2_DIGEST_LEN 16
|
||||
|
||||
#define md2_digest cryb_md2_digest
|
||||
#define md2_ctx cryb_md2_ctx
|
||||
#define md2_init cryb_md2_init
|
||||
#define md2_update cryb_md2_update
|
||||
#define md2_final cryb_md2_final
|
||||
#define md2_complete cryb_md2_complete
|
||||
|
||||
extern struct digest_algorithm md2_digest;
|
||||
|
||||
/**
|
||||
* \brief MD2 context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
unsigned char cksum[16]; /*!< checksum of the data block */
|
||||
unsigned char state[48]; /*!< intermediate digest state */
|
||||
unsigned char buffer[16]; /*!< data block being processed */
|
||||
|
||||
unsigned char ipad[64]; /*!< HMAC: inner padding */
|
||||
unsigned char opad[64]; /*!< HMAC: outer padding */
|
||||
int left; /*!< amount of data in buffer */
|
||||
}
|
||||
md2_ctx;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief MD2 context setup
|
||||
*
|
||||
* \param ctx context to be initialized
|
||||
*/
|
||||
void md2_init( md2_ctx *ctx );
|
||||
|
||||
/**
|
||||
* \brief MD2 process buffer
|
||||
*
|
||||
* \param ctx MD2 context
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
*/
|
||||
void md2_update( md2_ctx *ctx, const void *input, int ilen );
|
||||
|
||||
/**
|
||||
* \brief MD2 final digest
|
||||
*
|
||||
* \param ctx MD2 context
|
||||
* \param output MD2 checksum result
|
||||
*/
|
||||
void md2_final( md2_ctx *ctx, unsigned char output[16] );
|
||||
|
||||
/**
|
||||
* \brief Output = MD2( input buffer )
|
||||
*
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
* \param output MD2 checksum result
|
||||
*/
|
||||
void md2_complete( const void *input, int ilen, unsigned char output[16] );
|
||||
|
||||
/**
|
||||
* \brief MD2 HMAC context setup
|
||||
*
|
||||
* \param ctx HMAC context to be initialized
|
||||
* \param key HMAC secret key
|
||||
* \param keylen length of the HMAC key
|
||||
*/
|
||||
void md2_hmac_init( md2_ctx *ctx, unsigned char *key, int keylen );
|
||||
|
||||
/**
|
||||
* \brief MD2 HMAC process buffer
|
||||
*
|
||||
* \param ctx HMAC context
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
*/
|
||||
void md2_hmac_update( md2_ctx *ctx, unsigned char *input, int ilen );
|
||||
|
||||
/**
|
||||
* \brief MD2 HMAC final digest
|
||||
*
|
||||
* \param ctx HMAC context
|
||||
* \param output MD2 HMAC checksum result
|
||||
*/
|
||||
void md2_hmac_final( md2_ctx *ctx, unsigned char output[16] );
|
||||
|
||||
/**
|
||||
* \brief Output = HMAC-MD2( hmac key, input buffer )
|
||||
*
|
||||
* \param key HMAC secret key
|
||||
* \param keylen length of the HMAC key
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
* \param output HMAC-MD2 result
|
||||
*/
|
||||
void md2_hmac_complete( unsigned char *key, int keylen,
|
||||
unsigned char *input, int ilen,
|
||||
unsigned char output[16] );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* md2.h */
|
140
include/cryb/md4.h
Normal file
140
include/cryb/md4.h
Normal file
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2007 Christophe Devine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Cryb$
|
||||
*/
|
||||
|
||||
#ifndef CRYB_MD4_H_INCLUDED
|
||||
#define CRYB_MD4_H_INCLUDED
|
||||
|
||||
#define MD4_DIGEST_LEN 16
|
||||
|
||||
#define md4_digest cryb_md4_digest
|
||||
#define md4_ctx cryb_md4_ctx
|
||||
#define md4_init cryb_md4_init
|
||||
#define md4_update cryb_md4_update
|
||||
#define md4_final cryb_md4_final
|
||||
#define md4_complete cryb_md4_complete
|
||||
|
||||
extern struct digest_algorithm md4_digest;
|
||||
|
||||
/**
|
||||
* \brief MD4 context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
unsigned long total[2]; /*!< number of bytes processed */
|
||||
unsigned long state[4]; /*!< intermediate digest state */
|
||||
unsigned char buffer[64]; /*!< data block being processed */
|
||||
|
||||
unsigned char ipad[64]; /*!< HMAC: inner padding */
|
||||
unsigned char opad[64]; /*!< HMAC: outer padding */
|
||||
}
|
||||
md4_ctx;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief MD4 context setup
|
||||
*
|
||||
* \param ctx context to be initialized
|
||||
*/
|
||||
void md4_init( md4_ctx *ctx );
|
||||
|
||||
/**
|
||||
* \brief MD4 process buffer
|
||||
*
|
||||
* \param ctx MD4 context
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
*/
|
||||
void md4_update( md4_ctx *ctx, const void *input, int ilen );
|
||||
|
||||
/**
|
||||
* \brief MD4 final digest
|
||||
*
|
||||
* \param ctx MD4 context
|
||||
* \param output MD4 checksum result
|
||||
*/
|
||||
void md4_final( md4_ctx *ctx, unsigned char output[16] );
|
||||
|
||||
/**
|
||||
* \brief Output = MD4( input buffer )
|
||||
*
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
* \param output MD4 checksum result
|
||||
*/
|
||||
void md4_complete( const void *input, int ilen, unsigned char output[16] );
|
||||
|
||||
/**
|
||||
* \brief MD4 HMAC context setup
|
||||
*
|
||||
* \param ctx HMAC context to be initialized
|
||||
* \param key HMAC secret key
|
||||
* \param keylen length of the HMAC key
|
||||
*/
|
||||
void md4_hmac_init( md4_ctx *ctx, unsigned char *key, int keylen );
|
||||
|
||||
/**
|
||||
* \brief MD4 HMAC process buffer
|
||||
*
|
||||
* \param ctx HMAC context
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
*/
|
||||
void md4_hmac_update( md4_ctx *ctx, unsigned char *input, int ilen );
|
||||
|
||||
/**
|
||||
* \brief MD4 HMAC final digest
|
||||
*
|
||||
* \param ctx HMAC context
|
||||
* \param output MD4 HMAC checksum result
|
||||
*/
|
||||
void md4_hmac_final( md4_ctx *ctx, unsigned char output[16] );
|
||||
|
||||
/**
|
||||
* \brief Output = HMAC-MD4( hmac key, input buffer )
|
||||
*
|
||||
* \param key HMAC secret key
|
||||
* \param keylen length of the HMAC key
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
* \param output HMAC-MD4 result
|
||||
*/
|
||||
void md4_hmac_complete( unsigned char *key, int keylen,
|
||||
unsigned char *input, int ilen,
|
||||
unsigned char output[16] );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -38,14 +38,14 @@
|
|||
|
||||
#define MD5_DIGEST_LEN 16
|
||||
|
||||
#define md5_algorithm cryb_md5_algorithm
|
||||
#define md5_digest cryb_md5_digest
|
||||
#define md5_ctx cryb_md5_ctx
|
||||
#define md5_init cryb_md5_init
|
||||
#define md5_update cryb_md5_update
|
||||
#define md5_final cryb_md5_final
|
||||
#define md5_complete cryb_md5_complete
|
||||
|
||||
extern struct digest_algorithm md5_algorithm;
|
||||
extern struct digest_algorithm md5_digest;
|
||||
|
||||
typedef struct md5_ctx {
|
||||
uint8_t block[64];
|
||||
|
|
|
@ -38,14 +38,14 @@
|
|||
|
||||
#define SHA1_DIGEST_LEN 20
|
||||
|
||||
#define sha1_algorithm cryb_sha1_algorithm
|
||||
#define sha1_digest cryb_sha1_digest
|
||||
#define sha1_ctx cryb_sha1_ctx
|
||||
#define sha1_init cryb_sha1_init
|
||||
#define sha1_update cryb_sha1_update
|
||||
#define sha1_final cryb_sha1_final
|
||||
#define sha1_complete cryb_sha1_complete
|
||||
|
||||
extern struct digest_algorithm sha1_algorithm;
|
||||
extern struct digest_algorithm sha1_digest;
|
||||
|
||||
typedef struct sha1_ctx {
|
||||
uint8_t block[64];
|
||||
|
|
126
include/cryb/sha256.h
Normal file
126
include/cryb/sha256.h
Normal file
|
@ -0,0 +1,126 @@
|
|||
/*-
|
||||
* Copyright (c) 2005-2013 Colin Percival
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Cryb$
|
||||
*/
|
||||
|
||||
#ifndef CRYB_SHA256_H_INCLUDED
|
||||
#define CRYB_SHA256_H_INCLUDED
|
||||
|
||||
#define SHA256_DIGEST_LEN 32
|
||||
|
||||
/*
|
||||
* Use #defines in order to avoid namespace collisions with anyone else's
|
||||
* SHA256 code (e.g., the code in OpenSSL).
|
||||
*/
|
||||
#define sha256_digest cryb_sha256_digest
|
||||
#define sha256_ctx cryb_sha256_ctx
|
||||
#define sha256_init cryb_sha256_init
|
||||
#define sha256_update cryb_sha256_update
|
||||
#define sha256_final cryb_sha256_final
|
||||
#define sha256_complete cryb_sha256_complete
|
||||
|
||||
extern struct digest_algorithm sha256_digest;
|
||||
|
||||
#define hmac_sha256_init cryb_hmac_sha256_init
|
||||
#define hmac_sha256_update cryb_hmac_sha256_update
|
||||
#define hmac_sha256_final cryb_hmac_sha256_final
|
||||
#define hmac_sha256_complete cryb_hmac_sha256_complete
|
||||
#define hmac_sha256_ctx cryb_hmac_sha256_ctx
|
||||
|
||||
/* Context structure for SHA256 operations. */
|
||||
typedef struct {
|
||||
uint32_t state[8];
|
||||
uint64_t count;
|
||||
uint8_t buf[64];
|
||||
} sha256_ctx;
|
||||
|
||||
/**
|
||||
* sha256_init(ctx):
|
||||
* Initialize the SHA256 context ${ctx}.
|
||||
*/
|
||||
void sha256_init(sha256_ctx *);
|
||||
|
||||
/**
|
||||
* sha256_update(ctx, in, len):
|
||||
* Input ${len} bytes from ${in} into the SHA256 context ${ctx}.
|
||||
*/
|
||||
void sha256_update(sha256_ctx *, const void *, size_t);
|
||||
|
||||
/**
|
||||
* sha256_final(ctx, digest):
|
||||
* Output the SHA256 hash of the data input to the context ${ctx} into the
|
||||
* buffer ${digest}.
|
||||
*/
|
||||
void sha256_final(sha256_ctx *, uint8_t[SHA256_DIGEST_LEN]);
|
||||
|
||||
/**
|
||||
* sha256_complete(in, len, digest):
|
||||
* Compute the SHA256 hash of ${len} bytes from $in} and write it to ${digest}.
|
||||
*/
|
||||
void sha256_complete(const void *, size_t, uint8_t[SHA256_DIGEST_LEN]);
|
||||
|
||||
/* Context structure for HMAC-SHA256 operations. */
|
||||
typedef struct {
|
||||
sha256_ctx ictx;
|
||||
sha256_ctx octx;
|
||||
} hmac_sha256_ctx;
|
||||
|
||||
/**
|
||||
* hmac_sha256_init(ctx, K, Klen):
|
||||
* Initialize the HMAC-SHA256 context ${ctx} with ${Klen} bytes of key from
|
||||
* ${K}.
|
||||
*/
|
||||
void hmac_sha256_init(hmac_sha256_ctx *, const void *, size_t);
|
||||
|
||||
/**
|
||||
* hmac_sha256_update(ctx, in, len):
|
||||
* Input ${len} bytes from ${in} into the HMAC-SHA256 context ${ctx}.
|
||||
*/
|
||||
void hmac_sha256_update(hmac_sha256_ctx *, const void *, size_t);
|
||||
|
||||
/**
|
||||
* hmac_sha256_final(ctx, digest):
|
||||
* Output the HMAC-SHA256 of the data input to the context ${ctx} into the
|
||||
* buffer ${digest}.
|
||||
*/
|
||||
void hmac_sha256_final(hmac_sha256_ctx *, uint8_t[SHA256_DIGEST_LEN]);
|
||||
|
||||
/**
|
||||
* hmac_sha256_complete(K, Klen, in, len, digest):
|
||||
* Compute the HMAC-SHA256 of ${len} bytes from ${in} using the key ${K} of
|
||||
* length ${Klen}, and write the result to ${digest}.
|
||||
*/
|
||||
void hmac_sha256_complete(const void *, size_t, const void *, size_t, uint8_t[32]);
|
||||
|
||||
/**
|
||||
* PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
|
||||
* Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
|
||||
* write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).
|
||||
*/
|
||||
void pbkdf2_sha256(const uint8_t *, size_t, const uint8_t *, size_t,
|
||||
uint64_t, uint8_t *, size_t);
|
||||
|
||||
#endif
|
141
include/cryb/sha384.h
Normal file
141
include/cryb/sha384.h
Normal file
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2007 Christophe Devine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Cryb$
|
||||
*/
|
||||
|
||||
#ifndef CRYB_SHA384_H_INCLUDED
|
||||
#define CRYB_SHA384_H_INCLUDED
|
||||
|
||||
#define SHA384_DIGEST_LEN 48
|
||||
|
||||
#define sha384_digest cryb_sha384_digest
|
||||
#define sha384_ctx cryb_sha384_ctx
|
||||
#define sha384_init cryb_sha384_init
|
||||
#define sha384_update cryb_sha384_update
|
||||
#define sha384_final cryb_sha384_final
|
||||
#define sha384_complete cryb_sha384_complete
|
||||
|
||||
extern struct digest_algorithm sha384_digest;
|
||||
|
||||
/**
|
||||
* \brief SHA-384 context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint64_t total[2]; /*!< number of bytes processed */
|
||||
uint64_t state[8]; /*!< intermediate digest state */
|
||||
uint8_t buffer[128]; /*!< data block being processed */
|
||||
|
||||
uint8_t ipad[128]; /*!< HMAC: inner padding */
|
||||
uint8_t opad[128]; /*!< HMAC: outer padding */
|
||||
}
|
||||
sha384_ctx;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief SHA-384 context setup
|
||||
*
|
||||
* \param ctx context to be initialized
|
||||
*/
|
||||
void sha384_init( sha384_ctx *ctx );
|
||||
|
||||
/**
|
||||
* \brief SHA-384 process buffer
|
||||
*
|
||||
* \param ctx SHA-384 context
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
*/
|
||||
void sha384_update( sha384_ctx *ctx, const void *input, int ilen );
|
||||
|
||||
/**
|
||||
* \brief SHA-384 final digest
|
||||
*
|
||||
* \param ctx SHA-384 context
|
||||
* \param output SHA-384/384 checksum result
|
||||
*/
|
||||
void sha384_final( sha384_ctx *ctx, unsigned char output[64] );
|
||||
|
||||
/**
|
||||
* \brief Output = SHA-384( input buffer )
|
||||
*
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
* \param output SHA-384/384 checksum result
|
||||
*/
|
||||
void sha384_complete( const void *input, int ilen,
|
||||
unsigned char output[64] );
|
||||
|
||||
/**
|
||||
* \brief SHA-384 HMAC context setup
|
||||
*
|
||||
* \param ctx HMAC context to be initialized
|
||||
* \param key HMAC secret key
|
||||
* \param keylen length of the HMAC key
|
||||
*/
|
||||
void sha384_hmac_init( sha384_ctx *ctx, unsigned char *key, int keylen );
|
||||
|
||||
/**
|
||||
* \brief SHA-384 HMAC process buffer
|
||||
*
|
||||
* \param ctx HMAC context
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
*/
|
||||
void sha384_hmac_update( sha384_ctx *ctx, unsigned char *input, int ilen );
|
||||
|
||||
/**
|
||||
* \brief SHA-384 HMAC final digest
|
||||
*
|
||||
* \param ctx HMAC context
|
||||
* \param output SHA-384/384 HMAC checksum result
|
||||
*/
|
||||
void sha384_hmac_final( sha384_ctx *ctx, unsigned char output[64] );
|
||||
|
||||
/**
|
||||
* \brief Output = HMAC-SHA-384( hmac key, input buffer )
|
||||
*
|
||||
* \param key HMAC secret key
|
||||
* \param keylen length of the HMAC key
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
* \param output HMAC-SHA-384/384 result
|
||||
*/
|
||||
void sha384_hmac_complete( unsigned char *key, int keylen,
|
||||
unsigned char *input, int ilen,
|
||||
unsigned char output[64] );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
141
include/cryb/sha512.h
Normal file
141
include/cryb/sha512.h
Normal file
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2007 Christophe Devine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Cryb$
|
||||
*/
|
||||
|
||||
#ifndef CRYB_SHA512_H_INCLUDED
|
||||
#define CRYB_SHA512_H_INCLUDED
|
||||
|
||||
#define SHA512_DIGEST_LEN 64
|
||||
|
||||
#define sha512_digest cryb_sha512_digest
|
||||
#define sha512_ctx cryb_sha512_ctx
|
||||
#define sha512_init cryb_sha512_init
|
||||
#define sha512_update cryb_sha512_update
|
||||
#define sha512_final cryb_sha512_final
|
||||
#define sha512_complete cryb_sha512_complete
|
||||
|
||||
extern struct digest_algorithm sha512_digest;
|
||||
|
||||
/**
|
||||
* \brief SHA-512 context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint64_t total[2]; /*!< number of bytes processed */
|
||||
uint64_t state[8]; /*!< intermediate digest state */
|
||||
uint8_t buffer[128]; /*!< data block being processed */
|
||||
|
||||
uint8_t ipad[128]; /*!< HMAC: inner padding */
|
||||
uint8_t opad[128]; /*!< HMAC: outer padding */
|
||||
}
|
||||
sha512_ctx;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief SHA-512 context setup
|
||||
*
|
||||
* \param ctx context to be initialized
|
||||
*/
|
||||
void sha512_init( sha512_ctx *ctx );
|
||||
|
||||
/**
|
||||
* \brief SHA-512 process buffer
|
||||
*
|
||||
* \param ctx SHA-512 context
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
*/
|
||||
void sha512_update( sha512_ctx *ctx, const void *input, int ilen );
|
||||
|
||||
/**
|
||||
* \brief SHA-512 final digest
|
||||
*
|
||||
* \param ctx SHA-512 context
|
||||
* \param output SHA-384/512 checksum result
|
||||
*/
|
||||
void sha512_final( sha512_ctx *ctx, unsigned char output[64] );
|
||||
|
||||
/**
|
||||
* \brief Output = SHA-512( input buffer )
|
||||
*
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
* \param output SHA-384/512 checksum result
|
||||
*/
|
||||
void sha512_complete( const void *input, int ilen,
|
||||
unsigned char output[64] );
|
||||
|
||||
/**
|
||||
* \brief SHA-512 HMAC context setup
|
||||
*
|
||||
* \param ctx HMAC context to be initialized
|
||||
* \param key HMAC secret key
|
||||
* \param keylen length of the HMAC key
|
||||
*/
|
||||
void sha512_hmac_init( sha512_ctx *ctx, unsigned char *key, int keylen );
|
||||
|
||||
/**
|
||||
* \brief SHA-512 HMAC process buffer
|
||||
*
|
||||
* \param ctx HMAC context
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
*/
|
||||
void sha512_hmac_update( sha512_ctx *ctx, unsigned char *input, int ilen );
|
||||
|
||||
/**
|
||||
* \brief SHA-512 HMAC final digest
|
||||
*
|
||||
* \param ctx HMAC context
|
||||
* \param output SHA-384/512 HMAC checksum result
|
||||
*/
|
||||
void sha512_hmac_final( sha512_ctx *ctx, unsigned char output[64] );
|
||||
|
||||
/**
|
||||
* \brief Output = HMAC-SHA-512( hmac key, input buffer )
|
||||
*
|
||||
* \param key HMAC secret key
|
||||
* \param keylen length of the HMAC key
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
* \param output HMAC-SHA-384/512 result
|
||||
*/
|
||||
void sha512_hmac_complete( unsigned char *key, int keylen,
|
||||
unsigned char *input, int ilen,
|
||||
unsigned char output[64] );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -5,5 +5,10 @@ AM_CPPFLAGS = -I$(top_srcdir)/include
|
|||
lib_LTLIBRARIES = libcryb-digest.la
|
||||
|
||||
libcryb_digest_la_SOURCES = \
|
||||
md2.c \
|
||||
md4.c \
|
||||
md5.c \
|
||||
sha1.c
|
||||
sha1.c \
|
||||
sha256.c \
|
||||
sha384.c \
|
||||
sha512.c
|
||||
|
|
257
lib/digest/md2.c
Normal file
257
lib/digest/md2.c
Normal file
|
@ -0,0 +1,257 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2007 Christophe Devine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Cryb$
|
||||
*/
|
||||
/*
|
||||
* The MD2 algorithm was designed by Ron Rivest in 1989.
|
||||
*
|
||||
* http://www.ietf.org/rfc/rfc1115.txt
|
||||
* http://www.ietf.org/rfc/rfc1319.txt
|
||||
*/
|
||||
|
||||
#include "cryb/impl.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <cryb/digest.h>
|
||||
#include <cryb/md2.h>
|
||||
|
||||
static const unsigned char PI_SUBST[256] =
|
||||
{
|
||||
0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36,
|
||||
0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, 0x62, 0xA7, 0x05, 0xF3,
|
||||
0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C,
|
||||
0x82, 0xCA, 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16,
|
||||
0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, 0xBE, 0x4E,
|
||||
0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E,
|
||||
0xBB, 0x2F, 0xEE, 0x7A, 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2,
|
||||
0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
|
||||
0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E,
|
||||
0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, 0xFF, 0x19, 0x30, 0xB3,
|
||||
0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56,
|
||||
0xAA, 0xC6, 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6,
|
||||
0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, 0x45, 0x9D,
|
||||
0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65,
|
||||
0xE6, 0x2D, 0xA8, 0x02, 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0,
|
||||
0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
|
||||
0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C,
|
||||
0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, 0x2C, 0x53, 0x0D, 0x6E,
|
||||
0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81,
|
||||
0x4D, 0x52, 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA,
|
||||
0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, 0x78, 0x88,
|
||||
0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE,
|
||||
0x3B, 0x00, 0x1D, 0x39, 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58,
|
||||
0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
|
||||
0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99,
|
||||
0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14
|
||||
};
|
||||
|
||||
/*
|
||||
* MD2 context setup
|
||||
*/
|
||||
void md2_init( md2_ctx *ctx )
|
||||
{
|
||||
memset( ctx, 0, sizeof( md2_ctx ) );
|
||||
}
|
||||
|
||||
static void md2_process( md2_ctx *ctx )
|
||||
{
|
||||
int i, j;
|
||||
unsigned char t = 0;
|
||||
|
||||
for( i = 0; i < 16; i++ )
|
||||
{
|
||||
ctx->state[i + 16] = ctx->buffer[i];
|
||||
ctx->state[i + 32] =
|
||||
(unsigned char)( ctx->buffer[i] ^ ctx->state[i]);
|
||||
}
|
||||
|
||||
for( i = 0; i < 18; i++ )
|
||||
{
|
||||
for( j = 0; j < 48; j++ )
|
||||
{
|
||||
ctx->state[j] = (unsigned char)
|
||||
( ctx->state[j] ^ PI_SUBST[t] );
|
||||
t = ctx->state[j];
|
||||
}
|
||||
|
||||
t = (unsigned char)( t + i );
|
||||
}
|
||||
|
||||
t = ctx->cksum[15];
|
||||
|
||||
for( i = 0; i < 16; i++ )
|
||||
{
|
||||
ctx->cksum[i] = (unsigned char)
|
||||
( ctx->cksum[i] ^ PI_SUBST[ctx->buffer[i] ^ t] );
|
||||
t = ctx->cksum[i];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* MD2 process buffer
|
||||
*/
|
||||
void md2_update( md2_ctx *ctx, const void *input, int ilen )
|
||||
{
|
||||
int fill;
|
||||
|
||||
while( ilen > 0 )
|
||||
{
|
||||
if( ctx->left + ilen > 16 )
|
||||
fill = 16 - ctx->left;
|
||||
else
|
||||
fill = ilen;
|
||||
|
||||
memcpy( ctx->buffer + ctx->left, input, fill );
|
||||
|
||||
ctx->left += fill;
|
||||
input += fill;
|
||||
ilen -= fill;
|
||||
|
||||
if( ctx->left == 16 )
|
||||
{
|
||||
ctx->left = 0;
|
||||
md2_process( ctx );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* MD2 final digest
|
||||
*/
|
||||
void md2_final( md2_ctx *ctx, unsigned char *output )
|
||||
{
|
||||
int i;
|
||||
unsigned char x;
|
||||
|
||||
x = (unsigned char)( 16 - ctx->left );
|
||||
|
||||
for( i = ctx->left; i < 16; i++ )
|
||||
ctx->buffer[i] = x;
|
||||
|
||||
md2_process( ctx );
|
||||
|
||||
memcpy( ctx->buffer, ctx->cksum, sizeof ctx->cksum );
|
||||
md2_process( ctx );
|
||||
|
||||
memcpy( output, ctx->state, MD2_DIGEST_LEN );
|
||||
}
|
||||
|
||||
/*
|
||||
* output = MD2( input buffer )
|
||||
*/
|
||||
void md2_complete( const void *input, int ilen, unsigned char *output )
|
||||
{
|
||||
md2_ctx ctx;
|
||||
|
||||
md2_init( &ctx );
|
||||
md2_update( &ctx, input, ilen );
|
||||
md2_final( &ctx, output );
|
||||
|
||||
memset( &ctx, 0, sizeof( md2_ctx ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* MD2 HMAC context setup
|
||||
*/
|
||||
void md2_hmac_init( md2_ctx *ctx, unsigned char *key, int keylen )
|
||||
{
|
||||
int i;
|
||||
unsigned char sum[MD2_DIGEST_LEN];
|
||||
|
||||
if( keylen > 64 )
|
||||
{
|
||||
md2_complete( key, keylen, sum );
|
||||
keylen = sizeof sum;
|
||||
key = sum;
|
||||
}
|
||||
|
||||
memset( ctx->ipad, 0x36, sizeof ctx->ipad );
|
||||
memset( ctx->opad, 0x5C, sizeof ctx->opad );
|
||||
|
||||
for( i = 0; i < keylen; i++ )
|
||||
{
|
||||
ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
|
||||
ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
|
||||
}
|
||||
|
||||
md2_init( ctx );
|
||||
md2_update( ctx, ctx->ipad, sizeof ctx->ipad );
|
||||
|
||||
memset( sum, 0, sizeof( sum ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* MD2 HMAC process buffer
|
||||
*/
|
||||
void md2_hmac_update( md2_ctx *ctx, unsigned char *input, int ilen )
|
||||
{
|
||||
md2_update( ctx, input, ilen );
|
||||
}
|
||||
|
||||
/*
|
||||
* MD2 HMAC final digest
|
||||
*/
|
||||
void md2_hmac_final( md2_ctx *ctx, unsigned char *output )
|
||||
{
|
||||
unsigned char tmpbuf[MD2_DIGEST_LEN];
|
||||
|
||||
md2_final( ctx, tmpbuf );
|
||||
md2_init( ctx );
|
||||
md2_update( ctx, ctx->opad, sizeof ctx->opad );
|
||||
md2_update( ctx, tmpbuf, sizeof tmpbuf );
|
||||
md2_final( ctx, output );
|
||||
|
||||
memset( tmpbuf, 0, sizeof( tmpbuf ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* output = HMAC-MD2( hmac key, input buffer )
|
||||
*/
|
||||
void md2_hmac_complete( unsigned char *key, int keylen, unsigned char *input, int ilen,
|
||||
unsigned char *output )
|
||||
{
|
||||
md2_ctx ctx;
|
||||
|
||||
md2_hmac_init( &ctx, key, keylen );
|
||||
md2_hmac_update( &ctx, input, ilen );
|
||||
md2_hmac_final( &ctx, output );
|
||||
|
||||
memset( &ctx, 0, sizeof( md2_ctx ) );
|
||||
}
|
||||
|
||||
struct digest_algorithm md2_digest = {
|
||||
.name = "md2",
|
||||
.contextlen = sizeof md2_digest,
|
||||
.digestlen = MD2_DIGEST_LEN,
|
||||
.init = (digest_init_func)md2_init,
|
||||
.update = (digest_update_func)md2_update,
|
||||
.final = (digest_final_func)md2_final,
|
||||
.complete = (digest_complete_func)md2_complete,
|
||||
};
|
356
lib/digest/md4.c
Normal file
356
lib/digest/md4.c
Normal file
|
@ -0,0 +1,356 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2007 Christophe Devine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Cryb$
|
||||
*/
|
||||
/*
|
||||
* The MD4 algorithm was designed by Ron Rivest in 1990.
|
||||
*
|
||||
* http://www.ietf.org/rfc/rfc1186.txt
|
||||
* http://www.ietf.org/rfc/rfc1320.txt
|
||||
*/
|
||||
|
||||
#include "cryb/impl.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <cryb/digest.h>
|
||||
#include <cryb/md4.h>
|
||||
|
||||
/*
|
||||
* 32-bit integer manipulation macros (little endian)
|
||||
*/
|
||||
#ifndef GET_ULONG_LE
|
||||
#define GET_ULONG_LE(n,b,i) \
|
||||
do { \
|
||||
(n) = ( (unsigned long) (b)[(i) ] ) \
|
||||
| ( (unsigned long) (b)[(i) + 1] << 8 ) \
|
||||
| ( (unsigned long) (b)[(i) + 2] << 16 ) \
|
||||
| ( (unsigned long) (b)[(i) + 3] << 24 ); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef PUT_ULONG_LE
|
||||
#define PUT_ULONG_LE(n,b,i) \
|
||||
do { \
|
||||
(b)[(i) ] = (unsigned char) ( (n) ); \
|
||||
(b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
|
||||
(b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
|
||||
(b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MD4 context setup
|
||||
*/
|
||||
void md4_init( md4_ctx *ctx )
|
||||
{
|
||||
ctx->total[0] = 0;
|
||||
ctx->total[1] = 0;
|
||||
|
||||
ctx->state[0] = 0x67452301;
|
||||
ctx->state[1] = 0xEFCDAB89;
|
||||
ctx->state[2] = 0x98BADCFE;
|
||||
ctx->state[3] = 0x10325476;
|
||||
}
|
||||
|
||||
static void md4_process( md4_ctx *ctx, const unsigned char *data )
|
||||
{
|
||||
unsigned long X[16], A, B, C, D;
|
||||
|
||||
GET_ULONG_LE( X[ 0], data, 0 );
|
||||
GET_ULONG_LE( X[ 1], data, 4 );
|
||||
GET_ULONG_LE( X[ 2], data, 8 );
|
||||
GET_ULONG_LE( X[ 3], data, 12 );
|
||||
GET_ULONG_LE( X[ 4], data, 16 );
|
||||
GET_ULONG_LE( X[ 5], data, 20 );
|
||||
GET_ULONG_LE( X[ 6], data, 24 );
|
||||
GET_ULONG_LE( X[ 7], data, 28 );
|
||||
GET_ULONG_LE( X[ 8], data, 32 );
|
||||
GET_ULONG_LE( X[ 9], data, 36 );
|
||||
GET_ULONG_LE( X[10], data, 40 );
|
||||
GET_ULONG_LE( X[11], data, 44 );
|
||||
GET_ULONG_LE( X[12], data, 48 );
|
||||
GET_ULONG_LE( X[13], data, 52 );
|
||||
GET_ULONG_LE( X[14], data, 56 );
|
||||
GET_ULONG_LE( X[15], data, 60 );
|
||||
|
||||
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
|
||||
|
||||
A = ctx->state[0];
|
||||
B = ctx->state[1];
|
||||
C = ctx->state[2];
|
||||
D = ctx->state[3];
|
||||
|
||||
#define F(x, y, z) ((x & y) | ((~x) & z))
|
||||
#define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); }
|
||||
|
||||
P( A, B, C, D, X[ 0], 3 );
|
||||
P( D, A, B, C, X[ 1], 7 );
|
||||
P( C, D, A, B, X[ 2], 11 );
|
||||
P( B, C, D, A, X[ 3], 19 );
|
||||
P( A, B, C, D, X[ 4], 3 );
|
||||
P( D, A, B, C, X[ 5], 7 );
|
||||
P( C, D, A, B, X[ 6], 11 );
|
||||
P( B, C, D, A, X[ 7], 19 );
|
||||
P( A, B, C, D, X[ 8], 3 );
|
||||
P( D, A, B, C, X[ 9], 7 );
|
||||
P( C, D, A, B, X[10], 11 );
|
||||
P( B, C, D, A, X[11], 19 );
|
||||
P( A, B, C, D, X[12], 3 );
|
||||
P( D, A, B, C, X[13], 7 );
|
||||
P( C, D, A, B, X[14], 11 );
|
||||
P( B, C, D, A, X[15], 19 );
|
||||
|
||||
#undef P
|
||||
#undef F
|
||||
|
||||
#define F(x,y,z) ((x & y) | (x & z) | (y & z))
|
||||
#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); }
|
||||
|
||||
P( A, B, C, D, X[ 0], 3 );
|
||||
P( D, A, B, C, X[ 4], 5 );
|
||||
P( C, D, A, B, X[ 8], 9 );
|
||||
P( B, C, D, A, X[12], 13 );
|
||||
P( A, B, C, D, X[ 1], 3 );
|
||||
P( D, A, B, C, X[ 5], 5 );
|
||||
P( C, D, A, B, X[ 9], 9 );
|
||||
P( B, C, D, A, X[13], 13 );
|
||||
P( A, B, C, D, X[ 2], 3 );
|
||||
P( D, A, B, C, X[ 6], 5 );
|
||||
P( C, D, A, B, X[10], 9 );
|
||||
P( B, C, D, A, X[14], 13 );
|
||||
P( A, B, C, D, X[ 3], 3 );
|
||||
P( D, A, B, C, X[ 7], 5 );
|
||||
P( C, D, A, B, X[11], 9 );
|
||||
P( B, C, D, A, X[15], 13 );
|
||||
|
||||
#undef P
|
||||
#undef F
|
||||
|
||||
#define F(x,y,z) (x ^ y ^ z)
|
||||
#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); }
|
||||
|
||||
P( A, B, C, D, X[ 0], 3 );
|
||||
P( D, A, B, C, X[ 8], 9 );
|
||||
P( C, D, A, B, X[ 4], 11 );
|
||||
P( B, C, D, A, X[12], 15 );
|
||||
P( A, B, C, D, X[ 2], 3 );
|
||||
P( D, A, B, C, X[10], 9 );
|
||||
P( C, D, A, B, X[ 6], 11 );
|
||||
P( B, C, D, A, X[14], 15 );
|
||||
P( A, B, C, D, X[ 1], 3 );
|
||||
P( D, A, B, C, X[ 9], 9 );
|
||||
P( C, D, A, B, X[ 5], 11 );
|
||||
P( B, C, D, A, X[13], 15 );
|
||||
P( A, B, C, D, X[ 3], 3 );
|
||||
P( D, A, B, C, X[11], 9 );
|
||||
P( C, D, A, B, X[ 7], 11 );
|
||||
P( B, C, D, A, X[15], 15 );
|
||||
|
||||
#undef F
|
||||
#undef P
|
||||
|
||||
ctx->state[0] += A;
|
||||
ctx->state[1] += B;
|
||||
ctx->state[2] += C;
|
||||
ctx->state[3] += D;
|
||||
}
|
||||
|
||||
/*
|
||||
* MD4 process buffer
|
||||
*/
|
||||
void md4_update( md4_ctx *ctx, const void *input, int ilen )
|
||||
{
|
||||
int fill;
|
||||
unsigned long left;
|
||||
|
||||
if( ilen <= 0 )
|
||||
return;
|
||||
|
||||
left = ctx->total[0] & 0x3F;
|
||||
fill = 64 - left;
|
||||
|
||||
ctx->total[0] += ilen;
|
||||
ctx->total[0] &= 0xFFFFFFFF;
|
||||
|
||||
if( ctx->total[0] < (unsigned long) ilen )
|
||||
ctx->total[1]++;
|
||||
|
||||
if( left && ilen >= fill )
|
||||
{
|
||||
memcpy( (void *) (ctx->buffer + left),
|
||||
(void *) input, fill );
|
||||
md4_process( ctx, ctx->buffer );
|
||||
input += fill;
|
||||
ilen -= fill;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
while( ilen >= 64 )
|
||||
{
|
||||
md4_process( ctx, input );
|
||||
input += 64;
|
||||
ilen -= 64;
|
||||
}
|
||||
|
||||
if( ilen > 0 )
|
||||
{
|
||||
memcpy( (void *) (ctx->buffer + left),
|
||||
(void *) input, ilen );
|
||||
}
|
||||
}
|
||||
|
||||
static const unsigned char md4_padding[64] =
|
||||
{
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/*
|
||||
* MD4 final digest
|
||||
*/
|
||||
void md4_final( md4_ctx *ctx, unsigned char *output )
|
||||
{
|
||||
unsigned long last, padn;
|
||||
unsigned long high, low;
|
||||
unsigned char msglen[8];
|
||||
|
||||
high = ( ctx->total[0] >> 29 )
|
||||
| ( ctx->total[1] << 3 );
|
||||
low = ( ctx->total[0] << 3 );
|
||||
|
||||
PUT_ULONG_LE( low, msglen, 0 );
|
||||
PUT_ULONG_LE( high, msglen, 4 );
|
||||
|
||||
last = ctx->total[0] & 0x3F;
|
||||
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
|
||||
|
||||
md4_update( ctx, md4_padding, padn );
|
||||
md4_update( ctx, msglen, 8 );
|
||||
|
||||
PUT_ULONG_LE( ctx->state[0], output, 0 );
|
||||
PUT_ULONG_LE( ctx->state[1], output, 4 );
|
||||
PUT_ULONG_LE( ctx->state[2], output, 8 );
|
||||
PUT_ULONG_LE( ctx->state[3], output, 12 );
|
||||
}
|
||||
|
||||
/*
|
||||
* output = MD4( input buffer )
|
||||
*/
|
||||
void md4_complete( const void *input, int ilen, unsigned char *output )
|
||||
{
|
||||
md4_ctx ctx;
|
||||
|
||||
md4_init( &ctx );
|
||||
md4_update( &ctx, input, ilen );
|
||||
md4_final( &ctx, output );
|
||||
|
||||
memset( &ctx, 0, sizeof( md4_ctx ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* MD4 HMAC context setup
|
||||
*/
|
||||
void md4_hmac_init( md4_ctx *ctx, unsigned char *key, int keylen )
|
||||
{
|
||||
int i;
|
||||
unsigned char sum[16];
|
||||
|
||||
if( keylen > 64 )
|
||||
{
|
||||
md4_complete( key, keylen, sum );
|
||||
keylen = 16;
|
||||
key = sum;
|
||||
}
|
||||
|
||||
memset( ctx->ipad, 0x36, 64 );
|
||||
memset( ctx->opad, 0x5C, 64 );
|
||||
|
||||
for( i = 0; i < keylen; i++ )
|
||||
{
|
||||
ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
|
||||
ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
|
||||
}
|
||||
|
||||
md4_init( ctx );
|
||||
md4_update( ctx, ctx->ipad, 64 );
|
||||
|
||||
memset( sum, 0, sizeof( sum ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* MD4 HMAC process buffer
|
||||
*/
|
||||
void md4_hmac_update( md4_ctx *ctx, unsigned char *input, int ilen )
|
||||
{
|
||||
md4_update( ctx, input, ilen );
|
||||
}
|
||||
|
||||
/*
|
||||
* MD4 HMAC final digest
|
||||
*/
|
||||
void md4_hmac_final( md4_ctx *ctx, unsigned char *output )
|
||||
{
|
||||
unsigned char tmpbuf[MD4_DIGEST_LEN];
|
||||
|
||||
md4_final( ctx, tmpbuf );
|
||||
md4_init( ctx );
|
||||
md4_update( ctx, ctx->opad, 64 );
|
||||
md4_update( ctx, tmpbuf, 16 );
|
||||
md4_final( ctx, output );
|
||||
|
||||
memset( tmpbuf, 0, sizeof( tmpbuf ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* output = HMAC-MD4( hmac key, input buffer )
|
||||
*/
|
||||
void md4_hmac_complete( unsigned char *key, int keylen, unsigned char *input, int ilen,
|
||||
unsigned char output[16] )
|
||||
{
|
||||
md4_ctx ctx;
|
||||
|
||||
md4_hmac_init( &ctx, key, keylen );
|
||||
md4_hmac_update( &ctx, input, ilen );
|
||||
md4_hmac_final( &ctx, output );
|
||||
|
||||
memset( &ctx, 0, sizeof( md4_ctx ) );
|
||||
}
|
||||
|
||||
struct digest_algorithm md4_digest = {
|
||||
.name = "md4",
|
||||
.contextlen = sizeof md4_digest,
|
||||
.digestlen = MD4_DIGEST_LEN,
|
||||
.init = (digest_init_func)md4_init,
|
||||
.update = (digest_update_func)md4_update,
|
||||
.final = (digest_final_func)md4_final,
|
||||
.complete = (digest_complete_func)md4_complete,
|
||||
};
|
|
@ -35,10 +35,6 @@
|
|||
|
||||
#include "cryb/impl.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_SYS_ENDIAN_H
|
||||
#include <sys/endian.h>
|
||||
#endif
|
||||
|
@ -48,6 +44,9 @@
|
|||
#include <endian.h>
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <cryb/digest.h>
|
||||
#include <cryb/bitwise.h>
|
||||
#include <cryb/md5.h>
|
||||
|
@ -209,19 +208,19 @@ md5_update(struct md5_ctx *ctx, const void *buf, size_t len)
|
|||
size_t copylen;
|
||||
|
||||
while (len) {
|
||||
if (ctx->blocklen > 0 || len < 64) {
|
||||
copylen = 64 - ctx->blocklen;
|
||||
if (ctx->blocklen > 0 || len < sizeof ctx->block) {
|
||||
copylen = sizeof ctx->block - ctx->blocklen;
|
||||
if (copylen > len)
|
||||
copylen = len;
|
||||
memcpy(ctx->block + ctx->blocklen, buf, copylen);
|
||||
ctx->blocklen += copylen;
|
||||
if (ctx->blocklen == 64) {
|
||||
if (ctx->blocklen == sizeof ctx->block) {
|
||||
md5_compute(ctx, ctx->block);
|
||||
ctx->blocklen = 0;
|
||||
memset(ctx->block, 0, 64);
|
||||
memset(ctx->block, 0, sizeof ctx->block);
|
||||
}
|
||||
} else {
|
||||
copylen = 64;
|
||||
copylen = sizeof ctx->block;
|
||||
md5_compute(ctx, buf);
|
||||
}
|
||||
ctx->bitlen += copylen * 8;
|
||||
|
@ -238,7 +237,7 @@ md5_final(struct md5_ctx *ctx, void *digest)
|
|||
if (ctx->blocklen > 56) {
|
||||
md5_compute(ctx, ctx->block);
|
||||
ctx->blocklen = 0;
|
||||
memset(ctx->block, 0, 64);
|
||||
memset(ctx->block, 0, sizeof ctx->block);
|
||||
}
|
||||
le32enc(ctx->block + 56, ctx->bitlen & 0xffffffffUL);
|
||||
le32enc(ctx->block + 60, ctx->bitlen >> 32);
|
||||
|
|
|
@ -35,10 +35,6 @@
|
|||
|
||||
#include "cryb/impl.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_SYS_ENDIAN_H
|
||||
#include <sys/endian.h>
|
||||
#endif
|
||||
|
@ -48,6 +44,9 @@
|
|||
#include <endian.h>
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <cryb/digest.h>
|
||||
#include <cryb/bitwise.h>
|
||||
|
||||
|
@ -119,19 +118,19 @@ sha1_update(struct sha1_ctx *ctx, const void *buf, size_t len)
|
|||
size_t copylen;
|
||||
|
||||
while (len) {
|
||||
if (ctx->blocklen > 0 || len < 64) {
|
||||
if (ctx->blocklen > 0 || len < sizeof ctx->block) {
|
||||
copylen = sizeof ctx->block - ctx->blocklen;
|
||||
if (copylen > len)
|
||||
copylen = len;
|
||||
memcpy(ctx->block + ctx->blocklen, buf, copylen);
|
||||
ctx->blocklen += copylen;
|
||||
if (ctx->blocklen == 64) {
|
||||
if (ctx->blocklen == sizeof ctx->block) {
|
||||
sha1_compute(ctx, ctx->block);
|
||||
ctx->blocklen = 0;
|
||||
memset(ctx->block, 0, 64);
|
||||
memset(ctx->block, 0, sizeof ctx->block);
|
||||
}
|
||||
} else {
|
||||
copylen = 64;
|
||||
copylen = sizeof ctx->block;
|
||||
sha1_compute(ctx, buf);
|
||||
}
|
||||
ctx->bitlen += copylen * 8;
|
||||
|
@ -149,7 +148,7 @@ sha1_final(struct sha1_ctx *ctx, void *digest)
|
|||
if (ctx->blocklen > 56) {
|
||||
sha1_compute(ctx, ctx->block);
|
||||
ctx->blocklen = 0;
|
||||
memset(ctx->block, 0, 64);
|
||||
memset(ctx->block, 0, sizeof ctx->block);
|
||||
}
|
||||
hi = htobe32(ctx->bitlen >> 32);
|
||||
lo = htobe32(ctx->bitlen & 0xffffffffUL);
|
||||
|
|
477
lib/digest/sha256.c
Normal file
477
lib/digest/sha256.c
Normal file
|
@ -0,0 +1,477 @@
|
|||
/*-
|
||||
* Copyright (c) 2005-2013 Colin Percival
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Cryb$
|
||||
*/
|
||||
|
||||
#include "cryb/impl.h"
|
||||
|
||||
#ifdef HAVE_SYS_ENDIAN_H
|
||||
#include <sys/endian.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ENDIAN_H
|
||||
#define _BSD_SOURCE
|
||||
#include <endian.h>
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <cryb/digest.h>
|
||||
#include <cryb/sha256.h>
|
||||
|
||||
/*
|
||||
* Encode a length len/4 vector of (uint32_t) into a length len vector of
|
||||
* (uint8_t) in big-endian form. Assumes len is a multiple of 4.
|
||||
*/
|
||||
static void
|
||||
be32enc_vect(uint8_t *dst, const uint32_t *src, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < len / 4; i++)
|
||||
be32enc(dst + i * 4, src[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode a big-endian length len vector of (uint8_t) into a length
|
||||
* len/4 vector of (uint32_t). Assumes len is a multiple of 4.
|
||||
*/
|
||||
static void
|
||||
be32dec_vect(uint32_t *dst, const uint8_t *src, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < len / 4; i++)
|
||||
dst[i] = be32dec(src + i * 4);
|
||||
}
|
||||
|
||||
/* Elementary functions used by SHA256 */
|
||||
#define Ch(x, y, z) ((x & (y ^ z)) ^ z)
|
||||
#define Maj(x, y, z) ((x & (y | z)) | (y & z))
|
||||
#define SHR(x, n) (x >> n)
|
||||
#define ROTR(x, n) ((x >> n) | (x << (32 - n)))
|
||||
#define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
|
||||
#define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
|
||||
#define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
|
||||
#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
|
||||
|
||||
/* SHA256 round function */
|
||||
#define RND(a, b, c, d, e, f, g, h, k) \
|
||||
t0 = h + S1(e) + Ch(e, f, g) + k; \
|
||||
t1 = S0(a) + Maj(a, b, c); \
|
||||
d += t0; \
|
||||
h = t0 + t1;
|
||||
|
||||
/* Adjusted round function for rotating state */
|
||||
#define RNDr(S, W, i, k) \
|
||||
RND(S[(64 - i) % 8], S[(65 - i) % 8], \
|
||||
S[(66 - i) % 8], S[(67 - i) % 8], \
|
||||
S[(68 - i) % 8], S[(69 - i) % 8], \
|
||||
S[(70 - i) % 8], S[(71 - i) % 8], \
|
||||
W[i] + k)
|
||||
|
||||
/*
|
||||
* SHA256 block compression function. The 256-bit state is transformed via
|
||||
* the 512-bit input block to produce a new state.
|
||||
*/
|
||||
static void
|
||||
sha256_Transform(uint32_t * state, const uint8_t block[64])
|
||||
{
|
||||
uint32_t W[64];
|
||||
uint32_t S[8];
|
||||
uint32_t t0, t1;
|
||||
int i;
|
||||
|
||||
/* 1. Prepare message schedule W. */
|
||||
be32dec_vect(W, block, 64);
|
||||
for (i = 16; i < 64; i++)
|
||||
W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];
|
||||
|
||||
/* 2. Initialize working variables. */
|
||||
memcpy(S, state, 32);
|
||||
|
||||
/* 3. Mix. */
|
||||
RNDr(S, W, 0, 0x428a2f98);
|
||||
RNDr(S, W, 1, 0x71374491);
|
||||
RNDr(S, W, 2, 0xb5c0fbcf);
|
||||
RNDr(S, W, 3, 0xe9b5dba5);
|
||||
RNDr(S, W, 4, 0x3956c25b);
|
||||
RNDr(S, W, 5, 0x59f111f1);
|
||||
RNDr(S, W, 6, 0x923f82a4);
|
||||
RNDr(S, W, 7, 0xab1c5ed5);
|
||||
RNDr(S, W, 8, 0xd807aa98);
|
||||
RNDr(S, W, 9, 0x12835b01);
|
||||
RNDr(S, W, 10, 0x243185be);
|
||||
RNDr(S, W, 11, 0x550c7dc3);
|
||||
RNDr(S, W, 12, 0x72be5d74);
|
||||
RNDr(S, W, 13, 0x80deb1fe);
|
||||
RNDr(S, W, 14, 0x9bdc06a7);
|
||||
RNDr(S, W, 15, 0xc19bf174);
|
||||
RNDr(S, W, 16, 0xe49b69c1);
|
||||
RNDr(S, W, 17, 0xefbe4786);
|
||||
RNDr(S, W, 18, 0x0fc19dc6);
|
||||
RNDr(S, W, 19, 0x240ca1cc);
|
||||
RNDr(S, W, 20, 0x2de92c6f);
|
||||
RNDr(S, W, 21, 0x4a7484aa);
|
||||
RNDr(S, W, 22, 0x5cb0a9dc);
|
||||
RNDr(S, W, 23, 0x76f988da);
|
||||
RNDr(S, W, 24, 0x983e5152);
|
||||
RNDr(S, W, 25, 0xa831c66d);
|
||||
RNDr(S, W, 26, 0xb00327c8);
|
||||
RNDr(S, W, 27, 0xbf597fc7);
|
||||
RNDr(S, W, 28, 0xc6e00bf3);
|
||||
RNDr(S, W, 29, 0xd5a79147);
|
||||
RNDr(S, W, 30, 0x06ca6351);
|
||||
RNDr(S, W, 31, 0x14292967);
|
||||
RNDr(S, W, 32, 0x27b70a85);
|
||||
RNDr(S, W, 33, 0x2e1b2138);
|
||||
RNDr(S, W, 34, 0x4d2c6dfc);
|
||||
RNDr(S, W, 35, 0x53380d13);
|
||||
RNDr(S, W, 36, 0x650a7354);
|
||||
RNDr(S, W, 37, 0x766a0abb);
|
||||
RNDr(S, W, 38, 0x81c2c92e);
|
||||
RNDr(S, W, 39, 0x92722c85);
|
||||
RNDr(S, W, 40, 0xa2bfe8a1);
|
||||
RNDr(S, W, 41, 0xa81a664b);
|
||||
RNDr(S, W, 42, 0xc24b8b70);
|
||||
RNDr(S, W, 43, 0xc76c51a3);
|
||||
RNDr(S, W, 44, 0xd192e819);
|
||||
RNDr(S, W, 45, 0xd6990624);
|
||||
RNDr(S, W, 46, 0xf40e3585);
|
||||
RNDr(S, W, 47, 0x106aa070);
|
||||
RNDr(S, W, 48, 0x19a4c116);
|
||||
RNDr(S, W, 49, 0x1e376c08);
|
||||
RNDr(S, W, 50, 0x2748774c);
|
||||
RNDr(S, W, 51, 0x34b0bcb5);
|
||||
RNDr(S, W, 52, 0x391c0cb3);
|
||||
RNDr(S, W, 53, 0x4ed8aa4a);
|
||||
RNDr(S, W, 54, 0x5b9cca4f);
|
||||
RNDr(S, W, 55, 0x682e6ff3);
|
||||
RNDr(S, W, 56, 0x748f82ee);
|
||||
RNDr(S, W, 57, 0x78a5636f);
|
||||
RNDr(S, W, 58, 0x84c87814);
|
||||
RNDr(S, W, 59, 0x8cc70208);
|
||||
RNDr(S, W, 60, 0x90befffa);
|
||||
RNDr(S, W, 61, 0xa4506ceb);
|
||||
RNDr(S, W, 62, 0xbef9a3f7);
|
||||
RNDr(S, W, 63, 0xc67178f2);
|
||||
|
||||
/* 4. Mix local working variables into global state. */
|
||||
for (i = 0; i < 8; i++)
|
||||
state[i] += S[i];
|
||||
|
||||
/* Clean the stack. */
|
||||
memset(W, 0, 256);
|
||||
memset(S, 0, 32);
|
||||
t0 = t1 = 0;
|
||||
}
|
||||
|
||||
static uint8_t PAD[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/* Add padding and terminating bit-count. */
|
||||
static void
|
||||
sha256_pad(sha256_ctx * ctx)
|
||||
{
|
||||
uint8_t len[8];
|
||||
uint32_t r, plen;
|
||||
|
||||
/*
|
||||
* Convert length to a vector of bytes -- we do this now rather
|
||||
* than later because the length will change after we pad.
|
||||
*/
|
||||
be64enc(len, ctx->count);
|
||||
|
||||
/* Add 1--64 bytes so that the resulting length is 56 mod 64. */
|
||||
r = (ctx->count >> 3) & 0x3f;
|
||||
plen = (r < 56) ? (56 - r) : (120 - r);
|
||||
sha256_update(ctx, PAD, (size_t)plen);
|
||||
|
||||
/* Add the terminating bit-count. */
|
||||
sha256_update(ctx, len, 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* sha256_init(ctx):
|
||||
* Initialize the SHA256 context ${ctx}.
|
||||
*/
|
||||
void
|
||||
sha256_init(sha256_ctx * ctx)
|
||||
{
|
||||
|
||||
/* Zero bits processed so far. */
|
||||
ctx->count = 0;
|
||||
|
||||
/* Magic initialization constants. */
|
||||
ctx->state[0] = 0x6A09E667;
|
||||
ctx->state[1] = 0xBB67AE85;
|
||||
ctx->state[2] = 0x3C6EF372;
|
||||
ctx->state[3] = 0xA54FF53A;
|
||||
ctx->state[4] = 0x510E527F;
|
||||
ctx->state[5] = 0x9B05688C;
|
||||
ctx->state[6] = 0x1F83D9AB;
|
||||
ctx->state[7] = 0x5BE0CD19;
|
||||
}
|
||||
|
||||
/**
|
||||
* sha256_update(ctx, in, len):
|
||||
* Input ${len} bytes from ${in} into the SHA256 context ${ctx}.
|
||||
*/
|
||||
void
|
||||
sha256_update(sha256_ctx * ctx, const void *in, size_t len)
|
||||
{
|
||||
uint32_t r;
|
||||
const uint8_t *src = in;
|
||||
|
||||
/* Return immediately if we have nothing to do. */
|
||||
if (len == 0)
|
||||
return;
|
||||
|
||||
/* Number of bytes left in the buffer from previous updates. */
|
||||
r = (ctx->count >> 3) & 0x3f;
|
||||
|
||||
/* Update number of bits. */
|
||||
ctx->count += (uint64_t)(len) << 3;
|
||||
|
||||
/* Handle the case where we don't need to perform any transforms. */
|
||||
if (len < 64 - r) {
|
||||
memcpy(&ctx->buf[r], src, len);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Finish the current block. */
|
||||
memcpy(&ctx->buf[r], src, 64 - r);
|
||||
sha256_Transform(ctx->state, ctx->buf);
|
||||
src += 64 - r;
|
||||
len -= 64 - r;
|
||||
|
||||
/* Perform complete blocks. */
|
||||
while (len >= 64) {
|
||||
sha256_Transform(ctx->state, src);
|
||||
src += 64;
|
||||
len -= 64;
|
||||
}
|
||||
|
||||
/* Copy left over data into buffer. */
|
||||
memcpy(ctx->buf, src, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* sha256_final(ctx, digest):
|
||||
* Output the SHA256 hash of the data input to the context ${ctx} into the
|
||||
* buffer ${digest}.
|
||||
*/
|
||||
void
|
||||
sha256_final(sha256_ctx * ctx, uint8_t digest[SHA256_DIGEST_LEN])
|
||||
{
|
||||
|
||||
/* Add padding. */
|
||||
sha256_pad(ctx);
|
||||
|
||||
/* Write the hash. */
|
||||
be32enc_vect(digest, ctx->state, SHA256_DIGEST_LEN);
|
||||
|
||||
/* Clear the context state. */
|
||||
memset((void *)ctx, 0, sizeof(*ctx));
|
||||
}
|
||||
|
||||
/**
|
||||
* sha256_complete(in, len, digest):
|
||||
* Compute the SHA256 hash of ${len} bytes from $in} and write it to ${digest}.
|
||||
*/
|
||||
void
|
||||
sha256_complete(const void * in, size_t len, uint8_t digest[SHA256_DIGEST_LEN])
|
||||
{
|
||||
sha256_ctx ctx;
|
||||
|
||||
sha256_init(&ctx);
|
||||
sha256_update(&ctx, in, len);
|
||||
sha256_final(&ctx, digest);
|
||||
}
|
||||
|
||||
/**
|
||||
* hmac_sha256_init(ctx, K, Klen):
|
||||
* Initialize the HMAC-SHA256 context ${ctx} with ${Klen} bytes of key from
|
||||
* ${K}.
|
||||
*/
|
||||
void
|
||||
hmac_sha256_init(hmac_sha256_ctx * ctx, const void * _K, size_t Klen)
|
||||
{
|
||||
uint8_t pad[64];
|
||||
uint8_t khash[SHA256_DIGEST_LEN];
|
||||
const uint8_t * K = _K;
|
||||
size_t i;
|
||||
|
||||
/* If Klen > 64, the key is really SHA256(K). */
|
||||
if (Klen > 64) {
|
||||
sha256_init(&ctx->ictx);
|
||||
sha256_update(&ctx->ictx, K, Klen);
|
||||
sha256_final(&ctx->ictx, khash);
|
||||
K = khash;
|
||||
Klen = sizeof khash;
|
||||
}
|
||||
|
||||
/* Inner SHA256 operation is SHA256(K xor [block of 0x36] || data). */
|
||||
sha256_init(&ctx->ictx);
|
||||
memset(pad, 0x36, 64);
|
||||
for (i = 0; i < Klen; i++)
|
||||
pad[i] ^= K[i];
|
||||
sha256_update(&ctx->ictx, pad, 64);
|
||||
|
||||
/* Outer SHA256 operation is SHA256(K xor [block of 0x5c] || hash). */
|
||||
sha256_init(&ctx->octx);
|
||||
memset(pad, 0x5c, 64);
|
||||
for (i = 0; i < Klen; i++)
|
||||
pad[i] ^= K[i];
|
||||
sha256_update(&ctx->octx, pad, 64);
|
||||
|
||||
/* Clean the stack. */
|
||||
memset(khash, 0, sizeof khash);
|
||||
memset(pad, 0, 64);
|
||||
}
|
||||
|
||||
/**
|
||||
* hmac_sha256_update(ctx, in, len):
|
||||
* Input ${len} bytes from ${in} into the HMAC-SHA256 context ${ctx}.
|
||||
*/
|
||||
void
|
||||
hmac_sha256_update(hmac_sha256_ctx * ctx, const void *in, size_t len)
|
||||
{
|
||||
|
||||
/* Feed data to the inner SHA256 operation. */
|
||||
sha256_update(&ctx->ictx, in, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* hmac_sha256_final(ctx, digest):
|
||||
* Output the HMAC-SHA256 of the data input to the context ${ctx} into the
|
||||
* buffer ${digest}.
|
||||
*/
|
||||
void
|
||||
hmac_sha256_final(hmac_sha256_ctx * ctx, uint8_t digest[SHA256_DIGEST_LEN])
|
||||
{
|
||||
uint8_t ihash[SHA256_DIGEST_LEN];
|
||||
|
||||
/* Finish the inner SHA256 operation. */
|
||||
sha256_final(&ctx->ictx, ihash);
|
||||
|
||||
/* Feed the inner hash to the outer SHA256 operation. */
|
||||
sha256_update(&ctx->octx, ihash, sizeof ihash);
|
||||
|
||||
/* Finish the outer SHA256 operation. */
|
||||
sha256_final(&ctx->octx, digest);
|
||||
|
||||
/* Clean the stack. */
|
||||
memset(ihash, 0, sizeof ihash);
|
||||
}
|
||||
|
||||
/**
|
||||
* hmac_sha256_complete(K, Klen, in, len, digest):
|
||||
* Compute the HMAC-SHA256 of ${len} bytes from ${in} using the key ${K} of
|
||||
* length ${Klen}, and write the result to ${digest}.
|
||||
*/
|
||||
void
|
||||
hmac_sha256_complete(const void * K, size_t Klen, const void * in, size_t len,
|
||||
uint8_t digest[SHA256_DIGEST_LEN])
|
||||
{
|
||||
hmac_sha256_ctx ctx;
|
||||
|
||||
hmac_sha256_init(&ctx, K, Klen);
|
||||
hmac_sha256_update(&ctx, in, len);
|
||||
hmac_sha256_final(&ctx, digest);
|
||||
}
|
||||
|
||||
/**
|
||||
* PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
|
||||
* Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
|
||||
* write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).
|
||||
*/
|
||||
void
|
||||
pbkdf2_sha256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,
|
||||
size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen)
|
||||
{
|
||||
hmac_sha256_ctx PShctx, hctx;
|
||||
size_t i;
|
||||
uint8_t ivec[4];
|
||||
uint8_t U[SHA256_DIGEST_LEN];
|
||||
uint8_t T[SHA256_DIGEST_LEN];
|
||||
uint64_t j;
|
||||
unsigned int k;
|
||||
size_t clen;
|
||||
|
||||
/* Compute HMAC state after processing P and S. */
|
||||
hmac_sha256_init(&PShctx, passwd, passwdlen);
|
||||
hmac_sha256_update(&PShctx, salt, saltlen);
|
||||
|
||||
/* Iterate through the blocks. */
|
||||
for (i = 0; i * 32 < dkLen; i++) {
|
||||
/* Generate INT(i + 1). */
|
||||
be32enc(ivec, (uint32_t)(i + 1));
|
||||
|
||||
/* Compute U_1 = PRF(P, S || INT(i)). */
|
||||
memcpy(&hctx, &PShctx, sizeof(hmac_sha256_ctx));
|
||||
hmac_sha256_update(&hctx, ivec, 4);
|
||||
hmac_sha256_final(&hctx, U);
|
||||
|
||||
/* T_i = U_1 ... */
|
||||
memcpy(T, U, sizeof T);
|
||||
|
||||
for (j = 2; j <= c; j++) {
|
||||
/* Compute U_j. */
|
||||
hmac_sha256_init(&hctx, passwd, passwdlen);
|
||||
hmac_sha256_update(&hctx, U, 32);
|
||||
hmac_sha256_final(&hctx, U);
|
||||
|
||||
/* ... xor U_j ... */
|
||||
for (k = 0; k < sizeof T; k++)
|
||||
T[k] ^= U[k];
|
||||
}
|
||||
|
||||
/* Copy as many bytes as necessary into buf. */
|
||||
clen = dkLen - i * 32;
|
||||
if (clen > 32)
|
||||
clen = 32;
|
||||
memcpy(&buf[i * 32], T, clen);
|
||||
}
|
||||
|
||||
/* Clean PShctx, since we never called _final on it. */
|
||||
memset(&PShctx, 0, sizeof(hmac_sha256_ctx));
|
||||
}
|
||||
|
||||
struct digest_algorithm sha256_digest = {
|
||||
.name = "sha256",
|
||||
.contextlen = sizeof sha256_digest,
|
||||
.digestlen = SHA256_DIGEST_LEN,
|
||||
.init = (digest_init_func)sha256_init,
|
||||
.update = (digest_update_func)sha256_update,
|
||||
.final = (digest_final_func)sha256_final,
|
||||
.complete = (digest_complete_func)sha256_complete,
|
||||
};
|
419
lib/digest/sha384.c
Normal file
419
lib/digest/sha384.c
Normal file
|
@ -0,0 +1,419 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2007 Christophe Devine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Cryb$
|
||||
*/
|
||||
/*
|
||||
* The SHA-384 Secure Hash Standard was published by NIST in 2002.
|
||||
*
|
||||
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
|
||||
*/
|
||||
|
||||
#include "cryb/impl.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <cryb/digest.h>
|
||||
#include <cryb/sha384.h>
|
||||
|
||||
static int is384 = 1;
|
||||
|
||||
/*
|
||||
* 64-bit integer manipulation macros (big endian)
|
||||
*/
|
||||
#ifndef GET_UINT64_BE
|
||||
#define GET_UINT64_BE(n,b,i) \
|
||||
do { \
|
||||
(n) = ( (uint64_t) (b)[(i) ] << 56 ) \
|
||||
| ( (uint64_t) (b)[(i) + 1] << 48 ) \
|
||||
| ( (uint64_t) (b)[(i) + 2] << 40 ) \
|
||||
| ( (uint64_t) (b)[(i) + 3] << 32 ) \
|
||||
| ( (uint64_t) (b)[(i) + 4] << 24 ) \
|
||||
| ( (uint64_t) (b)[(i) + 5] << 16 ) \
|
||||
| ( (uint64_t) (b)[(i) + 6] << 8 ) \
|
||||
| ( (uint64_t) (b)[(i) + 7] ); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef PUT_UINT64_BE
|
||||
#define PUT_UINT64_BE(n,b,i) \
|
||||
do { \
|
||||
(b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
|
||||
(b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
|
||||
(b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
|
||||
(b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
|
||||
(b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
|
||||
(b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
|
||||
(b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
|
||||
(b)[(i) + 7] = (unsigned char) ( (n) ); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/* XXX */
|
||||
#define UL64(x) x##ULL
|
||||
|
||||
/*
|
||||
* Round constants
|
||||
*/
|
||||
static const uint64_t K[80] =
|
||||
{
|
||||
UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
|
||||
UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
|
||||
UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
|
||||
UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
|
||||
UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
|
||||
UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
|
||||
UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
|
||||
UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
|
||||
UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
|
||||
UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
|
||||
UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
|
||||
UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
|
||||
UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
|
||||
UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
|
||||
UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
|
||||
UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
|
||||
UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
|
||||
UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
|
||||
UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
|
||||
UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
|
||||
UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
|
||||
UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
|
||||
UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
|
||||
UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
|
||||
UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
|
||||
UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
|
||||
UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
|
||||
UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
|
||||
UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
|
||||
UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
|
||||
UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
|
||||
UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
|
||||
UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
|
||||
UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
|
||||
UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
|
||||
UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
|
||||
UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
|
||||
UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
|
||||
UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
|
||||
UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
|
||||
};
|
||||
|
||||
/*
|
||||
* SHA-384 context setup
|
||||
*/
|
||||
void sha384_init( sha384_ctx *ctx )
|
||||
{
|
||||
ctx->total[0] = 0;
|
||||
ctx->total[1] = 0;
|
||||
|
||||
if( is384 == 0 )
|
||||
{
|
||||
/* SHA-384 */
|
||||
ctx->state[0] = UL64(0x6A09E667F3BCC908);
|
||||
ctx->state[1] = UL64(0xBB67AE8584CAA73B);
|
||||
ctx->state[2] = UL64(0x3C6EF372FE94F82B);
|
||||
ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
|
||||
ctx->state[4] = UL64(0x510E527FADE682D1);
|
||||
ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
|
||||
ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
|
||||
ctx->state[7] = UL64(0x5BE0CD19137E2179);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* SHA-384 */
|
||||
ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
|
||||
ctx->state[1] = UL64(0x629A292A367CD507);
|
||||
ctx->state[2] = UL64(0x9159015A3070DD17);
|
||||
ctx->state[3] = UL64(0x152FECD8F70E5939);
|
||||
ctx->state[4] = UL64(0x67332667FFC00B31);
|
||||
ctx->state[5] = UL64(0x8EB44A8768581511);
|
||||
ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
|
||||
ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
|
||||
}
|
||||
}
|
||||
|
||||
static void sha384_process( sha384_ctx *ctx, const unsigned char *data )
|
||||
{
|
||||
int i;
|
||||
uint64_t temp1, temp2, W[80];
|
||||
uint64_t A, B, C, D, E, F, G, H;
|
||||
|
||||
#define SHR(x,n) (x >> n)
|
||||
#define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
|
||||
|
||||
#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
|
||||
#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
|
||||
|
||||
#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
|
||||
#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
|
||||
|
||||
#define F0(x,y,z) ((x & y) | (z & (x | y)))
|
||||
#define F1(x,y,z) (z ^ (x & (y ^ z)))
|
||||
|
||||
#define P(a,b,c,d,e,f,g,h,x,K) \
|
||||
{ \
|
||||
temp1 = h + S3(e) + F1(e,f,g) + K + x; \
|
||||
temp2 = S2(a) + F0(a,b,c); \
|
||||
d += temp1; h = temp1 + temp2; \
|
||||
}
|
||||
|
||||
for( i = 0; i < 16; i++ )
|
||||
{
|
||||
GET_UINT64_BE( W[i], data, i << 3 );
|
||||
}
|
||||
|
||||
for( ; i < 80; i++ )
|
||||
{
|
||||
W[i] = S1(W[i - 2]) + W[i - 7] +
|
||||
S0(W[i - 15]) + W[i - 16];
|
||||
}
|
||||
|
||||
A = ctx->state[0];
|
||||
B = ctx->state[1];
|
||||
C = ctx->state[2];
|
||||
D = ctx->state[3];
|
||||
E = ctx->state[4];
|
||||
F = ctx->state[5];
|
||||
G = ctx->state[6];
|
||||
H = ctx->state[7];
|
||||
i = 0;
|
||||
|
||||
do
|
||||
{
|
||||
P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
|
||||
P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
|
||||
P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
|
||||
P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
|
||||
P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
|
||||
P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
|
||||
P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
|
||||
P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
|
||||
}
|
||||
while( i < 80 );
|
||||
|
||||
ctx->state[0] += A;
|
||||
ctx->state[1] += B;
|
||||
ctx->state[2] += C;
|
||||
ctx->state[3] += D;
|
||||
ctx->state[4] += E;
|
||||
ctx->state[5] += F;
|
||||
ctx->state[6] += G;
|
||||
ctx->state[7] += H;
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-384 process buffer
|
||||
*/
|
||||
void sha384_update( sha384_ctx *ctx, const void *input, int ilen )
|
||||
{
|
||||
int fill;
|
||||
uint64_t left;
|
||||
|
||||
if( ilen <= 0 )
|
||||
return;
|
||||
|
||||
left = ctx->total[0] & 0x7F;
|
||||
fill = (int)( 128 - left );
|
||||
|
||||
ctx->total[0] += ilen;
|
||||
|
||||
if( ctx->total[0] < (uint64_t) ilen )
|
||||
ctx->total[1]++;
|
||||
|
||||
if( left && ilen >= fill )
|
||||
{
|
||||
memcpy( (void *) (ctx->buffer + left),
|
||||
(void *) input, fill );
|
||||
sha384_process( ctx, ctx->buffer );
|
||||
input += fill;
|
||||
ilen -= fill;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
while( ilen >= 128 )
|
||||
{
|
||||
sha384_process( ctx, input );
|
||||
input += 128;
|
||||
ilen -= 128;
|
||||
}
|
||||
|
||||
if( ilen > 0 )
|
||||
{
|
||||
memcpy( (void *) (ctx->buffer + left),
|
||||
(void *) input, ilen );
|
||||
}
|
||||
}
|
||||
|
||||
static const unsigned char sha384_padding[128] =
|
||||
{
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/*
|
||||
* SHA-384 final digest
|
||||
*/
|
||||
void sha384_final( sha384_ctx *ctx, unsigned char output[64] )
|
||||
{
|
||||
int last, padn;
|
||||
uint64_t high, low;
|
||||
unsigned char msglen[16];
|
||||
|
||||
high = ( ctx->total[0] >> 61 )
|
||||
| ( ctx->total[1] << 3 );
|
||||
low = ( ctx->total[0] << 3 );
|
||||
|
||||
PUT_UINT64_BE( high, msglen, 0 );
|
||||
PUT_UINT64_BE( low, msglen, 8 );
|
||||
|
||||
last = (int)( ctx->total[0] & 0x7F );
|
||||
padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
|
||||
|
||||
sha384_update( ctx, (unsigned char *) sha384_padding, padn );
|
||||
sha384_update( ctx, msglen, 16 );
|
||||
|
||||
PUT_UINT64_BE( ctx->state[0], output, 0 );
|
||||
PUT_UINT64_BE( ctx->state[1], output, 8 );
|
||||
PUT_UINT64_BE( ctx->state[2], output, 16 );
|
||||
PUT_UINT64_BE( ctx->state[3], output, 24 );
|
||||
PUT_UINT64_BE( ctx->state[4], output, 32 );
|
||||
PUT_UINT64_BE( ctx->state[5], output, 40 );
|
||||
|
||||
if( is384 == 0 )
|
||||
{
|
||||
PUT_UINT64_BE( ctx->state[6], output, 48 );
|
||||
PUT_UINT64_BE( ctx->state[7], output, 56 );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* output = SHA-384( input buffer )
|
||||
*/
|
||||
void sha384_complete( const void *input, int ilen,
|
||||
unsigned char output[64] )
|
||||
{
|
||||
sha384_ctx ctx;
|
||||
|
||||
sha384_init( &ctx );
|
||||
sha384_update( &ctx, input, ilen );
|
||||
sha384_final( &ctx, output );
|
||||
|
||||
memset( &ctx, 0, sizeof( sha384_ctx ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-384 HMAC context setup
|
||||
*/
|
||||
void sha384_hmac_init( sha384_ctx *ctx, unsigned char *key, int keylen )
|
||||
{
|
||||
int i;
|
||||
unsigned char sum[64];
|
||||
|
||||
if( keylen > 128 )
|
||||
{
|
||||
sha384_complete( key, keylen, sum );
|
||||
keylen = ( is384 ) ? 48 : 64;
|
||||
key = sum;
|
||||
}
|
||||
|
||||
memset( ctx->ipad, 0x36, 128 );
|
||||
memset( ctx->opad, 0x5C, 128 );
|
||||
|
||||
for( i = 0; i < keylen; i++ )
|
||||
{
|
||||
ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
|
||||
ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
|
||||
}
|
||||
|
||||
sha384_init( ctx );
|
||||
sha384_update( ctx, ctx->ipad, 128 );
|
||||
|
||||
memset( sum, 0, sizeof( sum ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-384 HMAC process buffer
|
||||
*/
|
||||
void sha384_hmac_update( sha384_ctx *ctx,
|
||||
unsigned char *input, int ilen )
|
||||
{
|
||||
sha384_update( ctx, input, ilen );
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-384 HMAC final digest
|
||||
*/
|
||||
void sha384_hmac_final( sha384_ctx *ctx, unsigned char output[64] )
|
||||
{
|
||||
int hlen;
|
||||
unsigned char tmpbuf[64];
|
||||
|
||||
hlen = ( is384 == 0 ) ? 64 : 48;
|
||||
|
||||
sha384_final( ctx, tmpbuf );
|
||||
sha384_init( ctx );
|
||||
sha384_update( ctx, ctx->opad, 128 );
|
||||
sha384_update( ctx, tmpbuf, hlen );
|
||||
sha384_final( ctx, output );
|
||||
|
||||
memset( tmpbuf, 0, sizeof( tmpbuf ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* output = HMAC-SHA-384( hmac key, input buffer )
|
||||
*/
|
||||
void sha384_hmac_complete( unsigned char *key, int keylen,
|
||||
unsigned char *input, int ilen,
|
||||
unsigned char output[64] )
|
||||
{
|
||||
sha384_ctx ctx;
|
||||
|
||||
sha384_hmac_init( &ctx, key, keylen );
|
||||
sha384_hmac_update( &ctx, input, ilen );
|
||||
sha384_hmac_final( &ctx, output );
|
||||
|
||||
memset( &ctx, 0, sizeof( sha384_ctx ) );
|
||||
}
|
||||
|
||||
struct digest_algorithm sha384_digest = {
|
||||
.name = "sha384",
|
||||
.contextlen = sizeof sha384_digest,
|
||||
.digestlen = SHA384_DIGEST_LEN,
|
||||
.init = (digest_init_func)sha384_init,
|
||||
.update = (digest_update_func)sha384_update,
|
||||
.final = (digest_final_func)sha384_final,
|
||||
.complete = (digest_complete_func)sha384_complete,
|
||||
};
|
419
lib/digest/sha512.c
Normal file
419
lib/digest/sha512.c
Normal file
|
@ -0,0 +1,419 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2007 Christophe Devine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Cryb$
|
||||
*/
|
||||
/*
|
||||
* The SHA-512 Secure Hash Standard was published by NIST in 2002.
|
||||
*
|
||||
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
|
||||
*/
|
||||
|
||||
#include "cryb/impl.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <cryb/digest.h>
|
||||
#include <cryb/sha512.h>
|
||||
|
||||
static int is384 = 0;
|
||||
|
||||
/*
|
||||
* 64-bit integer manipulation macros (big endian)
|
||||
*/
|
||||
#ifndef GET_UINT64_BE
|
||||
#define GET_UINT64_BE(n,b,i) \
|
||||
do { \
|
||||
(n) = ( (uint64_t) (b)[(i) ] << 56 ) \
|
||||
| ( (uint64_t) (b)[(i) + 1] << 48 ) \
|
||||
| ( (uint64_t) (b)[(i) + 2] << 40 ) \
|
||||
| ( (uint64_t) (b)[(i) + 3] << 32 ) \
|
||||
| ( (uint64_t) (b)[(i) + 4] << 24 ) \
|
||||
| ( (uint64_t) (b)[(i) + 5] << 16 ) \
|
||||
| ( (uint64_t) (b)[(i) + 6] << 8 ) \
|
||||
| ( (uint64_t) (b)[(i) + 7] ); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef PUT_UINT64_BE
|
||||
#define PUT_UINT64_BE(n,b,i) \
|
||||
do { \
|
||||
(b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
|
||||
(b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
|
||||
(b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
|
||||
(b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
|
||||
(b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
|
||||
(b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
|
||||
(b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
|
||||
(b)[(i) + 7] = (unsigned char) ( (n) ); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/* XXX */
|
||||
#define UL64(x) x##ULL
|
||||
|
||||
/*
|
||||
* Round constants
|
||||
*/
|
||||
static const uint64_t K[80] =
|
||||
{
|
||||
UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
|
||||
UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
|
||||
UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
|
||||
UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
|
||||
UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
|
||||
UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
|
||||
UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
|
||||
UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
|
||||
UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
|
||||
UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
|
||||
UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
|
||||
UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
|
||||
UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
|
||||
UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
|
||||
UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
|
||||
UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
|
||||
UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
|
||||
UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
|
||||
UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
|
||||
UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
|
||||
UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
|
||||
UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
|
||||
UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
|
||||
UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
|
||||
UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
|
||||
UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
|
||||
UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
|
||||
UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
|
||||
UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
|
||||
UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
|
||||
UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
|
||||
UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
|
||||
UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
|
||||
UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
|
||||
UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
|
||||
UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
|
||||
UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
|
||||
UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
|
||||
UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
|
||||
UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
|
||||
};
|
||||
|
||||
/*
|
||||
* SHA-512 context setup
|
||||
*/
|
||||
void sha512_init( sha512_ctx *ctx )
|
||||
{
|
||||
ctx->total[0] = 0;
|
||||
ctx->total[1] = 0;
|
||||
|
||||
if( is384 == 0 )
|
||||
{
|
||||
/* SHA-512 */
|
||||
ctx->state[0] = UL64(0x6A09E667F3BCC908);
|
||||
ctx->state[1] = UL64(0xBB67AE8584CAA73B);
|
||||
ctx->state[2] = UL64(0x3C6EF372FE94F82B);
|
||||
ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
|
||||
ctx->state[4] = UL64(0x510E527FADE682D1);
|
||||
ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
|
||||
ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
|
||||
ctx->state[7] = UL64(0x5BE0CD19137E2179);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* SHA-384 */
|
||||
ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
|
||||
ctx->state[1] = UL64(0x629A292A367CD507);
|
||||
ctx->state[2] = UL64(0x9159015A3070DD17);
|
||||
ctx->state[3] = UL64(0x152FECD8F70E5939);
|
||||
ctx->state[4] = UL64(0x67332667FFC00B31);
|
||||
ctx->state[5] = UL64(0x8EB44A8768581511);
|
||||
ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
|
||||
ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
|
||||
}
|
||||
}
|
||||
|
||||
static void sha512_process( sha512_ctx *ctx, const unsigned char *data )
|
||||
{
|
||||
int i;
|
||||
uint64_t temp1, temp2, W[80];
|
||||
uint64_t A, B, C, D, E, F, G, H;
|
||||
|
||||
#define SHR(x,n) (x >> n)
|
||||
#define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
|
||||
|
||||
#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
|
||||
#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
|
||||
|
||||
#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
|
||||
#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
|
||||
|
||||
#define F0(x,y,z) ((x & y) | (z & (x | y)))
|
||||
#define F1(x,y,z) (z ^ (x & (y ^ z)))
|
||||
|
||||
#define P(a,b,c,d,e,f,g,h,x,K) \
|
||||
{ \
|
||||
temp1 = h + S3(e) + F1(e,f,g) + K + x; \
|
||||
temp2 = S2(a) + F0(a,b,c); \
|
||||
d += temp1; h = temp1 + temp2; \
|
||||
}
|
||||
|
||||
for( i = 0; i < 16; i++ )
|
||||
{
|
||||
GET_UINT64_BE( W[i], data, i << 3 );
|
||||
}
|
||||
|
||||
for( ; i < 80; i++ )
|
||||
{
|
||||
W[i] = S1(W[i - 2]) + W[i - 7] +
|
||||
S0(W[i - 15]) + W[i - 16];
|
||||
}
|
||||
|
||||
A = ctx->state[0];
|
||||
B = ctx->state[1];
|
||||
C = ctx->state[2];
|
||||
D = ctx->state[3];
|
||||
E = ctx->state[4];
|
||||
F = ctx->state[5];
|
||||
G = ctx->state[6];
|
||||
H = ctx->state[7];
|
||||
i = 0;
|
||||
|
||||
do
|
||||
{
|
||||
P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
|
||||
P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
|
||||
P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
|
||||
P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
|
||||
P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
|
||||
P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
|
||||
P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
|
||||
P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
|
||||
}
|
||||
while( i < 80 );
|
||||
|
||||
ctx->state[0] += A;
|
||||
ctx->state[1] += B;
|
||||
ctx->state[2] += C;
|
||||
ctx->state[3] += D;
|
||||
ctx->state[4] += E;
|
||||
ctx->state[5] += F;
|
||||
ctx->state[6] += G;
|
||||
ctx->state[7] += H;
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-512 process buffer
|
||||
*/
|
||||
void sha512_update( sha512_ctx *ctx, const void *input, int ilen )
|
||||
{
|
||||
int fill;
|
||||
uint64_t left;
|
||||
|
||||
if( ilen <= 0 )
|
||||
return;
|
||||
|
||||
left = ctx->total[0] & 0x7F;
|
||||
fill = (int)( 128 - left );
|
||||
|
||||
ctx->total[0] += ilen;
|
||||
|
||||
if( ctx->total[0] < (uint64_t) ilen )
|
||||
ctx->total[1]++;
|
||||
|
||||
if( left && ilen >= fill )
|
||||
{
|
||||
memcpy( (void *) (ctx->buffer + left),
|
||||
(void *) input, fill );
|
||||
sha512_process( ctx, ctx->buffer );
|
||||
input += fill;
|
||||
ilen -= fill;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
while( ilen >= 128 )
|
||||
{
|
||||
sha512_process( ctx, input );
|
||||
input += 128;
|
||||
ilen -= 128;
|
||||
}
|
||||
|
||||
if( ilen > 0 )
|
||||
{
|
||||
memcpy( (void *) (ctx->buffer + left),
|
||||
(void *) input, ilen );
|
||||
}
|
||||
}
|
||||
|
||||
static const unsigned char sha512_padding[128] =
|
||||
{
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/*
|
||||
* SHA-512 final digest
|
||||
*/
|
||||
void sha512_final( sha512_ctx *ctx, unsigned char output[64] )
|
||||
{
|
||||
int last, padn;
|
||||
uint64_t high, low;
|
||||
unsigned char msglen[16];
|
||||
|
||||
high = ( ctx->total[0] >> 61 )
|
||||
| ( ctx->total[1] << 3 );
|
||||
low = ( ctx->total[0] << 3 );
|
||||
|
||||
PUT_UINT64_BE( high, msglen, 0 );
|
||||
PUT_UINT64_BE( low, msglen, 8 );
|
||||
|
||||
last = (int)( ctx->total[0] & 0x7F );
|
||||
padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
|
||||
|
||||
sha512_update( ctx, (unsigned char *) sha512_padding, padn );
|
||||
sha512_update( ctx, msglen, 16 );
|
||||
|
||||
PUT_UINT64_BE( ctx->state[0], output, 0 );
|
||||
PUT_UINT64_BE( ctx->state[1], output, 8 );
|
||||
PUT_UINT64_BE( ctx->state[2], output, 16 );
|
||||
PUT_UINT64_BE( ctx->state[3], output, 24 );
|
||||
PUT_UINT64_BE( ctx->state[4], output, 32 );
|
||||
PUT_UINT64_BE( ctx->state[5], output, 40 );
|
||||
|
||||
if( is384 == 0 )
|
||||
{
|
||||
PUT_UINT64_BE( ctx->state[6], output, 48 );
|
||||
PUT_UINT64_BE( ctx->state[7], output, 56 );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* output = SHA-512( input buffer )
|
||||
*/
|
||||
void sha512_complete( const void *input, int ilen,
|
||||
unsigned char output[64] )
|
||||
{
|
||||
sha512_ctx ctx;
|
||||
|
||||
sha512_init( &ctx );
|
||||
sha512_update( &ctx, input, ilen );
|
||||
sha512_final( &ctx, output );
|
||||
|
||||
memset( &ctx, 0, sizeof( sha512_ctx ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-512 HMAC context setup
|
||||
*/
|
||||
void sha512_hmac_init( sha512_ctx *ctx, unsigned char *key, int keylen )
|
||||
{
|
||||
int i;
|
||||
unsigned char sum[64];
|
||||
|
||||
if( keylen > 128 )
|
||||
{
|
||||
sha512_complete( key, keylen, sum );
|
||||
keylen = ( is384 ) ? 48 : 64;
|
||||
key = sum;
|
||||
}
|
||||
|
||||
memset( ctx->ipad, 0x36, 128 );
|
||||
memset( ctx->opad, 0x5C, 128 );
|
||||
|
||||
for( i = 0; i < keylen; i++ )
|
||||
{
|
||||
ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
|
||||
ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
|
||||
}
|
||||
|
||||
sha512_init( ctx );
|
||||
sha512_update( ctx, ctx->ipad, 128 );
|
||||
|
||||
memset( sum, 0, sizeof( sum ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-512 HMAC process buffer
|
||||
*/
|
||||
void sha512_hmac_update( sha512_ctx *ctx,
|
||||
unsigned char *input, int ilen )
|
||||
{
|
||||
sha512_update( ctx, input, ilen );
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-512 HMAC final digest
|
||||
*/
|
||||
void sha512_hmac_final( sha512_ctx *ctx, unsigned char output[64] )
|
||||
{
|
||||
int hlen;
|
||||
unsigned char tmpbuf[64];
|
||||
|
||||
hlen = ( is384 == 0 ) ? 64 : 48;
|
||||
|
||||
sha512_final( ctx, tmpbuf );
|
||||
sha512_init( ctx );
|
||||
sha512_update( ctx, ctx->opad, 128 );
|
||||
sha512_update( ctx, tmpbuf, hlen );
|
||||
sha512_final( ctx, output );
|
||||
|
||||
memset( tmpbuf, 0, sizeof( tmpbuf ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* output = HMAC-SHA-512( hmac key, input buffer )
|
||||
*/
|
||||
void sha512_hmac_complete( unsigned char *key, int keylen,
|
||||
unsigned char *input, int ilen,
|
||||
unsigned char output[64] )
|
||||
{
|
||||
sha512_ctx ctx;
|
||||
|
||||
sha512_hmac_init( &ctx, key, keylen );
|
||||
sha512_hmac_update( &ctx, input, ilen );
|
||||
sha512_hmac_final( &ctx, output );
|
||||
|
||||
memset( &ctx, 0, sizeof( sha512_ctx ) );
|
||||
}
|
||||
|
||||
struct digest_algorithm sha512_digest = {
|
||||
.name = "sha512",
|
||||
.contextlen = sizeof sha512_digest,
|
||||
.digestlen = SHA512_DIGEST_LEN,
|
||||
.init = (digest_init_func)sha512_init,
|
||||
.update = (digest_update_func)sha512_update,
|
||||
.final = (digest_final_func)sha512_final,
|
||||
.complete = (digest_complete_func)sha512_complete,
|
||||
};
|
|
@ -45,26 +45,41 @@ TESTS += t_ctype
|
|||
TESTS += t_rfc3986 t_rfc4648
|
||||
|
||||
# libcryb-digest
|
||||
TESTS += t_md5
|
||||
TESTS += t_md2 t_md4 t_md5
|
||||
if WITH_OPENSSL
|
||||
TESTS += t_md5_openssl
|
||||
TESTS += t_md4_openssl t_md5_openssl
|
||||
t_md4_openssl_SOURCES = t_md4.c
|
||||
t_md4_openssl_CFLAGS = $(OPENSSL_INCLUDES) $(OPENSSL_CFLAGS)
|
||||
t_md4_openssl_LDADD = $(OPENSSL_LDADD)
|
||||
t_md5_openssl_SOURCES = t_md5.c
|
||||
t_md5_openssl_CFLAGS = $(OPENSSL_INCLUDES) $(OPENSSL_CFLAGS)
|
||||
t_md5_openssl_LDADD = $(OPENSSL_LDADD)
|
||||
endif
|
||||
if WITH_RSAREF
|
||||
TESTS += t_md5_rsaref
|
||||
TESTS += t_md2_rsaref t_md5_rsaref
|
||||
t_md2_rsaref_SOURCES = t_md2.c
|
||||
t_md2_rsaref_CFLAGS = $(RSAREF_INCLUDES) $(RSAREF_CFLAGS)
|
||||
t_md2_rsaref_LDADD = $(RSAREF_LDADD)
|
||||
t_md5_rsaref_SOURCES = t_md5.c
|
||||
t_md5_rsaref_CFLAGS = $(RSAREF_INCLUDES) $(RSAREF_CFLAGS)
|
||||
t_md5_rsaref_LDADD = $(RSAREF_LDADD)
|
||||
endif
|
||||
|
||||
TESTS += t_sha1
|
||||
TESTS += t_sha1 t_sha256 t_sha384 t_sha512
|
||||
if WITH_OPENSSL
|
||||
TESTS += t_sha1_openssl
|
||||
TESTS += t_sha1_openssl t_sha256_openssl t_sha384_openssl t_sha512_openssl
|
||||
t_sha1_openssl_SOURCES = t_sha1.c
|
||||
t_sha1_openssl_CFLAGS = $(OPENSSL_INCLUDES) $(OPENSSL_CFLAGS)
|
||||
t_sha1_openssl_LDADD = $(OPENSSL_LDADD)
|
||||
t_sha256_openssl_SOURCES = t_sha256.c
|
||||
t_sha256_openssl_CFLAGS = $(OPENSSL_INCLUDES) $(OPENSSL_CFLAGS)
|
||||
t_sha256_openssl_LDADD = $(OPENSSL_LDADD)
|
||||
t_sha384_openssl_SOURCES = t_sha384.c
|
||||
t_sha384_openssl_CFLAGS = $(OPENSSL_INCLUDES) $(OPENSSL_CFLAGS)
|
||||
t_sha384_openssl_LDADD = $(OPENSSL_LDADD)
|
||||
t_sha512_openssl_SOURCES = t_sha512.c
|
||||
t_sha512_openssl_CFLAGS = $(OPENSSL_INCLUDES) $(OPENSSL_CFLAGS)
|
||||
t_sha512_openssl_LDADD = $(OPENSSL_LDADD)
|
||||
endif
|
||||
|
||||
# libcryb-mac
|
||||
|
|
257
t/t_md2.c
Normal file
257
t/t_md2.c
Normal file
|
@ -0,0 +1,257 @@
|
|||
/*-
|
||||
* Copyright (c) 2012 Universitetet i Oslo
|
||||
* Copyright (c) 2012-2014 Dag-Erling Smørgrav
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||
* Sponsor: the University of Oslo
|
||||
*
|
||||
* $Cryb$
|
||||
*/
|
||||
|
||||
#include "cryb/impl.h"
|
||||
|
||||
#include <err.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "t.h"
|
||||
|
||||
#if WITH_RSAREF
|
||||
|
||||
#include <rsaref.h>
|
||||
|
||||
#define MD2_DIGEST_LEN 16
|
||||
|
||||
static void
|
||||
t_md2_complete(const void *msg, size_t msglen, uint8_t *digest)
|
||||
{
|
||||
MD2_CTX ctx;
|
||||
|
||||
MD2Init(&ctx);
|
||||
MD2Update(&ctx, (unsigned char *)(uintptr_t)msg, msglen);
|
||||
MD2Final(digest, &ctx);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <cryb/md2.h>
|
||||
|
||||
#define t_md2_complete(msg, msglen, digest) \
|
||||
md2_complete(msg, msglen, digest)
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Test vectors from RFC 1319
|
||||
*/
|
||||
static struct t_vector {
|
||||
const char *msg;
|
||||
const uint8_t digest[MD2_DIGEST_LEN];
|
||||
} t_md2_vectors[] = {
|
||||
{
|
||||
"",
|
||||
{
|
||||
0x83, 0x50, 0xe5, 0xa3, 0xe2, 0x4c, 0x15, 0x3d,
|
||||
0xf2, 0x27, 0x5c, 0x9f, 0x80, 0x69, 0x27, 0x73,
|
||||
}
|
||||
},
|
||||
{
|
||||
"a",
|
||||
{
|
||||
0x32, 0xec, 0x01, 0xec, 0x4a, 0x6d, 0xac, 0x72,
|
||||
0xc0, 0xab, 0x96, 0xfb, 0x34, 0xc0, 0xb5, 0xd1,
|
||||
}
|
||||
},
|
||||
{
|
||||
"abc",
|
||||
{
|
||||
0xda, 0x85, 0x3b, 0x0d, 0x3f, 0x88, 0xd9, 0x9b,
|
||||
0x30, 0x28, 0x3a, 0x69, 0xe6, 0xde, 0xd6, 0xbb,
|
||||
}
|
||||
},
|
||||
{
|
||||
"message digest",
|
||||
{
|
||||
0xab, 0x4f, 0x49, 0x6b, 0xfb, 0x2a, 0x53, 0x0b,
|
||||
0x21, 0x9f, 0xf3, 0x30, 0x31, 0xfe, 0x06, 0xb0,
|
||||
}
|
||||
},
|
||||
{
|
||||
"abcdefghijklmnopqrstuvwxyz",
|
||||
{
|
||||
0x4e, 0x8d, 0xdf, 0xf3, 0x65, 0x02, 0x92, 0xab,
|
||||
0x5a, 0x41, 0x08, 0xc3, 0xaa, 0x47, 0x94, 0x0b,
|
||||
}
|
||||
},
|
||||
{
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789",
|
||||
{
|
||||
0xda, 0x33, 0xde, 0xf2, 0xa4, 0x2d, 0xf1, 0x39,
|
||||
0x75, 0x35, 0x28, 0x46, 0xc3, 0x03, 0x38, 0xcd,
|
||||
}
|
||||
},
|
||||
{
|
||||
"1234567890123456789012345678901234567890"
|
||||
"1234567890123456789012345678901234567890",
|
||||
{
|
||||
0xd5, 0x97, 0x6f, 0x79, 0xd8, 0x3d, 0x3a, 0x0d,
|
||||
0xc9, 0x80, 0x6c, 0x3c, 0x66, 0xf3, 0xef, 0xd8,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* Unit test: compute the MD2 sum of the specified string and compare it
|
||||
* to the expected result.
|
||||
*/
|
||||
static int
|
||||
t_md2_vector(char **desc CRYB_UNUSED, void *arg)
|
||||
{
|
||||
struct t_vector *vector = (struct t_vector *)arg;
|
||||
uint8_t digest[MD2_DIGEST_LEN];
|
||||
|
||||
t_md2_complete(vector->msg, strlen(vector->msg), digest);
|
||||
if (memcmp(digest, vector->digest, MD2_DIGEST_LEN) != 0) {
|
||||
t_verbose("expected ");
|
||||
t_verbose_hex(vector->digest, MD2_DIGEST_LEN);
|
||||
t_verbose("\n");
|
||||
t_verbose("got ");
|
||||
t_verbose_hex(digest, MD2_DIGEST_LEN);
|
||||
t_verbose("\n");
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
#ifdef BENCHMARKS
|
||||
/*
|
||||
* Performance test: measure the time spent computing the MD2 sum of a
|
||||
* message of the specified length.
|
||||
*/
|
||||
#define T_PERF_ITERATIONS 1000
|
||||
static int
|
||||
t_md2_perf(char **desc, void *arg)
|
||||
{
|
||||
struct timespec ts, te;
|
||||
unsigned long ns;
|
||||
uint8_t digest[MD2_DIGEST_LEN];
|
||||
char *msg, *comment;
|
||||
size_t msglen = *(size_t *)arg;
|
||||
|
||||
if ((msg = calloc(1, msglen)) == NULL)
|
||||
err(1, "calloc()");
|
||||
clock_gettime(CLOCK_MONOTONIC_PRECISE, &ts);
|
||||
for (int i = 0; i < T_PERF_ITERATIONS; ++i)
|
||||
t_md2_complete(msg, msglen, digest);
|
||||
clock_gettime(CLOCK_MONOTONIC_PRECISE, &te);
|
||||
free(msg);
|
||||
ns = te.tv_sec * 1000000000LU + te.tv_nsec;
|
||||
ns -= ts.tv_sec * 1000000000LU + ts.tv_nsec;
|
||||
asprintf(&comment, "%zu bytes: %d iterations in %'lu ns",
|
||||
msglen, T_PERF_ITERATIONS, ns);
|
||||
if (comment == NULL)
|
||||
err(1, "asprintf()");
|
||||
*desc = comment;
|
||||
return (1);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(WITH_RSAREF)
|
||||
/*
|
||||
* Various corner cases and error conditions
|
||||
*/
|
||||
static int
|
||||
t_md2_short_updates(char **desc CRYB_UNUSED, void *arg)
|
||||
{
|
||||
struct t_vector *vector = (struct t_vector *)arg;
|
||||
uint8_t digest[MD2_DIGEST_LEN];
|
||||
md2_ctx ctx;
|
||||
int i, len;
|
||||
|
||||
md2_init(&ctx);
|
||||
len = strlen(vector->msg);
|
||||
for (i = 0; i + 5 < len; i += 5)
|
||||
md2_update(&ctx, vector->msg + i, 5);
|
||||
md2_update(&ctx, vector->msg + i, len - i);
|
||||
md2_final(&ctx, digest);
|
||||
return (memcmp(digest, vector->digest, MD2_DIGEST_LEN) == 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Boilerplate
|
||||
*/
|
||||
|
||||
int
|
||||
t_prepare(int argc, char *argv[])
|
||||
{
|
||||
int i, n;
|
||||
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
n = sizeof t_md2_vectors / sizeof t_md2_vectors[0];
|
||||
for (i = 0; i < n; ++i)
|
||||
t_add_test(t_md2_vector, &t_md2_vectors[i],
|
||||
"RFC 1321 test vector %d", i + 1);
|
||||
#if !defined(WITH_RSAREF)
|
||||
/*
|
||||
* Run test vector 7 (which is 80 characters long) 5 characters at
|
||||
* a time. This tests a) appending data to an underfull block and
|
||||
* b) appending more data to an underfull block than it has room
|
||||
* for (since 64 % 5 != 0). Test vector 7 already exercised the
|
||||
* code path for computing a block directly from source (without
|
||||
* copying it in), and all the test vectors except vector 1
|
||||
* exercised the general case of copying a small amount of data in
|
||||
* without crossing the block boundary.
|
||||
*/
|
||||
t_add_test(t_md2_short_updates, &t_md2_vectors[6],
|
||||
"multiple short updates");
|
||||
#endif
|
||||
#ifdef BENCHMARKS
|
||||
static size_t one = 1, thousand = 1000, million = 1000000;
|
||||
t_add_test(t_md2_perf, &one,
|
||||
"performance test (1 byte)");
|
||||
t_add_test(t_md2_perf, &thousand,
|
||||
"performance test (1,000 bytes)");
|
||||
t_add_test(t_md2_perf, &million,
|
||||
"performance test (1,000,000 bytes)");
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
t_cleanup(void)
|
||||
{
|
||||
}
|
273
t/t_md4.c
Normal file
273
t/t_md4.c
Normal file
|
@ -0,0 +1,273 @@
|
|||
/*-
|
||||
* Copyright (c) 2012 Universitetet i Oslo
|
||||
* Copyright (c) 2012-2014 Dag-Erling Smørgrav
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||
* Sponsor: the University of Oslo
|
||||
*
|
||||
* $Cryb$
|
||||
*/
|
||||
|
||||
#include "cryb/impl.h"
|
||||
|
||||
#include <err.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "t.h"
|
||||
|
||||
#if WITH_OPENSSL
|
||||
|
||||
#include <openssl/md4.h>
|
||||
|
||||
#define MD4_DIGEST_LEN MD4_DIGEST_LENGTH
|
||||
|
||||
static void
|
||||
t_md4_complete(const void *msg, size_t msglen, uint8_t *digest)
|
||||
{
|
||||
MD4_CTX ctx;
|
||||
|
||||
MD4_Init(&ctx);
|
||||
MD4_Update(&ctx, msg, msglen);
|
||||
MD4_Final(digest, &ctx);
|
||||
}
|
||||
|
||||
#elif WITH_RSAREF
|
||||
|
||||
#include <rsaref.h>
|
||||
|
||||
#define MD4_DIGEST_LEN 16
|
||||
|
||||
static void
|
||||
t_md4_complete(const void *msg, size_t msglen, uint8_t *digest)
|
||||
{
|
||||
MD4_CTX ctx;
|
||||
|
||||
MD4Init(&ctx);
|
||||
MD4Update(&ctx, (unsigned char *)(uintptr_t)msg, msglen);
|
||||
MD4Final(digest, &ctx);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <cryb/md4.h>
|
||||
|
||||
#define t_md4_complete(msg, msglen, digest) \
|
||||
md4_complete(msg, msglen, digest)
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Test vectors from RFC 1320
|
||||
*/
|
||||
static struct t_vector {
|
||||
const char *msg;
|
||||
const uint8_t digest[MD4_DIGEST_LEN];
|
||||
} t_md4_vectors[] = {
|
||||
{
|
||||
"",
|
||||
{
|
||||
0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31,
|
||||
0xb7, 0x3c, 0x59, 0xd7, 0xe0, 0xc0, 0x89, 0xc0,
|
||||
}
|
||||
},
|
||||
{
|
||||
"a",
|
||||
{
|
||||
0xbd, 0xe5, 0x2c, 0xb3, 0x1d, 0xe3, 0x3e, 0x46,
|
||||
0x24, 0x5e, 0x05, 0xfb, 0xdb, 0xd6, 0xfb, 0x24,
|
||||
}
|
||||
},
|
||||
{
|
||||
"abc",
|
||||
{
|
||||
0xa4, 0x48, 0x01, 0x7a, 0xaf, 0x21, 0xd8, 0x52,
|
||||
0x5f, 0xc1, 0x0a, 0xe8, 0x7a, 0xa6, 0x72, 0x9d,
|
||||
}
|
||||
},
|
||||
{
|
||||
"message digest",
|
||||
{
|
||||
0xd9, 0x13, 0x0a, 0x81, 0x64, 0x54, 0x9f, 0xe8,
|
||||
0x18, 0x87, 0x48, 0x06, 0xe1, 0xc7, 0x01, 0x4b,
|
||||
}
|
||||
},
|
||||
{
|
||||
"abcdefghijklmnopqrstuvwxyz",
|
||||
{
|
||||
0xd7, 0x9e, 0x1c, 0x30, 0x8a, 0xa5, 0xbb, 0xcd,
|
||||
0xee, 0xa8, 0xed, 0x63, 0xdf, 0x41, 0x2d, 0xa9,
|
||||
}
|
||||
},
|
||||
{
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789",
|
||||
{
|
||||
0x04, 0x3f, 0x85, 0x82, 0xf2, 0x41, 0xdb, 0x35,
|
||||
0x1c, 0xe6, 0x27, 0xe1, 0x53, 0xe7, 0xf0, 0xe4,
|
||||
}
|
||||
},
|
||||
{
|
||||
"1234567890123456789012345678901234567890"
|
||||
"1234567890123456789012345678901234567890",
|
||||
{
|
||||
0xe3, 0x3b, 0x4d, 0xdc, 0x9c, 0x38, 0xf2, 0x19,
|
||||
0x9c, 0x3e, 0x7b, 0x16, 0x4f, 0xcc, 0x05, 0x36,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* Unit test: compute the MD4 sum of the specified string and compare it
|
||||
* to the expected result.
|
||||
*/
|
||||
static int
|
||||
t_md4_vector(char **desc CRYB_UNUSED, void *arg)
|
||||
{
|
||||
struct t_vector *vector = (struct t_vector *)arg;
|
||||
uint8_t digest[MD4_DIGEST_LEN];
|
||||
|
||||
t_md4_complete(vector->msg, strlen(vector->msg), digest);
|
||||
if (memcmp(digest, vector->digest, MD4_DIGEST_LEN) != 0) {
|
||||
t_verbose("expected ");
|
||||
t_verbose_hex(vector->digest, MD4_DIGEST_LEN);
|
||||
t_verbose("\n");
|
||||
t_verbose("got ");
|
||||
t_verbose_hex(digest, MD4_DIGEST_LEN);
|
||||
t_verbose("\n");
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
#ifdef BENCHMARKS
|
||||
/*
|
||||
* Performance test: measure the time spent computing the MD4 sum of a
|
||||
* message of the specified length.
|
||||
*/
|
||||
#define T_PERF_ITERATIONS 1000
|
||||
static int
|
||||
t_md4_perf(char **desc, void *arg)
|
||||
{
|
||||
struct timespec ts, te;
|
||||
unsigned long ns;
|
||||
uint8_t digest[MD4_DIGEST_LEN];
|
||||
char *msg, *comment;
|
||||
size_t msglen = *(size_t *)arg;
|
||||
|
||||
if ((msg = calloc(1, msglen)) == NULL)
|
||||
err(1, "calloc()");
|
||||
clock_gettime(CLOCK_MONOTONIC_PRECISE, &ts);
|
||||
for (int i = 0; i < T_PERF_ITERATIONS; ++i)
|
||||
t_md4_complete(msg, msglen, digest);
|
||||
clock_gettime(CLOCK_MONOTONIC_PRECISE, &te);
|
||||
free(msg);
|
||||
ns = te.tv_sec * 1000000000LU + te.tv_nsec;
|
||||
ns -= ts.tv_sec * 1000000000LU + ts.tv_nsec;
|
||||
asprintf(&comment, "%zu bytes: %d iterations in %'lu ns",
|
||||
msglen, T_PERF_ITERATIONS, ns);
|
||||
if (comment == NULL)
|
||||
err(1, "asprintf()");
|
||||
*desc = comment;
|
||||
return (1);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(WITH_OPENSSL) && !defined(WITH_RSAREF)
|
||||
/*
|
||||
* Various corner cases and error conditions
|
||||
*/
|
||||
static int
|
||||
t_md4_short_updates(char **desc CRYB_UNUSED, void *arg)
|
||||
{
|
||||
struct t_vector *vector = (struct t_vector *)arg;
|
||||
uint8_t digest[MD4_DIGEST_LEN];
|
||||
md4_ctx ctx;
|
||||
int i, len;
|
||||
|
||||
md4_init(&ctx);
|
||||
len = strlen(vector->msg);
|
||||
for (i = 0; i + 5 < len; i += 5)
|
||||
md4_update(&ctx, vector->msg + i, 5);
|
||||
md4_update(&ctx, vector->msg + i, len - i);
|
||||
md4_final(&ctx, digest);
|
||||
return (memcmp(digest, vector->digest, MD4_DIGEST_LEN) == 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Boilerplate
|
||||
*/
|
||||
|
||||
int
|
||||
t_prepare(int argc, char *argv[])
|
||||
{
|
||||
int i, n;
|
||||
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
n = sizeof t_md4_vectors / sizeof t_md4_vectors[0];
|
||||
for (i = 0; i < n; ++i)
|
||||
t_add_test(t_md4_vector, &t_md4_vectors[i],
|
||||
"RFC 1321 test vector %d", i + 1);
|
||||
#if !defined(WITH_OPENSSL) && !defined(WITH_RSAREF)
|
||||
/*
|
||||
* Run test vector 7 (which is 80 characters long) 5 characters at
|
||||
* a time. This tests a) appending data to an underfull block and
|
||||
* b) appending more data to an underfull block than it has room
|
||||
* for (since 64 % 5 != 0). Test vector 7 already exercised the
|
||||
* code path for computing a block directly from source (without
|
||||
* copying it in), and all the test vectors except vector 1
|
||||
* exercised the general case of copying a small amount of data in
|
||||
* without crossing the block boundary.
|
||||
*/
|
||||
t_add_test(t_md4_short_updates, &t_md4_vectors[6],
|
||||
"multiple short updates");
|
||||
#endif
|
||||
#ifdef BENCHMARKS
|
||||
static size_t one = 1, thousand = 1000, million = 1000000;
|
||||
t_add_test(t_md4_perf, &one,
|
||||
"performance test (1 byte)");
|
||||
t_add_test(t_md4_perf, &thousand,
|
||||
"performance test (1,000 bytes)");
|
||||
t_add_test(t_md4_perf, &million,
|
||||
"performance test (1,000,000 bytes)");
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
t_cleanup(void)
|
||||
{
|
||||
}
|
275
t/t_sha256.c
Normal file
275
t/t_sha256.c
Normal file
|
@ -0,0 +1,275 @@
|
|||
/*-
|
||||
* Copyright (c) 2012 Universitetet i Oslo
|
||||
* Copyright (c) 2012-2014 Dag-Erling Smørgrav
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||
* Sponsor: the University of Oslo
|
||||
*
|
||||
* $Cryb$
|
||||
*/
|
||||
|
||||
#include "cryb/impl.h"
|
||||
|
||||
#include <err.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "t.h"
|
||||
|
||||
#if WITH_OPENSSL
|
||||
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#define SHA256_DIGEST_LEN SHA256_DIGEST_LENGTH
|
||||
|
||||
static void
|
||||
t_sha256_complete(const void *msg, size_t msglen, uint8_t *digest)
|
||||
{
|
||||
SHA256_CTX ctx;
|
||||
|
||||
SHA256_Init(&ctx);
|
||||
SHA256_Update(&ctx, msg, msglen);
|
||||
SHA256_Final(digest, &ctx);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <cryb/sha256.h>
|
||||
|
||||
#define t_sha256_complete(msg, msglen, digest) \
|
||||
sha256_complete(msg, msglen, digest)
|
||||
|
||||
#endif
|
||||
|
||||
static struct t_vector {
|
||||
const char *desc;
|
||||
const char *msg;
|
||||
const uint8_t digest[SHA256_DIGEST_LEN];
|
||||
} t_sha256_vectors[] = {
|
||||
{
|
||||
"zero-length message",
|
||||
"",
|
||||
{
|
||||
0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14,
|
||||
0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
|
||||
0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
|
||||
0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55,
|
||||
}
|
||||
},
|
||||
{
|
||||
"FIPS 180-2 B.1 (one-block message)",
|
||||
"abc",
|
||||
{
|
||||
0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
|
||||
0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
|
||||
0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
|
||||
0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad,
|
||||
}
|
||||
},
|
||||
{
|
||||
/*
|
||||
* This message is *just* long enough to necessitate a
|
||||
* second block, which consists entirely of padding.
|
||||
*/
|
||||
"FIPS 180-2 B.2 (multi-block message)",
|
||||
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
|
||||
{
|
||||
0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8,
|
||||
0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
|
||||
0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
|
||||
0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1,
|
||||
}
|
||||
},
|
||||
{
|
||||
/*
|
||||
* 1,000,000 x 'a', filled in by t_prepare()
|
||||
*/
|
||||
"FIPS 180-2 B.3 (long message)",
|
||||
NULL,
|
||||
{
|
||||
0xcd, 0xc7, 0x6e, 0x5c, 0x99, 0x14, 0xfb, 0x92,
|
||||
0x81, 0xa1, 0xc7, 0xe2, 0x84, 0xd7, 0x3e, 0x67,
|
||||
0xf1, 0x80, 0x9a, 0x48, 0xa4, 0x97, 0x20, 0x0e,
|
||||
0x04, 0x6d, 0x39, 0xcc, 0xc7, 0x11, 0x2c, 0xd0,
|
||||
},
|
||||
},
|
||||
{
|
||||
/*
|
||||
* One of the MD5 test vectors, included for the "short
|
||||
* update" test.
|
||||
*/
|
||||
"\"1234567890\"x8",
|
||||
"1234567890123456789012345678901234567890"
|
||||
"1234567890123456789012345678901234567890",
|
||||
{
|
||||
0xf3, 0x71, 0xbc, 0x4a, 0x31, 0x1f, 0x2b, 0x00,
|
||||
0x9e, 0xef, 0x95, 0x2d, 0xd8, 0x3c, 0xa8, 0x0e,
|
||||
0x2b, 0x60, 0x02, 0x6c, 0x8e, 0x93, 0x55, 0x92,
|
||||
0xd0, 0xf9, 0xc3, 0x08, 0x45, 0x3c, 0x81, 0x3e,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* Unit test: compute the SHA256 sum of the specified string and compare it
|
||||
* to the expected result.
|
||||
*/
|
||||
static int
|
||||
t_sha256_vector(char **desc CRYB_UNUSED, void *arg)
|
||||
{
|
||||
struct t_vector *vector = (struct t_vector *)arg;
|
||||
uint8_t digest[SHA256_DIGEST_LEN];
|
||||
char *msg;
|
||||
|
||||
if (vector->msg) {
|
||||
t_sha256_complete(vector->msg, strlen(vector->msg), digest);
|
||||
} else {
|
||||
/* special case for FIPS test vector 3 */
|
||||
if ((msg = malloc(1000000)) == NULL)
|
||||
err(1, "malloc()");
|
||||
memset(msg, 'a', 1000000);
|
||||
t_sha256_complete(msg, 1000000, digest);
|
||||
free(msg);
|
||||
}
|
||||
if (memcmp(digest, vector->digest, SHA256_DIGEST_LEN) != 0) {
|
||||
t_verbose("expected ");
|
||||
t_verbose_hex(vector->digest, SHA256_DIGEST_LEN);
|
||||
t_verbose("\n");
|
||||
t_verbose("got ");
|
||||
t_verbose_hex(digest, SHA256_DIGEST_LEN);
|
||||
t_verbose("\n");
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
#if !defined(WITH_OPENSSL) && !defined(WITH_RSAREF)
|
||||
/*
|
||||
* Various corner cases and error conditions
|
||||
*/
|
||||
static int
|
||||
t_sha256_short_updates(char **desc CRYB_UNUSED, void *arg)
|
||||
{
|
||||
struct t_vector *vector = (struct t_vector *)arg;
|
||||
uint8_t digest[SHA256_DIGEST_LEN];
|
||||
sha256_ctx ctx;
|
||||
int i, len;
|
||||
|
||||
sha256_init(&ctx);
|
||||
len = strlen(vector->msg);
|
||||
for (i = 0; i + 5 < len; i += 5)
|
||||
sha256_update(&ctx, vector->msg + i, 5);
|
||||
sha256_update(&ctx, vector->msg + i, len - i);
|
||||
sha256_final(&ctx, digest);
|
||||
return (memcmp(digest, vector->digest, SHA256_DIGEST_LEN) == 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BENCHMARKS
|
||||
/*
|
||||
* Performance test: measure the time spent computing the SHA256 sum of a
|
||||
* message of the specified length.
|
||||
*/
|
||||
#define T_PERF_ITERATIONS 1000
|
||||
static int
|
||||
t_sha256_perf(char **desc, void *arg)
|
||||
{
|
||||
struct timespec ts, te;
|
||||
unsigned long ns;
|
||||
uint8_t digest[SHA256_DIGEST_LEN];
|
||||
char *msg, *comment;
|
||||
size_t msglen = *(size_t *)arg;
|
||||
|
||||
if ((msg = calloc(1, msglen)) == NULL)
|
||||
err(1, "calloc()");
|
||||
clock_gettime(CLOCK_MONOTONIC_PRECISE, &ts);
|
||||
for (int i = 0; i < T_PERF_ITERATIONS; ++i)
|
||||
t_sha256_complete(msg, msglen, digest);
|
||||
clock_gettime(CLOCK_MONOTONIC_PRECISE, &te);
|
||||
free(msg);
|
||||
ns = te.tv_sec * 1000000000LU + te.tv_nsec;
|
||||
ns -= ts.tv_sec * 1000000000LU + ts.tv_nsec;
|
||||
asprintf(&comment, "%zu bytes: %d iterations in %'lu ns",
|
||||
msglen, T_PERF_ITERATIONS, ns);
|
||||
if (comment == NULL)
|
||||
err(1, "asprintf()");
|
||||
*desc = comment;
|
||||
return (1);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Boilerplate
|
||||
*/
|
||||
|
||||
int
|
||||
t_prepare(int argc, char *argv[])
|
||||
{
|
||||
int i, n;
|
||||
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
n = sizeof t_sha256_vectors / sizeof t_sha256_vectors[0];
|
||||
for (i = 0; i < n; ++i)
|
||||
t_add_test(t_sha256_vector, &t_sha256_vectors[i],
|
||||
t_sha256_vectors[i].desc);
|
||||
#if !defined(WITH_OPENSSL) && !defined(WITH_RSAREF)
|
||||
/*
|
||||
* Run test vector 5 (md5 test vector 7, which is 80 characters
|
||||
* long) 5 characters at a time. This tests a) appending data to
|
||||
* an underfull block and b) appending more data to an underfull
|
||||
* block than it has room for (since 64 % 5 != 0). Test vector 4
|
||||
* and 5 already exercised the code path for computing a block
|
||||
* directly from source (without copying it in), and all the test
|
||||
* vectors except vector 1 exercised the general case of copying a
|
||||
* small amount of data in without crossing the block boundary.
|
||||
*/
|
||||
t_add_test(t_sha256_short_updates, &t_sha256_vectors[4],
|
||||
"multiple short updates");
|
||||
#endif
|
||||
#ifdef BENCHMARKS
|
||||
static size_t one = 1, thousand = 1000, million = 1000000;
|
||||
t_add_test(t_sha256_perf, &one,
|
||||
"performance test (1 byte)");
|
||||
t_add_test(t_sha256_perf, &thousand,
|
||||
"performance test (1,000 bytes)");
|
||||
t_add_test(t_sha256_perf, &million,
|
||||
"performance test (1,000,000 bytes)");
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
t_cleanup(void)
|
||||
{
|
||||
}
|
286
t/t_sha384.c
Normal file
286
t/t_sha384.c
Normal file
|
@ -0,0 +1,286 @@
|
|||
/*-
|
||||
* Copyright (c) 2012 Universitetet i Oslo
|
||||
* Copyright (c) 2012-2014 Dag-Erling Smørgrav
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||
* Sponsor: the University of Oslo
|
||||
*
|
||||
* $Cryb: trunk/t/t_sha384.c 3 2014-07-04 11:20:46Z des $
|
||||
*/
|
||||
|
||||
#include "cryb/impl.h"
|
||||
|
||||
#include <err.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "t.h"
|
||||
|
||||
#if WITH_OPENSSL
|
||||
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#define SHA384_DIGEST_LEN SHA384_DIGEST_LENGTH
|
||||
|
||||
static void
|
||||
t_sha384_complete(const void *msg, size_t msglen, uint8_t *digest)
|
||||
{
|
||||
SHA512_CTX ctx; /* yes, 512 is correct */
|
||||
|
||||
SHA384_Init(&ctx);
|
||||
SHA384_Update(&ctx, msg, msglen);
|
||||
SHA384_Final(digest, &ctx);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <cryb/sha384.h>
|
||||
|
||||
#define t_sha384_complete(msg, msglen, digest) \
|
||||
sha384_complete(msg, msglen, digest)
|
||||
|
||||
#endif
|
||||
|
||||
static struct t_vector {
|
||||
const char *desc;
|
||||
const char *msg;
|
||||
const uint8_t digest[SHA384_DIGEST_LEN];
|
||||
} t_sha384_vectors[] = {
|
||||
{
|
||||
"zero-length message",
|
||||
"",
|
||||
{
|
||||
0x38, 0xb0, 0x60, 0xa7, 0x51, 0xac, 0x96, 0x38,
|
||||
0x4c, 0xd9, 0x32, 0x7e, 0xb1, 0xb1, 0xe3, 0x6a,
|
||||
0x21, 0xfd, 0xb7, 0x11, 0x14, 0xbe, 0x07, 0x43,
|
||||
0x4c, 0x0c, 0xc7, 0xbf, 0x63, 0xf6, 0xe1, 0xda,
|
||||
0x27, 0x4e, 0xde, 0xbf, 0xe7, 0x6f, 0x65, 0xfb,
|
||||
0xd5, 0x1a, 0xd2, 0xf1, 0x48, 0x98, 0xb9, 0x5b,
|
||||
}
|
||||
},
|
||||
{
|
||||
"FIPS 180-2 D.1 (one-block message)",
|
||||
"abc",
|
||||
{
|
||||
0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b,
|
||||
0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07,
|
||||
0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63,
|
||||
0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed,
|
||||
0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23,
|
||||
0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7,
|
||||
}
|
||||
},
|
||||
{
|
||||
/*
|
||||
* This message is *just* long enough to necessitate a
|
||||
* second block, which consists entirely of padding.
|
||||
*/
|
||||
"FIPS 180-2 D.2 (multi-block message)",
|
||||
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
|
||||
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
|
||||
{
|
||||
0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8,
|
||||
0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47,
|
||||
0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2,
|
||||
0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12,
|
||||
0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9,
|
||||
0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39,
|
||||
}
|
||||
},
|
||||
{
|
||||
/*
|
||||
* 1,000,000 x 'a', filled in by t_prepare()
|
||||
*/
|
||||
"FIPS 180-2 D.3 (long message)",
|
||||
NULL,
|
||||
{
|
||||
0x9d, 0x0e, 0x18, 0x09, 0x71, 0x64, 0x74, 0xcb,
|
||||
0x08, 0x6e, 0x83, 0x4e, 0x31, 0x0a, 0x4a, 0x1c,
|
||||
0xed, 0x14, 0x9e, 0x9c, 0x00, 0xf2, 0x48, 0x52,
|
||||
0x79, 0x72, 0xce, 0xc5, 0x70, 0x4c, 0x2a, 0x5b,
|
||||
0x07, 0xb8, 0xb3, 0xdc, 0x38, 0xec, 0xc4, 0xeb,
|
||||
0xae, 0x97, 0xdd, 0xd8, 0x7f, 0x3d, 0x89, 0x85,
|
||||
},
|
||||
},
|
||||
{
|
||||
/*
|
||||
* One of the MD5 test vectors, included for the "short
|
||||
* update" test.
|
||||
*/
|
||||
"\"1234567890\"x8",
|
||||
"1234567890123456789012345678901234567890"
|
||||
"1234567890123456789012345678901234567890",
|
||||
{
|
||||
0xb1, 0x29, 0x32, 0xb0, 0x62, 0x7d, 0x1c, 0x06,
|
||||
0x09, 0x42, 0xf5, 0x44, 0x77, 0x64, 0x15, 0x56,
|
||||
0x55, 0xbd, 0x4d, 0xa0, 0xc9, 0xaf, 0xa6, 0xdd,
|
||||
0x9b, 0x9e, 0xf5, 0x31, 0x29, 0xaf, 0x1b, 0x8f,
|
||||
0xb0, 0x19, 0x59, 0x96, 0xd2, 0xde, 0x9c, 0xa0,
|
||||
0xdf, 0x9d, 0x82, 0x1f, 0xfe, 0xe6, 0x70, 0x26,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* Unit test: compute the SHA384 sum of the specified string and compare it
|
||||
* to the expected result.
|
||||
*/
|
||||
static int
|
||||
t_sha384_vector(char **desc CRYB_UNUSED, void *arg)
|
||||
{
|
||||
struct t_vector *vector = (struct t_vector *)arg;
|
||||
uint8_t digest[SHA384_DIGEST_LEN];
|
||||
char *msg;
|
||||
|
||||
if (vector->msg) {
|
||||
t_sha384_complete(vector->msg, strlen(vector->msg), digest);
|
||||
} else {
|
||||
/* special case for FIPS test vector 3 */
|
||||
if ((msg = malloc(1000000)) == NULL)
|
||||
err(1, "malloc()");
|
||||
memset(msg, 'a', 1000000);
|
||||
t_sha384_complete(msg, 1000000, digest);
|
||||
free(msg);
|
||||
}
|
||||
if (memcmp(digest, vector->digest, SHA384_DIGEST_LEN) != 0) {
|
||||
t_verbose("expected ");
|
||||
t_verbose_hex(vector->digest, SHA384_DIGEST_LEN);
|
||||
t_verbose("\n");
|
||||
t_verbose("got ");
|
||||
t_verbose_hex(digest, SHA384_DIGEST_LEN);
|
||||
t_verbose("\n");
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
#if !defined(WITH_OPENSSL) && !defined(WITH_RSAREF)
|
||||
/*
|
||||
* Various corner cases and error conditions
|
||||
*/
|
||||
static int
|
||||
t_sha384_short_updates(char **desc CRYB_UNUSED, void *arg)
|
||||
{
|
||||
struct t_vector *vector = (struct t_vector *)arg;
|
||||
uint8_t digest[SHA384_DIGEST_LEN];
|
||||
sha384_ctx ctx;
|
||||
int i, len;
|
||||
|
||||
sha384_init(&ctx);
|
||||
len = strlen(vector->msg);
|
||||
for (i = 0; i + 5 < len; i += 5)
|
||||
sha384_update(&ctx, vector->msg + i, 5);
|
||||
sha384_update(&ctx, vector->msg + i, len - i);
|
||||
sha384_final(&ctx, digest);
|
||||
return (memcmp(digest, vector->digest, SHA384_DIGEST_LEN) == 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BENCHMARKS
|
||||
/*
|
||||
* Performance test: measure the time spent computing the SHA384 sum of a
|
||||
* message of the specified length.
|
||||
*/
|
||||
#define T_PERF_ITERATIONS 1000
|
||||
static int
|
||||
t_sha384_perf(char **desc, void *arg)
|
||||
{
|
||||
struct timespec ts, te;
|
||||
unsigned long ns;
|
||||
uint8_t digest[SHA384_DIGEST_LEN];
|
||||
char *msg, *comment;
|
||||
size_t msglen = *(size_t *)arg;
|
||||
|
||||
if ((msg = calloc(1, msglen)) == NULL)
|
||||
err(1, "calloc()");
|
||||
clock_gettime(CLOCK_MONOTONIC_PRECISE, &ts);
|
||||
for (int i = 0; i < T_PERF_ITERATIONS; ++i)
|
||||
t_sha384_complete(msg, msglen, digest);
|
||||
clock_gettime(CLOCK_MONOTONIC_PRECISE, &te);
|
||||
free(msg);
|
||||
ns = te.tv_sec * 1000000000LU + te.tv_nsec;
|
||||
ns -= ts.tv_sec * 1000000000LU + ts.tv_nsec;
|
||||
asprintf(&comment, "%zu bytes: %d iterations in %'lu ns",
|
||||
msglen, T_PERF_ITERATIONS, ns);
|
||||
if (comment == NULL)
|
||||
err(1, "asprintf()");
|
||||
*desc = comment;
|
||||
return (1);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Boilerplate
|
||||
*/
|
||||
|
||||
int
|
||||
t_prepare(int argc, char *argv[])
|
||||
{
|
||||
int i, n;
|
||||
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
n = sizeof t_sha384_vectors / sizeof t_sha384_vectors[0];
|
||||
for (i = 0; i < n; ++i)
|
||||
t_add_test(t_sha384_vector, &t_sha384_vectors[i],
|
||||
t_sha384_vectors[i].desc);
|
||||
#if !defined(WITH_OPENSSL) && !defined(WITH_RSAREF)
|
||||
/*
|
||||
* Run test vector 5 (md5 test vector 7, which is 80 characters
|
||||
* long) 5 characters at a time. This tests a) appending data to
|
||||
* an underfull block and b) appending more data to an underfull
|
||||
* block than it has room for (since 64 % 5 != 0). Test vector 4
|
||||
* and 5 already exercised the code path for computing a block
|
||||
* directly from source (without copying it in), and all the test
|
||||
* vectors except vector 1 exercised the general case of copying a
|
||||
* small amount of data in without crossing the block boundary.
|
||||
*/
|
||||
t_add_test(t_sha384_short_updates, &t_sha384_vectors[4],
|
||||
"multiple short updates");
|
||||
#endif
|
||||
#ifdef BENCHMARKS
|
||||
static size_t one = 1, thousand = 1000, million = 1000000;
|
||||
t_add_test(t_sha384_perf, &one,
|
||||
"performance test (1 byte)");
|
||||
t_add_test(t_sha384_perf, &thousand,
|
||||
"performance test (1,000 bytes)");
|
||||
t_add_test(t_sha384_perf, &million,
|
||||
"performance test (1,000,000 bytes)");
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
t_cleanup(void)
|
||||
{
|
||||
}
|
296
t/t_sha512.c
Normal file
296
t/t_sha512.c
Normal file
|
@ -0,0 +1,296 @@
|
|||
/*-
|
||||
* Copyright (c) 2012 Universitetet i Oslo
|
||||
* Copyright (c) 2012-2014 Dag-Erling Smørgrav
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||
* Sponsor: the University of Oslo
|
||||
*
|
||||
* $Cryb$
|
||||
*/
|
||||
|
||||
#include "cryb/impl.h"
|
||||
|
||||
#include <err.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "t.h"
|
||||
|
||||
#if WITH_OPENSSL
|
||||
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#define SHA512_DIGEST_LEN SHA512_DIGEST_LENGTH
|
||||
|
||||
static void
|
||||
t_sha512_complete(const void *msg, size_t msglen, uint8_t *digest)
|
||||
{
|
||||
SHA512_CTX ctx;
|
||||
|
||||
SHA512_Init(&ctx);
|
||||
SHA512_Update(&ctx, msg, msglen);
|
||||
SHA512_Final(digest, &ctx);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <cryb/sha512.h>
|
||||
|
||||
#define t_sha512_complete(msg, msglen, digest) \
|
||||
sha512_complete(msg, msglen, digest)
|
||||
|
||||
#endif
|
||||
|
||||
static struct t_vector {
|
||||
const char *desc;
|
||||
const char *msg;
|
||||
const uint8_t digest[SHA512_DIGEST_LEN];
|
||||
} t_sha512_vectors[] = {
|
||||
{
|
||||
"zero-length message",
|
||||
"",
|
||||
{
|
||||
0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd,
|
||||
0xf1, 0x54, 0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07,
|
||||
0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc,
|
||||
0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce,
|
||||
0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0,
|
||||
0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f,
|
||||
0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81,
|
||||
0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e,
|
||||
}
|
||||
},
|
||||
{
|
||||
"FIPS 180-2 C.1 (one-block message)",
|
||||
"abc",
|
||||
{
|
||||
0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
|
||||
0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
|
||||
0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
|
||||
0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
|
||||
0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
|
||||
0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
|
||||
0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
|
||||
0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f,
|
||||
}
|
||||
},
|
||||
{
|
||||
/*
|
||||
* This message is *just* long enough to necessitate a
|
||||
* second block, which consists entirely of padding.
|
||||
*/
|
||||
"FIPS 180-2 C.2 (multi-block message)",
|
||||
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
|
||||
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
|
||||
{
|
||||
0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda,
|
||||
0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f,
|
||||
0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1,
|
||||
0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18,
|
||||
0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4,
|
||||
0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a,
|
||||
0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
|
||||
0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09,
|
||||
}
|
||||
},
|
||||
{
|
||||
/*
|
||||
* 1,000,000 x 'a', filled in by t_prepare()
|
||||
*/
|
||||
"FIPS 180-2 C.3 (long message)",
|
||||
NULL,
|
||||
{
|
||||
0xe7, 0x18, 0x48, 0x3d, 0x0c, 0xe7, 0x69, 0x64,
|
||||
0x4e, 0x2e, 0x42, 0xc7, 0xbc, 0x15, 0xb4, 0x63,
|
||||
0x8e, 0x1f, 0x98, 0xb1, 0x3b, 0x20, 0x44, 0x28,
|
||||
0x56, 0x32, 0xa8, 0x03, 0xaf, 0xa9, 0x73, 0xeb,
|
||||
0xde, 0x0f, 0xf2, 0x44, 0x87, 0x7e, 0xa6, 0x0a,
|
||||
0x4c, 0xb0, 0x43, 0x2c, 0xe5, 0x77, 0xc3, 0x1b,
|
||||
0xeb, 0x00, 0x9c, 0x5c, 0x2c, 0x49, 0xaa, 0x2e,
|
||||
0x4e, 0xad, 0xb2, 0x17, 0xad, 0x8c, 0xc0, 0x9b,
|
||||
},
|
||||
},
|
||||
{
|
||||
/*
|
||||
* One of the MD5 test vectors, included for the "short
|
||||
* update" test.
|
||||
*/
|
||||
"\"1234567890\"x8",
|
||||
"1234567890123456789012345678901234567890"
|
||||
"1234567890123456789012345678901234567890",
|
||||
{
|
||||
0x72, 0xec, 0x1e, 0xf1, 0x12, 0x4a, 0x45, 0xb0,
|
||||
0x47, 0xe8, 0xb7, 0xc7, 0x5a, 0x93, 0x21, 0x95,
|
||||
0x13, 0x5b, 0xb6, 0x1d, 0xe2, 0x4e, 0xc0, 0xd1,
|
||||
0x91, 0x40, 0x42, 0x24, 0x6e, 0x0a, 0xec, 0x3a,
|
||||
0x23, 0x54, 0xe0, 0x93, 0xd7, 0x6f, 0x30, 0x48,
|
||||
0xb4, 0x56, 0x76, 0x43, 0x46, 0x90, 0x0c, 0xb1,
|
||||
0x30, 0xd2, 0xa4, 0xfd, 0x5d, 0xd1, 0x6a, 0xbb,
|
||||
0x5e, 0x30, 0xbc, 0xb8, 0x50, 0xde, 0xe8, 0x43,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* Unit test: compute the SHA512 sum of the specified string and compare it
|
||||
* to the expected result.
|
||||
*/
|
||||
static int
|
||||
t_sha512_vector(char **desc CRYB_UNUSED, void *arg)
|
||||
{
|
||||
struct t_vector *vector = (struct t_vector *)arg;
|
||||
uint8_t digest[SHA512_DIGEST_LEN];
|
||||
char *msg;
|
||||
|
||||
if (vector->msg) {
|
||||
t_sha512_complete(vector->msg, strlen(vector->msg), digest);
|
||||
} else {
|
||||
/* special case for FIPS test vector 3 */
|
||||
if ((msg = malloc(1000000)) == NULL)
|
||||
err(1, "malloc()");
|
||||
memset(msg, 'a', 1000000);
|
||||
t_sha512_complete(msg, 1000000, digest);
|
||||
free(msg);
|
||||
}
|
||||
if (memcmp(digest, vector->digest, SHA512_DIGEST_LEN) != 0) {
|
||||
t_verbose("expected ");
|
||||
t_verbose_hex(vector->digest, SHA512_DIGEST_LEN);
|
||||
t_verbose("\n");
|
||||
t_verbose("got ");
|
||||
t_verbose_hex(digest, SHA512_DIGEST_LEN);
|
||||
t_verbose("\n");
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
#if !defined(WITH_OPENSSL) && !defined(WITH_RSAREF)
|
||||
/*
|
||||
* Various corner cases and error conditions
|
||||
*/
|
||||
static int
|
||||
t_sha512_short_updates(char **desc CRYB_UNUSED, void *arg)
|
||||
{
|
||||
struct t_vector *vector = (struct t_vector *)arg;
|
||||
uint8_t digest[SHA512_DIGEST_LEN];
|
||||
sha512_ctx ctx;
|
||||
int i, len;
|
||||
|
||||
sha512_init(&ctx);
|
||||
len = strlen(vector->msg);
|
||||
for (i = 0; i + 5 < len; i += 5)
|
||||
sha512_update(&ctx, vector->msg + i, 5);
|
||||
sha512_update(&ctx, vector->msg + i, len - i);
|
||||
sha512_final(&ctx, digest);
|
||||
return (memcmp(digest, vector->digest, SHA512_DIGEST_LEN) == 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BENCHMARKS
|
||||
/*
|
||||
* Performance test: measure the time spent computing the SHA512 sum of a
|
||||
* message of the specified length.
|
||||
*/
|
||||
#define T_PERF_ITERATIONS 1000
|
||||
static int
|
||||
t_sha512_perf(char **desc, void *arg)
|
||||
{
|
||||
struct timespec ts, te;
|
||||
unsigned long ns;
|
||||
uint8_t digest[SHA512_DIGEST_LEN];
|
||||
char *msg, *comment;
|
||||
size_t msglen = *(size_t *)arg;
|
||||
|
||||
if ((msg = calloc(1, msglen)) == NULL)
|
||||
err(1, "calloc()");
|
||||
clock_gettime(CLOCK_MONOTONIC_PRECISE, &ts);
|
||||
for (int i = 0; i < T_PERF_ITERATIONS; ++i)
|
||||
t_sha512_complete(msg, msglen, digest);
|
||||
clock_gettime(CLOCK_MONOTONIC_PRECISE, &te);
|
||||
free(msg);
|
||||
ns = te.tv_sec * 1000000000LU + te.tv_nsec;
|
||||
ns -= ts.tv_sec * 1000000000LU + ts.tv_nsec;
|
||||
asprintf(&comment, "%zu bytes: %d iterations in %'lu ns",
|
||||
msglen, T_PERF_ITERATIONS, ns);
|
||||
if (comment == NULL)
|
||||
err(1, "asprintf()");
|
||||
*desc = comment;
|
||||
return (1);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Boilerplate
|
||||
*/
|
||||
|
||||
int
|
||||
t_prepare(int argc, char *argv[])
|
||||
{
|
||||
int i, n;
|
||||
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
n = sizeof t_sha512_vectors / sizeof t_sha512_vectors[0];
|
||||
for (i = 0; i < n; ++i)
|
||||
t_add_test(t_sha512_vector, &t_sha512_vectors[i],
|
||||
t_sha512_vectors[i].desc);
|
||||
#if !defined(WITH_OPENSSL) && !defined(WITH_RSAREF)
|
||||
/*
|
||||
* Run test vector 5 (md5 test vector 7, which is 80 characters
|
||||
* long) 5 characters at a time. This tests a) appending data to
|
||||
* an underfull block and b) appending more data to an underfull
|
||||
* block than it has room for (since 64 % 5 != 0). Test vector 4
|
||||
* and 5 already exercised the code path for computing a block
|
||||
* directly from source (without copying it in), and all the test
|
||||
* vectors except vector 1 exercised the general case of copying a
|
||||
* small amount of data in without crossing the block boundary.
|
||||
*/
|
||||
t_add_test(t_sha512_short_updates, &t_sha512_vectors[4],
|
||||
"multiple short updates");
|
||||
#endif
|
||||
#ifdef BENCHMARKS
|
||||
static size_t one = 1, thousand = 1000, million = 1000000;
|
||||
t_add_test(t_sha512_perf, &one,
|
||||
"performance test (1 byte)");
|
||||
t_add_test(t_sha512_perf, &thousand,
|
||||
"performance test (1,000 bytes)");
|
||||
t_add_test(t_sha512_perf, &million,
|
||||
"performance test (1,000,000 bytes)");
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
t_cleanup(void)
|
||||
{
|
||||
}
|
Loading…
Reference in a new issue