typedef void (*digest_func)(void *, size_t, uint8_t *);
typedef void (*set_key_func)(void *, size_t, const uint8_t *);
typedef void (*set_nonce_func)(void *, size_t, const uint8_t *);
+typedef void (*init_func)(void *);
static int wrap_nettle_hash_init(gnutls_digest_algorithm_t algo, void **_ctx);
size_t length;
update_func update;
digest_func digest;
+ init_func init;
};
struct nettle_mac_ctx {
digest + MD5_DIGEST_SIZE);
}
+static void _md5_sha1_init(void *_ctx)
+{
+ struct md5_sha1_ctx *ctx = _ctx;
+
+ md5_init(&ctx->md5);
+ sha1_init(&ctx->sha1);
+}
+
static int _ctx_init(gnutls_digest_algorithm_t algo,
struct nettle_hash_ctx *ctx)
{
* gnutls_hash_init() and gnutls_hmac_init() */
switch (algo) {
case GNUTLS_DIG_MD5:
- md5_init(&ctx->ctx.md5);
+ ctx->init = (init_func)md5_init;
ctx->update = (update_func)md5_update;
ctx->digest = (digest_func)md5_digest;
ctx->ctx_ptr = &ctx->ctx.md5;
ctx->length = MD5_DIGEST_SIZE;
break;
case GNUTLS_DIG_SHA1:
- sha1_init(&ctx->ctx.sha1);
+ ctx->init = (init_func)sha1_init;
ctx->update = (update_func)sha1_update;
ctx->digest = (digest_func)sha1_digest;
ctx->ctx_ptr = &ctx->ctx.sha1;
ctx->length = SHA1_DIGEST_SIZE;
break;
case GNUTLS_DIG_MD5_SHA1:
- md5_init(&ctx->ctx.md5_sha1.md5);
- sha1_init(&ctx->ctx.md5_sha1.sha1);
+ ctx->init = (init_func)_md5_sha1_init;
ctx->update = (update_func)_md5_sha1_update;
ctx->digest = (digest_func)_md5_sha1_digest;
ctx->ctx_ptr = &ctx->ctx.md5_sha1;
ctx->length = MD5_DIGEST_SIZE + SHA1_DIGEST_SIZE;
break;
case GNUTLS_DIG_SHA224:
- sha224_init(&ctx->ctx.sha224);
+ ctx->init = (init_func)sha224_init;
ctx->update = (update_func)sha224_update;
ctx->digest = (digest_func)sha224_digest;
ctx->ctx_ptr = &ctx->ctx.sha224;
ctx->length = SHA224_DIGEST_SIZE;
break;
case GNUTLS_DIG_SHA256:
- sha256_init(&ctx->ctx.sha256);
+ ctx->init = (init_func)sha256_init;
ctx->update = (update_func)sha256_update;
ctx->digest = (digest_func)sha256_digest;
ctx->ctx_ptr = &ctx->ctx.sha256;
ctx->length = SHA256_DIGEST_SIZE;
break;
case GNUTLS_DIG_SHA384:
- sha384_init(&ctx->ctx.sha384);
+ ctx->init = (init_func)sha384_init;
ctx->update = (update_func)sha384_update;
ctx->digest = (digest_func)sha384_digest;
ctx->ctx_ptr = &ctx->ctx.sha384;
ctx->length = SHA384_DIGEST_SIZE;
break;
case GNUTLS_DIG_SHA512:
- sha512_init(&ctx->ctx.sha512);
+ ctx->init = (init_func)sha512_init;
ctx->update = (update_func)sha512_update;
ctx->digest = (digest_func)sha512_digest;
ctx->ctx_ptr = &ctx->ctx.sha512;
break;
#ifdef NETTLE_SHA3_FIPS202
case GNUTLS_DIG_SHA3_224:
- sha3_224_init(&ctx->ctx.sha3_224);
+ ctx->init = (init_func)sha3_224_init;
ctx->update = (update_func)sha3_224_update;
ctx->digest = (digest_func)sha3_224_digest;
ctx->ctx_ptr = &ctx->ctx.sha3_224;
ctx->length = SHA3_224_DIGEST_SIZE;
break;
case GNUTLS_DIG_SHA3_256:
- sha3_256_init(&ctx->ctx.sha3_256);
+ ctx->init = (init_func)sha3_256_init;
ctx->update = (update_func)sha3_256_update;
ctx->digest = (digest_func)sha3_256_digest;
ctx->ctx_ptr = &ctx->ctx.sha3_256;
ctx->length = SHA3_256_DIGEST_SIZE;
break;
case GNUTLS_DIG_SHA3_384:
- sha3_384_init(&ctx->ctx.sha3_384);
+ ctx->init = (init_func)sha3_384_init;
ctx->update = (update_func)sha3_384_update;
ctx->digest = (digest_func)sha3_384_digest;
ctx->ctx_ptr = &ctx->ctx.sha3_384;
ctx->length = SHA3_384_DIGEST_SIZE;
break;
case GNUTLS_DIG_SHA3_512:
- sha3_512_init(&ctx->ctx.sha3_512);
+ ctx->init = (init_func)sha3_512_init;
ctx->update = (update_func)sha3_512_update;
ctx->digest = (digest_func)sha3_512_digest;
ctx->ctx_ptr = &ctx->ctx.sha3_512;
ctx->length = SHA3_512_DIGEST_SIZE;
break;
case GNUTLS_DIG_SHAKE_128:
- sha3_128_init(&ctx->ctx.sha3_128);
+ ctx->init = (init_func)sha3_128_init;
ctx->update = (update_func)sha3_128_update;
ctx->digest = (digest_func)sha3_128_shake_output;
ctx->ctx_ptr = &ctx->ctx.sha3_128;
ctx->length = 0; /* unused */
break;
case GNUTLS_DIG_SHAKE_256:
- sha3_256_init(&ctx->ctx.sha3_256);
+ ctx->init = (init_func)sha3_256_init;
ctx->update = (update_func)sha3_256_update;
ctx->digest = (digest_func)sha3_256_shake_output;
ctx->ctx_ptr = &ctx->ctx.sha3_256;
break;
#endif
case GNUTLS_DIG_MD2:
- md2_init(&ctx->ctx.md2);
+ ctx->init = (init_func)md2_init;
ctx->update = (update_func)md2_update;
ctx->digest = (digest_func)md2_digest;
ctx->ctx_ptr = &ctx->ctx.md2;
break;
case GNUTLS_DIG_RMD160:
- ripemd160_init(&ctx->ctx.ripemd160);
+ ctx->init = (init_func)ripemd160_init;
ctx->update = (update_func)ripemd160_update;
ctx->digest = (digest_func)ripemd160_digest;
ctx->ctx_ptr = &ctx->ctx.ripemd160;
break;
#if ENABLE_GOST
case GNUTLS_DIG_GOSTR_94:
- gosthash94cp_init(&ctx->ctx.gosthash94cp);
+ ctx->init = (init_func)gosthash94cp_init;
ctx->update = (update_func)gosthash94cp_update;
ctx->digest = (digest_func)gosthash94cp_digest;
ctx->ctx_ptr = &ctx->ctx.gosthash94cp;
ctx->length = GOSTHASH94_DIGEST_SIZE;
break;
case GNUTLS_DIG_STREEBOG_256:
- streebog256_init(&ctx->ctx.streebog256);
+ ctx->init = (init_func)streebog256_init;
ctx->update = (update_func)streebog256_update;
ctx->digest = (digest_func)streebog256_digest;
ctx->ctx_ptr = &ctx->ctx.streebog256;
ctx->length = STREEBOG256_DIGEST_SIZE;
break;
case GNUTLS_DIG_STREEBOG_512:
- streebog512_init(&ctx->ctx.streebog512);
+ ctx->init = (init_func)streebog512_init;
ctx->update = (update_func)streebog512_update;
ctx->digest = (digest_func)streebog512_digest;
ctx->ctx_ptr = &ctx->ctx.streebog512;
gnutls_assert();
return GNUTLS_E_INVALID_REQUEST;
}
-
+ ctx->init(ctx->ctx_ptr);
return 0;
}
struct nettle_hash_ctx *ctx;
ctx = src_ctx;
+ if (digest == NULL) {
+ ctx->init(ctx->ctx_ptr);
+ return 0;
+ }
+
if (ctx->length > 0 && digestsize < ctx->length) {
gnutls_assert();
return GNUTLS_E_SHORT_MEMORY_BUFFER;