md: Implement one-shot md5

Which can be used for non-cryptographic purposes
even in FIPS mode.

Signed-off-by: Pavol Žáčik <pzacik@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
Pavol Žáčik
2025-12-18 10:08:16 +01:00
committed by Jakub Jelen
parent 83ae6b3f0a
commit 2c5bb17211
4 changed files with 104 additions and 0 deletions

View File

@@ -75,6 +75,7 @@ MD5CTX md5_init(void);
void md5_ctx_free(MD5CTX);
int md5_update(MD5CTX c, const void *data, size_t len);
int md5_final(unsigned char *md, MD5CTX c);
int md5(const unsigned char *digest, size_t len, unsigned char *hash);
SHACTX sha1_init(void);
void sha1_ctx_free(SHACTX);

View File

@@ -322,3 +322,52 @@ md5_final(unsigned char *md, MD5CTX c)
}
return SSH_OK;
}
/**
* @ brief One-shot MD5. Not intended for use in security-relevant contexts.
*/
int
md5(const unsigned char *digest, size_t len, unsigned char *hash)
{
int rc, ret = SSH_ERROR;
unsigned int mdlen = 0;
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
EVP_MD *md5 = NULL;
#endif
MD5CTX c = EVP_MD_CTX_new();
if (c == NULL) {
goto out;
}
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
md5 = EVP_MD_fetch(NULL, "MD5", "provider=default,-fips");
if (md5 == NULL) {
goto out;
}
rc = EVP_DigestInit(c, md5);
#else
rc = EVP_DigestInit_ex(c, EVP_md5(), NULL);
#endif
if (rc == 0) {
goto out;
}
rc = EVP_DigestUpdate(c, digest, len);
if (rc != 1) {
goto out;
}
rc = EVP_DigestFinal(c, hash, &mdlen);
if (rc != 1) {
goto out;
}
ret = SSH_OK;
out:
EVP_MD_CTX_free(c);
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
EVP_MD_free(md5);
#endif
return ret;
}

View File

@@ -244,3 +244,9 @@ md5_final(unsigned char *md, MD5CTX c)
gcry_md_close(c);
return SSH_OK;
}
int md5(const unsigned char *digest, size_t len, unsigned char *hash)
{
gcry_md_hash_buffer(GCRY_MD_MD5, hash, digest, len);
return SSH_OK;
}

View File

@@ -405,3 +405,51 @@ md5_final(unsigned char *md, MD5CTX c)
}
return SSH_OK;
}
int md5(const unsigned char *digest, size_t len, unsigned char *hash)
{
MD5CTX ctx = NULL;
int rc;
const mbedtls_md_info_t *md_info =
mbedtls_md_info_from_type(MBEDTLS_MD_MD5);
if (md_info == NULL) {
return SSH_ERROR;
}
ctx = malloc(sizeof(mbedtls_md_context_t));
if (ctx == NULL) {
return SSH_ERROR;
}
mbedtls_md_init(ctx);
rc = mbedtls_md_setup(ctx, md_info, 0);
if (rc != 0) {
mbedtls_md_free(ctx);
SAFE_FREE(ctx);
return SSH_ERROR;
}
rc = mbedtls_md_starts(ctx);
if (rc != 0) {
mbedtls_md_free(ctx);
SAFE_FREE(ctx);
return SSH_ERROR;
}
rc = mbedtls_md_update(ctx, digest, len);
if (rc != 0) {
mbedtls_md_free(ctx);
SAFE_FREE(ctx);
return SSH_ERROR;
}
rc = mbedtls_md_finish(ctx, hash);
mbedtls_md_free(ctx);
SAFE_FREE(ctx);
if (rc != 0) {
return SSH_ERROR;
}
return SSH_OK;
}