Add one-shot |MD4| function.

This could live in decrepit, but it's tiny and having it makes the
interface more uniform that what we have for MD5 so I put it in the main
code. This is to more easily support nmap.

Change-Id: Ia098cc7ef6e00a90d2f3f56ee7deba8329c9a82e
Reviewed-by: David Benjamin <>
diff --git a/crypto/md4/md4.c b/crypto/md4/md4.c
index 86a540b..f79da9f 100644
--- a/crypto/md4/md4.c
+++ b/crypto/md4/md4.c
@@ -60,6 +60,15 @@
 #include <string.h>
+uint8_t *MD4(const uint8_t *data, size_t len, uint8_t *out) {
+  MD4_CTX ctx;
+  MD4_Init(&ctx);
+  MD4_Update(&ctx, data, len);
+  MD4_Final(out, &ctx);
+  return out;
 /* Implemented from RFC1186 The MD4 Message-Digest Algorithm. */
 int MD4_Init(MD4_CTX *md4) {
diff --git a/include/openssl/md4.h b/include/openssl/md4.h
index 93c7af8..b66fcb0 100644
--- a/include/openssl/md4.h
+++ b/include/openssl/md4.h
@@ -83,6 +83,10 @@
  * returns one. */
 OPENSSL_EXPORT int MD4_Final(uint8_t *md, MD4_CTX *md4);
+/* MD4 writes the digest of |len| bytes from |data| to |out| and returns |out|.
+ * There must be at least |MD4_DIGEST_LENGTH| bytes of space in |out|. */
+OPENSSL_EXPORT uint8_t *MD4(const uint8_t *data, size_t len, uint8_t *out);
 /* MD4_Transform is a low-level function that performs a single, MD4 block
  * transformation using the state from |md4| and 64 bytes from |block|. */
 OPENSSL_EXPORT void MD4_Transform(MD4_CTX *md4, const uint8_t *block);