#include <string.h>
#include <isc/hmacsha.h>
#include <isc/sha1.h>
#include <isc/sha2.h>
#include <isc/util.h>
void
isc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key,
unsigned int len)
{
ctx->ctx = HMAC_CTX_new();
RUNTIME_CHECK(ctx->ctx != NULL);
RUNTIME_CHECK(HMAC_Init_ex(ctx->ctx, (const void *) key,
(int) len, EVP_sha1(), NULL) == 1);
}
void
isc_hmacsha1_invalidate(isc_hmacsha1_t *ctx) {
if (ctx->ctx == NULL)
return;
HMAC_CTX_free(ctx->ctx);
ctx->ctx = NULL;
}
void
isc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf,
unsigned int len)
{
RUNTIME_CHECK(HMAC_Update(ctx->ctx, buf, (int) len) == 1);
}
void
isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
RUNTIME_CHECK(HMAC_Final(ctx->ctx, newdigest, NULL) == 1);
HMAC_CTX_free(ctx->ctx);
ctx->ctx = NULL;
memmove(digest, newdigest, len);
explicit_bzero(newdigest, sizeof(newdigest));
}
void
isc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key,
unsigned int len)
{
ctx->ctx = HMAC_CTX_new();
RUNTIME_CHECK(ctx->ctx != NULL);
RUNTIME_CHECK(HMAC_Init_ex(ctx->ctx, (const void *) key,
(int) len, EVP_sha224(), NULL) == 1);
}
void
isc_hmacsha224_invalidate(isc_hmacsha224_t *ctx) {
if (ctx->ctx == NULL)
return;
HMAC_CTX_free(ctx->ctx);
ctx->ctx = NULL;
}
void
isc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf,
unsigned int len)
{
RUNTIME_CHECK(HMAC_Update(ctx->ctx, buf, (int) len) == 1);
}
void
isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
RUNTIME_CHECK(HMAC_Final(ctx->ctx, newdigest, NULL) == 1);
HMAC_CTX_free(ctx->ctx);
ctx->ctx = NULL;
memmove(digest, newdigest, len);
explicit_bzero(newdigest, sizeof(newdigest));
}
void
isc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key,
unsigned int len)
{
ctx->ctx = HMAC_CTX_new();
RUNTIME_CHECK(ctx->ctx != NULL);
RUNTIME_CHECK(HMAC_Init_ex(ctx->ctx, (const void *) key,
(int) len, EVP_sha256(), NULL) == 1);
}
void
isc_hmacsha256_invalidate(isc_hmacsha256_t *ctx) {
if (ctx->ctx == NULL)
return;
HMAC_CTX_free(ctx->ctx);
ctx->ctx = NULL;
}
void
isc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf,
unsigned int len)
{
RUNTIME_CHECK(HMAC_Update(ctx->ctx, buf, (int) len) == 1);
}
void
isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
RUNTIME_CHECK(HMAC_Final(ctx->ctx, newdigest, NULL) == 1);
HMAC_CTX_free(ctx->ctx);
ctx->ctx = NULL;
memmove(digest, newdigest, len);
explicit_bzero(newdigest, sizeof(newdigest));
}
void
isc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key,
unsigned int len)
{
ctx->ctx = HMAC_CTX_new();
RUNTIME_CHECK(ctx->ctx != NULL);
RUNTIME_CHECK(HMAC_Init_ex(ctx->ctx, (const void *) key,
(int) len, EVP_sha384(), NULL) == 1);
}
void
isc_hmacsha384_invalidate(isc_hmacsha384_t *ctx) {
if (ctx->ctx == NULL)
return;
HMAC_CTX_free(ctx->ctx);
ctx->ctx = NULL;
}
void
isc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf,
unsigned int len)
{
RUNTIME_CHECK(HMAC_Update(ctx->ctx, buf, (int) len) == 1);
}
void
isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
RUNTIME_CHECK(HMAC_Final(ctx->ctx, newdigest, NULL) == 1);
HMAC_CTX_free(ctx->ctx);
ctx->ctx = NULL;
memmove(digest, newdigest, len);
explicit_bzero(newdigest, sizeof(newdigest));
}
void
isc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key,
unsigned int len)
{
ctx->ctx = HMAC_CTX_new();
RUNTIME_CHECK(ctx->ctx != NULL);
RUNTIME_CHECK(HMAC_Init_ex(ctx->ctx, (const void *) key,
(int) len, EVP_sha512(), NULL) == 1);
}
void
isc_hmacsha512_invalidate(isc_hmacsha512_t *ctx) {
if (ctx->ctx == NULL)
return;
HMAC_CTX_free(ctx->ctx);
ctx->ctx = NULL;
}
void
isc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf,
unsigned int len)
{
RUNTIME_CHECK(HMAC_Update(ctx->ctx, buf, (int) len) == 1);
}
void
isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
unsigned char newdigest[ISC_SHA512_DIGESTLENGTH];
REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
RUNTIME_CHECK(HMAC_Final(ctx->ctx, newdigest, NULL) == 1);
HMAC_CTX_free(ctx->ctx);
ctx->ctx = NULL;
memmove(digest, newdigest, len);
explicit_bzero(newdigest, sizeof(newdigest));
}
int
isc_hmacsha1_verify(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
isc_hmacsha1_sign(ctx, newdigest, ISC_SHA1_DIGESTLENGTH);
return (timingsafe_bcmp(digest, newdigest, len) == 0);
}
int
isc_hmacsha224_verify(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
isc_hmacsha224_sign(ctx, newdigest, ISC_SHA224_DIGESTLENGTH);
return (timingsafe_bcmp(digest, newdigest, len) == 0);
}
int
isc_hmacsha256_verify(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
isc_hmacsha256_sign(ctx, newdigest, ISC_SHA256_DIGESTLENGTH);
return (timingsafe_bcmp(digest, newdigest, len) == 0);
}
int
isc_hmacsha384_verify(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
isc_hmacsha384_sign(ctx, newdigest, ISC_SHA384_DIGESTLENGTH);
return (timingsafe_bcmp(digest, newdigest, len) == 0);
}
int
isc_hmacsha512_verify(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
unsigned char newdigest[ISC_SHA512_DIGESTLENGTH];
REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
isc_hmacsha512_sign(ctx, newdigest, ISC_SHA512_DIGESTLENGTH);
return (timingsafe_bcmp(digest, newdigest, len) == 0);
}