lib: add crypt subsystem

Add the basic functionality required to support the standard crypt
format.
The files crypt-sha256.c and crypt-sha512.c originate from libxcrypt and
their formatting is therefor retained.
The integration is done via a crypt_compare() function in crypt.c.

```
libxcrypt $ git describe --long --always --all
tags/v4.4.17-0-g6b110bc
```

Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Heiko Schocher <hs@denx.de>
diff --git a/test/Kconfig b/test/Kconfig
index ab3ac54..e15ba23 100644
--- a/test/Kconfig
+++ b/test/Kconfig
@@ -38,6 +38,16 @@
 	  Enables a test which exercises asn1 compiler and decoder function
 	  via various parsers.
 
+config UT_LIB_CRYPT
+	bool "Unit test for crypt-style password hashing"
+	depends on !SPL && AUTOBOOT_KEYED && AUTOBOOT_ENCRYPTION
+	default y
+	select CRYPT_PW
+	select CRYPT_PW_SHA256
+	select CRYPT_PW_SHA512
+	help
+	  Enables a test for the crypt-style password hash functions.
+
 config UT_LIB_RSA
 	bool "Unit test for rsa_verify() function"
 	depends on RSA
diff --git a/test/lib/Makefile b/test/lib/Makefile
index aa2e66b..6fd0514 100644
--- a/test/lib/Makefile
+++ b/test/lib/Makefile
@@ -17,3 +17,4 @@
 obj-$(CONFIG_UT_LIB_RSA) += rsa.o
 obj-$(CONFIG_AES) += test_aes.o
 obj-$(CONFIG_GETOPT) += getopt.o
+obj-$(CONFIG_UT_LIB_CRYPT) += test_crypt.o
diff --git a/test/lib/test_crypt.c b/test/lib/test_crypt.c
new file mode 100644
index 0000000..277e4ef
--- /dev/null
+++ b/test/lib/test_crypt.c
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2021 Steffen Jaeckel
+ *
+ * Unit test for crypt-style password hashing
+ */
+
+#include <common.h>
+#include <test/lib.h>
+#include <test/test.h>
+#include <test/ut.h>
+
+#include <crypt.h>
+
+/**
+ * lib_crypt() - unit test for crypt-style password hashing
+ *
+ * @uts:	unit test state
+ * Return:	0 = success, 1 = failure
+ */
+static int lib_crypt(struct unit_test_state *uts)
+{
+	int equals = 0;
+
+	if (IS_ENABLED(CONFIG_CRYPT_PW_SHA256)) {
+		crypt_compare(
+			"$5$rounds=640000$TM4lL4zXDG7F4aRX$JM7a9wmvodnA0WasjTztj6mxg.KVuk6doQ/eBhdcapB",
+			"password", &equals);
+		ut_assertf(equals == 1,
+			   "crypt-sha256 password hash didn't match\n");
+	}
+	equals = 0;
+	if (IS_ENABLED(CONFIG_CRYPT_PW_SHA512)) {
+		crypt_compare(
+			"$6$rounds=640000$fCTP1F0N5JLq2eND$z5EzK5KZJA9JnOaj5d1Gg/2v6VqFOQJ3bVekWuCPauabutBt/8qzV1exJnytUyhbq3H0bSBXtodwNbtGEi/Tm/",
+			"password", &equals);
+		ut_assertf(equals == 1,
+			   "crypt-sha512 password hash didn't match\n");
+	}
+
+	return CMD_RET_SUCCESS;
+}
+
+LIB_TEST(lib_crypt, 0);