Index: trunk/src/VBox/Runtime/common/crypto/shacrypt-256.cpp.h
===================================================================
--- trunk/src/VBox/Runtime/common/crypto/shacrypt-256.cpp.h	(revision 102491)
+++ 	(revision )
@@ -1,282 +1,0 @@
-/* $Id$ */
-/** @file
- * IPRT - Crypto - SHA-crypt, code template for SHA-256 core.
- *
- * This is almost identical to shacrypt-512.cpp.h, fixes generally applies to
- * both. Diff the files after updates!
- */
-
-/*
- * Copyright (C) 2023 Oracle and/or its affiliates.
- *
- * This file is part of VirtualBox base platform packages, as
- * available from https://www.virtualbox.org.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation, in version 3 of the
- * License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <https://www.gnu.org/licenses>.
- *
- * The contents of this file may alternatively be used under the terms
- * of the Common Development and Distribution License Version 1.0
- * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
- * in the VirtualBox distribution, in which case the provisions of the
- * CDDL are applicable instead of those of the GPL.
- *
- * You may elect to license modified versions of this file under the
- * terms and conditions of either the GPL or the CDDL or both.
- *
- * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
- */
-
-
-RTDECL(int) RTCrShaCrypt256(const char *pszPhrase, const char *pszSalt, uint32_t cRounds, char *pszString, size_t cbString)
-{
-    uint8_t abHash[RTSHA256_HASH_SIZE];
-    int rc = RTCrShaCrypt256Ex(pszPhrase, pszSalt, cRounds, abHash);
-    if (RT_SUCCESS(rc))
-        rc = RTCrShaCrypt256ToString(abHash, pszSalt, cRounds, pszString, cbString);
-    return rc;
-}
-
-
-RTR3DECL(int) RTCrShaCrypt256Ex(const char *pszPhrase, const char *pszSalt, uint32_t cRounds, uint8_t pabHash[RTSHA256_HASH_SIZE])
-{
-    /*
-     * Validate and adjust input.
-     */
-    AssertPtrReturn(pszPhrase, VERR_INVALID_POINTER);
-    size_t const cchPhrase = strlen(pszPhrase);
-    AssertReturn(cchPhrase, VERR_INVALID_PARAMETER);
-
-    AssertPtrReturn(pszSalt, VERR_INVALID_POINTER);
-    size_t cchSalt;
-    pszSalt = rtCrShaCryptExtractSaltAndRounds(pszSalt, &cchSalt, &cRounds);
-    AssertReturn(pszSalt != NULL, VERR_INVALID_PARAMETER);
-    AssertReturn(cchSalt >= RT_SHACRYPT_SALT_MIN_LEN, VERR_BUFFER_UNDERFLOW);
-    AssertReturn(cchSalt <= RT_SHACRYPT_SALT_MAX_LEN, VERR_TOO_MUCH_DATA);
-    AssertReturn(cRounds >= RT_SHACRYPT_ROUNDS_MIN && cRounds <= RT_SHACRYPT_ROUNDS_MAX, VERR_OUT_OF_RANGE);
-
-    /*
-     * Get started...
-     */
-    RTSHA256CONTEXT CtxA;
-    RTSha256Init(&CtxA);                                                        /* Step 1. */
-    RTSha256Update(&CtxA, pszPhrase, cchPhrase);                                /* Step 2. */
-    RTSha256Update(&CtxA, pszSalt, cchSalt);                                    /* Step 3. */
-
-    RTSHA256CONTEXT CtxB;
-    RTSha256Init(&CtxB);                                                        /* Step 4. */
-    RTSha256Update(&CtxB, pszPhrase, cchPhrase);                                /* Step 5. */
-    RTSha256Update(&CtxB, pszSalt, cchSalt);                                    /* Step 6. */
-    RTSha256Update(&CtxB, pszPhrase, cchPhrase);                                /* Step 7. */
-    uint8_t abDigest[RTSHA256_HASH_SIZE];
-    RTSha256Final(&CtxB, abDigest);                                             /* Step 8. */
-
-    size_t cbLeft = cchPhrase;
-    while (cbLeft > RTSHA256_HASH_SIZE)                                         /* Step 9. */
-    {
-        RTSha256Update(&CtxA, abDigest, sizeof(abDigest));
-        cbLeft -= RTSHA256_HASH_SIZE;
-    }
-    RTSha256Update(&CtxA, abDigest, cbLeft);                                    /* Step 10. */
-
-    size_t iPhraseBit = cchPhrase;
-    while (iPhraseBit)                                                          /* Step 11. */
-    {
-        if ((iPhraseBit & 1) != 0)
-            RTSha256Update(&CtxA, abDigest, sizeof(abDigest));                  /* a) */
-        else
-            RTSha256Update(&CtxA, pszPhrase, cchPhrase);                        /* b) */
-        iPhraseBit >>= 1;
-    }
-
-    RTSha256Final(&CtxA, abDigest);                                             /* Step 12. */
-
-    RTSha256Init(&CtxB);                                                        /* Step 13. */
-    for (size_t i = 0; i < cchPhrase; i++)                                      /* Step 14. */
-        RTSha256Update(&CtxB, pszPhrase, cchPhrase);
-
-    uint8_t abDigestTemp[RTSHA256_HASH_SIZE];
-    RTSha256Final(&CtxB, abDigestTemp);                                         /* Step 15. */
-
-    /*
-     * Byte sequence P (= password).
-     */
-    /* Step 16. */
-    size_t const cbSeqP  = cchPhrase;
-    uint8_t     *pabSeqP = (uint8_t *)RTMemTmpAllocZ(cbSeqP + 1);               /* +1 because the password may be empty */
-    uint8_t     *pb       = pabSeqP;
-    AssertPtrReturn(pabSeqP, VERR_NO_MEMORY);
-    cbLeft = cbSeqP;
-    while (cbLeft > RTSHA256_HASH_SIZE)
-    {
-        memcpy(pb, abDigestTemp, sizeof(abDigestTemp));                         /* a) */
-        pb     += RTSHA256_HASH_SIZE;
-        cbLeft -= RTSHA256_HASH_SIZE;
-    }
-    memcpy(pb, abDigestTemp, cbLeft);                                           /* b) */
-
-    RTSha256Init(&CtxB);                                                        /* Step 17. */
-
-    for (size_t i = 0; i < 16 + (unsigned)abDigest[0]; i++)                     /* Step 18. */
-        RTSha256Update(&CtxB, pszSalt, cchSalt);
-
-    RTSha256Final(&CtxB, abDigestTemp);                                         /* Step 19. */
-
-    /*
-     * Byte sequence S (= salt).
-     */
-    /* Step 20. */
-    size_t   const  cbSeqS  = cchSalt;
-#if 0 /* Given that the salt has a fixed range (8 thru 16 bytes), and SHA-256
-       * producing 64 bytes, we can safely skip the loop part here (a) and go
-       * straight for step (b). Further, we can drop the whole memory allocation,
-       * let alone duplication (it's all overwritten!), and use an uninitalized
-       * stack buffer. */
-    uint8_t * const pabSeqS = (uint8_t *)RTMemDup(pszSalt, cbSeqS + 1);
-    AssertPtrReturn(pabSeqS, VERR_NO_MEMORY);
-
-    pb     = pabSeqS;
-    cbLeft = cbSeqS;
-    while (cbLeft > RTSHA256_HASH_SIZE)
-    {
-        memcpy(pb, (void *)abDigestTemp, sizeof(abDigestTemp));                 /* a) */
-        pb     += RTSHA256_HASH_SIZE;
-        cbLeft -= RTSHA256_HASH_SIZE
-    }
-    memcpy(pb, abDigestTemp, cbLeft);                                           /* b) */
-#else
-    AssertCompile(RT_SHACRYPT_SALT_MAX_LEN < RTSHA256_HASH_SIZE);
-    uint8_t         abSeqS[RT_SHACRYPT_SALT_MAX_LEN + 2];
-    uint8_t * const pabSeqS = abSeqS;
-    memcpy(abSeqS, abDigestTemp, cbSeqS);                                       /* b) */
-#endif
-
-    /* Step 21. */
-    for (uint32_t iRound = 0; iRound < cRounds; iRound++)
-    {
-        RTSHA256CONTEXT CtxC;
-        RTSha256Init(&CtxC);                                                    /* a) */
-
-        if ((iRound & 1) != 0)
-            RTSha256Update(&CtxC, pabSeqP, cbSeqP);                             /* b) */
-        else
-            RTSha256Update(&CtxC, abDigest, sizeof(abDigest));                  /* c) */
-
-        if (iRound % 3 != 0)                                                    /* d) */
-            RTSha256Update(&CtxC, pabSeqS, cbSeqS);
-
-        if (iRound % 7 != 0)
-            RTSha256Update(&CtxC, pabSeqP, cbSeqP);                             /* e) */
-
-        if ((iRound & 1) != 0)
-            RTSha256Update(&CtxC, abDigest, sizeof(abDigest));                  /* f) */
-        else
-            RTSha256Update(&CtxC, pabSeqP, cbSeqP);                             /* g) */
-
-        RTSha256Final(&CtxC, abDigest);                                         /* h) */
-    }
-
-    /*
-     * Done.
-     */
-    memcpy(pabHash, abDigest, RTSHA256_HASH_SIZE);
-
-    /*
-     * Cleanup.
-     */
-    RTMemWipeThoroughly(abDigestTemp, RTSHA256_HASH_SIZE, 3);
-    RTMemWipeThoroughly(pabSeqP, cbSeqP, 3);
-    RTMemTmpFree(pabSeqP);
-#if 0
-    RTMemWipeThoroughly(pabSeqS, cbSeqS, 3);
-    RTMemFree(pabSeqS);
-#else
-    RTMemWipeThoroughly(abSeqS, sizeof(abSeqS), 3);
-#endif
-
-    return VINF_SUCCESS;
-}
-
-
-RTR3DECL(int) RTCrShaCrypt256ToString(uint8_t const pabHash[RTSHA256_HASH_SIZE], const char *pszSalt, uint32_t cRounds,
-                                      char *pszString, size_t cbString)
-{
-    /*
-     * Validate and adjust input.
-     */
-    AssertPtrReturn(pszSalt, VERR_INVALID_POINTER);
-    size_t cchSalt;
-    pszSalt = rtCrShaCryptExtractSaltAndRounds(pszSalt, &cchSalt, &cRounds);
-    AssertReturn(pszSalt != NULL, VERR_INVALID_PARAMETER);
-    AssertReturn(cchSalt >= RT_SHACRYPT_SALT_MIN_LEN, VERR_BUFFER_UNDERFLOW);
-    AssertReturn(cchSalt <= RT_SHACRYPT_SALT_MAX_LEN, VERR_TOO_MUCH_DATA);
-    AssertReturn(cRounds >= RT_SHACRYPT_ROUNDS_MIN && cRounds <= RT_SHACRYPT_ROUNDS_MAX, VERR_OUT_OF_RANGE);
-
-    AssertPtrReturn(pszString, VERR_INVALID_POINTER);
-
-    /*
-     * Calc the necessary buffer space and check that the caller supplied enough.
-     */
-    char    szRounds[64];
-    ssize_t cchRounds = 0;
-    if (cRounds != RT_SHACRYPT_ROUNDS_DEFAULT)
-    {
-        cchRounds = RTStrFormatU32(szRounds, sizeof(szRounds), cRounds, 10, 0, 0, 0);
-        Assert(cchRounds > 0 && cchRounds <= 9);
-    }
-
-    size_t const cchNeeded = sizeof(RT_SHACRYPT_ID_STR_256) - 1
-                           + (cRounds != RT_SHACRYPT_ROUNDS_DEFAULT ? cchRounds + sizeof("rounds=$") - 1 : 0)
-                           + cchSalt + 1
-                           + RTSHA256_HASH_SIZE * 4 / 3
-                           + 1;
-    AssertReturn(cbString > cchNeeded, VERR_BUFFER_OVERFLOW);
-
-    /*
-     * Do the formatting.
-     */
-    memcpy(pszString, RT_STR_TUPLE(RT_SHACRYPT_ID_STR_256));
-    size_t off = sizeof(RT_SHACRYPT_ID_STR_256) - 1;
-
-    if (cRounds != RT_SHACRYPT_ROUNDS_DEFAULT)
-    {
-        memcpy(&pszString[off], RT_STR_TUPLE("rounds="));
-        off += sizeof("rounds=") - 1;
-
-        memcpy(&pszString[off], szRounds, cchRounds);
-        off += cchRounds;
-        pszString[off++] = '$';
-    }
-
-    memcpy(&pszString[off], pszSalt, cchSalt);
-    off += cchSalt;
-    pszString[off++] = '$';
-
-    BASE64_ENCODE(pszString, off, pabHash[00], pabHash[10], pabHash[20], 4);
-    BASE64_ENCODE(pszString, off, pabHash[21], pabHash[ 1], pabHash[11], 4);
-    BASE64_ENCODE(pszString, off, pabHash[12], pabHash[22], pabHash[ 2], 4);
-    BASE64_ENCODE(pszString, off, pabHash[ 3], pabHash[13], pabHash[23], 4);
-    BASE64_ENCODE(pszString, off, pabHash[24], pabHash[ 4], pabHash[14], 4);
-    BASE64_ENCODE(pszString, off, pabHash[15], pabHash[25], pabHash[ 5], 4);
-    BASE64_ENCODE(pszString, off, pabHash[ 6], pabHash[16], pabHash[26], 4);
-    BASE64_ENCODE(pszString, off, pabHash[27], pabHash[ 7], pabHash[17], 4);
-    BASE64_ENCODE(pszString, off, pabHash[18], pabHash[28], pabHash[ 8], 4);
-    BASE64_ENCODE(pszString, off, pabHash[ 9], pabHash[19], pabHash[29], 4);
-    BASE64_ENCODE(pszString, off, 0,           pabHash[31], pabHash[30], 3);
-
-    pszString[off] = '\0';
-    Assert(off < cbString);
-
-    return VINF_SUCCESS;
-}
-
Index: trunk/src/VBox/Runtime/common/crypto/shacrypt-512.cpp.h
===================================================================
--- trunk/src/VBox/Runtime/common/crypto/shacrypt-512.cpp.h	(revision 102491)
+++ 	(revision )
@@ -1,294 +1,0 @@
-/* $Id$ */
-/** @file
- * IPRT - Crypto - SHA-crypt, code template for SHA-512 core.
- *
- * This is almost identical to shacrypt-256.cpp.h, fixes generally applies to
- * both. Diff the files after updates!
- */
-
-/*
- * Copyright (C) 2023 Oracle and/or its affiliates.
- *
- * This file is part of VirtualBox base platform packages, as
- * available from https://www.virtualbox.org.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation, in version 3 of the
- * License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <https://www.gnu.org/licenses>.
- *
- * The contents of this file may alternatively be used under the terms
- * of the Common Development and Distribution License Version 1.0
- * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
- * in the VirtualBox distribution, in which case the provisions of the
- * CDDL are applicable instead of those of the GPL.
- *
- * You may elect to license modified versions of this file under the
- * terms and conditions of either the GPL or the CDDL or both.
- *
- * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
- */
-
-
-RTDECL(int) RTCrShaCrypt512(const char *pszPhrase, const char *pszSalt, uint32_t cRounds, char *pszString, size_t cbString)
-{
-    uint8_t abHash[RTSHA512_HASH_SIZE];
-    int rc = RTCrShaCrypt512Ex(pszPhrase, pszSalt, cRounds, abHash);
-    if (RT_SUCCESS(rc))
-        rc = RTCrShaCrypt512ToString(abHash, pszSalt, cRounds, pszString, cbString);
-    return rc;
-}
-
-
-
-RTR3DECL(int) RTCrShaCrypt512Ex(const char *pszPhrase, const char *pszSalt, uint32_t cRounds, uint8_t pabHash[RTSHA512_HASH_SIZE])
-{
-    /*
-     * Validate and adjust input.
-     */
-    AssertPtrReturn(pszPhrase, VERR_INVALID_POINTER);
-    size_t const cchPhrase = strlen(pszPhrase);
-    AssertReturn(cchPhrase, VERR_INVALID_PARAMETER);
-
-    AssertPtrReturn(pszSalt, VERR_INVALID_POINTER);
-    size_t cchSalt;
-    pszSalt = rtCrShaCryptExtractSaltAndRounds(pszSalt, &cchSalt, &cRounds);
-    AssertReturn(pszSalt != NULL, VERR_INVALID_PARAMETER);
-    AssertReturn(cchSalt >= RT_SHACRYPT_SALT_MIN_LEN, VERR_BUFFER_UNDERFLOW);
-    AssertReturn(cchSalt <= RT_SHACRYPT_SALT_MAX_LEN, VERR_TOO_MUCH_DATA);
-    AssertReturn(cRounds >= RT_SHACRYPT_ROUNDS_MIN && cRounds <= RT_SHACRYPT_ROUNDS_MAX, VERR_OUT_OF_RANGE);
-
-    /*
-     * Get started...
-     */
-    RTSHA512CONTEXT CtxA;
-    RTSha512Init(&CtxA);                                                        /* Step 1. */
-    RTSha512Update(&CtxA, pszPhrase, cchPhrase);                                /* Step 2. */
-    RTSha512Update(&CtxA, pszSalt, cchSalt);                                    /* Step 3. */
-
-    RTSHA512CONTEXT CtxB;
-    RTSha512Init(&CtxB);                                                        /* Step 4. */
-    RTSha512Update(&CtxB, pszPhrase, cchPhrase);                                /* Step 5. */
-    RTSha512Update(&CtxB, pszSalt, cchSalt);                                    /* Step 6. */
-    RTSha512Update(&CtxB, pszPhrase, cchPhrase);                                /* Step 7. */
-    uint8_t abDigest[RTSHA512_HASH_SIZE];
-    RTSha512Final(&CtxB, abDigest);                                             /* Step 8. */
-
-    size_t cbLeft = cchPhrase;
-    while (cbLeft > RTSHA512_HASH_SIZE)                                         /* Step 9. */
-    {
-        RTSha512Update(&CtxA, abDigest, sizeof(abDigest));
-        cbLeft -= RTSHA512_HASH_SIZE;
-    }
-    RTSha512Update(&CtxA, abDigest, cbLeft);                                    /* Step 10. */
-
-    size_t iPhraseBit = cchPhrase;
-    while (iPhraseBit)                                                          /* Step 11. */
-    {
-        if ((iPhraseBit & 1) != 0)
-            RTSha512Update(&CtxA, abDigest, sizeof(abDigest));                  /* a) */
-        else
-            RTSha512Update(&CtxA, pszPhrase, cchPhrase);                        /* b) */
-        iPhraseBit >>= 1;
-    }
-
-    RTSha512Final(&CtxA, abDigest);                                             /* Step 12. */
-
-    RTSha512Init(&CtxB);                                                        /* Step 13. */
-    for (size_t i = 0; i < cchPhrase; i++)                                      /* Step 14. */
-        RTSha512Update(&CtxB, pszPhrase, cchPhrase);
-
-    uint8_t abDigestTemp[RTSHA512_HASH_SIZE];
-    RTSha512Final(&CtxB, abDigestTemp);                                         /* Step 15. */
-
-    /*
-     * Byte sequence P (= password).
-     */
-    /* Step 16. */
-    size_t const cbSeqP  = cchPhrase;
-    uint8_t     *pabSeqP = (uint8_t *)RTMemTmpAllocZ(cbSeqP + 1);               /* +1 because the password may be empty */
-    uint8_t     *pb       = pabSeqP;
-    AssertPtrReturn(pabSeqP, VERR_NO_MEMORY);
-    cbLeft = cbSeqP;
-    while (cbLeft > RTSHA512_HASH_SIZE)
-    {
-        memcpy(pb, abDigestTemp, sizeof(abDigestTemp));                         /* a) */
-        pb     += RTSHA512_HASH_SIZE;
-        cbLeft -= RTSHA512_HASH_SIZE;
-    }
-    memcpy(pb, abDigestTemp, cbLeft);                                           /* b) */
-
-    RTSha512Init(&CtxB);                                                        /* Step 17. */
-
-    for (size_t i = 0; i < 16 + (unsigned)abDigest[0]; i++)                     /* Step 18. */
-        RTSha512Update(&CtxB, pszSalt, cchSalt);
-
-    RTSha512Final(&CtxB, abDigestTemp);                                         /* Step 19. */
-
-    /*
-     * Byte sequence S (= salt).
-     */
-    /* Step 20. */
-    size_t   const  cbSeqS  = cchSalt;
-#if 0 /* Given that the salt has a fixed range (8 thru 16 bytes), and SHA-512
-       * producing 64 bytes, we can safely skip the loop part here (a) and go
-       * straight for step (b). Further, we can drop the whole memory allocation,
-       * let alone duplication (it's all overwritten!), and use an uninitalized
-       * stack buffer. */
-    uint8_t * const pabSeqS = (uint8_t *)RTMemDup(pszSalt, cbSeqS + 1);
-    AssertPtrReturn(pabSeqS, VERR_NO_MEMORY);
-
-    pb     = pabSeqS;
-    cbLeft = cbSeqS;
-    while (cbLeft > RTSHA512_HASH_SIZE)
-    {
-        memcpy(pb, (void *)abDigestTemp, sizeof(abDigestTemp));                 /* a) */
-        pb     += RTSHA512_HASH_SIZE;
-        cbLeft -= RTSHA512_HASH_SIZE
-    }
-    memcpy(pb, abDigestTemp, cbLeft);                                           /* b) */
-#else
-    AssertCompile(RT_SHACRYPT_SALT_MAX_LEN < RTSHA512_HASH_SIZE);
-    uint8_t         abSeqS[RT_SHACRYPT_SALT_MAX_LEN + 2];
-    uint8_t * const pabSeqS = abSeqS;
-    memcpy(abSeqS, abDigestTemp, cbSeqS);                                       /* b) */
-#endif
-
-    /* Step 21. */
-    for (uint32_t iRound = 0; iRound < cRounds; iRound++)
-    {
-        RTSHA512CONTEXT CtxC;
-        RTSha512Init(&CtxC);                                                    /* a) */
-
-        if ((iRound & 1) != 0)
-            RTSha512Update(&CtxC, pabSeqP, cbSeqP);                             /* b) */
-        else
-            RTSha512Update(&CtxC, abDigest, sizeof(abDigest));                  /* c) */
-
-        if (iRound % 3 != 0)                                                    /* d) */
-            RTSha512Update(&CtxC, pabSeqS, cbSeqS);
-
-        if (iRound % 7 != 0)
-            RTSha512Update(&CtxC, pabSeqP, cbSeqP);                             /* e) */
-
-        if ((iRound & 1) != 0)
-            RTSha512Update(&CtxC, abDigest, sizeof(abDigest));                  /* f) */
-        else
-            RTSha512Update(&CtxC, pabSeqP, cbSeqP);                             /* g) */
-
-        RTSha512Final(&CtxC, abDigest);                                         /* h) */
-    }
-
-    /*
-     * Done.
-     */
-    memcpy(pabHash, abDigest, RTSHA512_HASH_SIZE);
-
-    /*
-     * Cleanup.
-     */
-    RTMemWipeThoroughly(abDigestTemp, RTSHA512_HASH_SIZE, 3);
-    RTMemWipeThoroughly(pabSeqP, cbSeqP, 3);
-    RTMemTmpFree(pabSeqP);
-#if 0
-    RTMemWipeThoroughly(pabSeqS, cbSeqS, 3);
-    RTMemFree(pabSeqS);
-#else
-    RTMemWipeThoroughly(abSeqS, sizeof(abSeqS), 3);
-#endif
-
-    return VINF_SUCCESS;
-}
-
-
-RTR3DECL(int) RTCrShaCrypt512ToString(uint8_t const pabHash[RTSHA512_HASH_SIZE], const char *pszSalt, uint32_t cRounds,
-                                      char *pszString, size_t cbString)
-{
-    /*
-     * Validate and adjust input.
-     */
-    AssertPtrReturn(pszSalt, VERR_INVALID_POINTER);
-    size_t cchSalt;
-    pszSalt = rtCrShaCryptExtractSaltAndRounds(pszSalt, &cchSalt, &cRounds);
-    AssertReturn(pszSalt != NULL, VERR_INVALID_PARAMETER);
-    AssertReturn(cchSalt >= RT_SHACRYPT_SALT_MIN_LEN, VERR_BUFFER_UNDERFLOW);
-    AssertReturn(cchSalt <= RT_SHACRYPT_SALT_MAX_LEN, VERR_TOO_MUCH_DATA);
-    AssertReturn(cRounds >= RT_SHACRYPT_ROUNDS_MIN && cRounds <= RT_SHACRYPT_ROUNDS_MAX, VERR_OUT_OF_RANGE);
-
-    AssertPtrReturn(pszString, VERR_INVALID_POINTER);
-
-    /*
-     * Calc the necessary buffer space and check that the caller supplied enough.
-     */
-    char    szRounds[64];
-    ssize_t cchRounds = 0;
-    if (cRounds != RT_SHACRYPT_ROUNDS_DEFAULT)
-    {
-        cchRounds = RTStrFormatU32(szRounds, sizeof(szRounds), cRounds, 10, 0, 0, 0);
-        Assert(cchRounds > 0 && cchRounds <= 9);
-    }
-
-    size_t const cchNeeded = sizeof(RT_SHACRYPT_ID_STR_512) - 1
-                           + (cRounds != RT_SHACRYPT_ROUNDS_DEFAULT ? cchRounds + sizeof("rounds=$") - 1 : 0)
-                           + cchSalt + 1
-                           + RTSHA512_HASH_SIZE * 4 / 3
-                           + 1;
-    AssertReturn(cbString > cchNeeded, VERR_BUFFER_OVERFLOW);
-
-    /*
-     * Do the formatting.
-     */
-    memcpy(pszString, RT_STR_TUPLE(RT_SHACRYPT_ID_STR_512));
-    size_t off = sizeof(RT_SHACRYPT_ID_STR_512) - 1;
-
-    if (cRounds != RT_SHACRYPT_ROUNDS_DEFAULT)
-    {
-        memcpy(&pszString[off], RT_STR_TUPLE("rounds="));
-        off += sizeof("rounds=") - 1;
-
-        memcpy(&pszString[off], szRounds, cchRounds);
-        off += cchRounds;
-        pszString[off++] = '$';
-    }
-
-    memcpy(&pszString[off], pszSalt, cchSalt);
-    off += cchSalt;
-    pszString[off++] = '$';
-
-    BASE64_ENCODE(pszString, off, pabHash[ 0], pabHash[21], pabHash[42], 4);
-    BASE64_ENCODE(pszString, off, pabHash[22], pabHash[43], pabHash[ 1], 4);
-    BASE64_ENCODE(pszString, off, pabHash[44], pabHash[ 2], pabHash[23], 4);
-    BASE64_ENCODE(pszString, off, pabHash[ 3], pabHash[24], pabHash[45], 4);
-    BASE64_ENCODE(pszString, off, pabHash[25], pabHash[46], pabHash[ 4], 4);
-    BASE64_ENCODE(pszString, off, pabHash[47], pabHash[ 5], pabHash[26], 4);
-    BASE64_ENCODE(pszString, off, pabHash[ 6], pabHash[27], pabHash[48], 4);
-    BASE64_ENCODE(pszString, off, pabHash[28], pabHash[49], pabHash[ 7], 4);
-    BASE64_ENCODE(pszString, off, pabHash[50], pabHash[ 8], pabHash[29], 4);
-    BASE64_ENCODE(pszString, off, pabHash[ 9], pabHash[30], pabHash[51], 4);
-    BASE64_ENCODE(pszString, off, pabHash[31], pabHash[52], pabHash[10], 4);
-    BASE64_ENCODE(pszString, off, pabHash[53], pabHash[11], pabHash[32], 4);
-    BASE64_ENCODE(pszString, off, pabHash[12], pabHash[33], pabHash[54], 4);
-    BASE64_ENCODE(pszString, off, pabHash[34], pabHash[55], pabHash[13], 4);
-    BASE64_ENCODE(pszString, off, pabHash[56], pabHash[14], pabHash[35], 4);
-    BASE64_ENCODE(pszString, off, pabHash[15], pabHash[36], pabHash[57], 4);
-    BASE64_ENCODE(pszString, off, pabHash[37], pabHash[58], pabHash[16], 4);
-    BASE64_ENCODE(pszString, off, pabHash[59], pabHash[17], pabHash[38], 4);
-    BASE64_ENCODE(pszString, off, pabHash[18], pabHash[39], pabHash[60], 4);
-    BASE64_ENCODE(pszString, off, pabHash[40], pabHash[61], pabHash[19], 4);
-    BASE64_ENCODE(pszString, off, pabHash[62], pabHash[20], pabHash[41], 4);
-    BASE64_ENCODE(pszString, off,           0,           0, pabHash[63], 2);
-
-    pszString[off] = '\0';
-    Assert(off < cbString);
-
-    return VINF_SUCCESS;
-}
-
Index: trunk/src/VBox/Runtime/common/crypto/shacrypt-tmpl.cpp.h
===================================================================
--- trunk/src/VBox/Runtime/common/crypto/shacrypt-tmpl.cpp.h	(revision 102495)
+++ trunk/src/VBox/Runtime/common/crypto/shacrypt-tmpl.cpp.h	(revision 102495)
@@ -0,0 +1,325 @@
+/* $Id$ */
+/** @file
+ * IPRT - Crypto - SHA-crypt, code template the core code.
+ *
+ * This is included a couple of times from shacrypt.cpp with different set of
+ * defines for each variation.
+ */
+
+/*
+ * Copyright (C) 2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
+ * in the VirtualBox distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
+ */
+
+
+RTDECL(int) RTCrShaCryptTmpl(const char *pszPhrase, const char *pszSalt, uint32_t cRounds, char *pszString, size_t cbString)
+{
+    uint8_t abHash[TMPL_HASH_SIZE];
+    int rc = RTCrShaCryptTmplEx(pszPhrase, pszSalt, cRounds, abHash);
+    if (RT_SUCCESS(rc))
+        rc = RTCrShaCryptTmplToString(abHash, pszSalt, cRounds, pszString, cbString);
+    return rc;
+}
+
+
+
+RTR3DECL(int) RTCrShaCryptTmplEx(const char *pszPhrase, const char *pszSalt, uint32_t cRounds, uint8_t pabHash[TMPL_HASH_SIZE])
+{
+    /*
+     * Validate and adjust input.
+     */
+    AssertPtrReturn(pszPhrase, VERR_INVALID_POINTER);
+    size_t const cchPhrase = strlen(pszPhrase);
+    AssertReturn(cchPhrase, VERR_INVALID_PARAMETER);
+
+    AssertPtrReturn(pszSalt, VERR_INVALID_POINTER);
+    size_t cchSalt;
+    pszSalt = rtCrShaCryptExtractSaltAndRounds(pszSalt, &cchSalt, &cRounds);
+    AssertReturn(pszSalt != NULL, VERR_INVALID_PARAMETER);
+    AssertReturn(cchSalt >= RT_SHACRYPT_SALT_MIN_LEN, VERR_BUFFER_UNDERFLOW);
+    AssertReturn(cchSalt <= RT_SHACRYPT_SALT_MAX_LEN, VERR_TOO_MUCH_DATA);
+    AssertReturn(cRounds >= RT_SHACRYPT_ROUNDS_MIN && cRounds <= RT_SHACRYPT_ROUNDS_MAX, VERR_OUT_OF_RANGE);
+
+    /*
+     * Get started...
+     */
+    TMPL_HASH_CONTEXT_T CtxA;
+    TmplHashInit(&CtxA);                                                        /* Step 1. */
+    TmplHashUpdate(&CtxA, pszPhrase, cchPhrase);                                /* Step 2. */
+    TmplHashUpdate(&CtxA, pszSalt, cchSalt);                                    /* Step 3. */
+
+    TMPL_HASH_CONTEXT_T CtxB;
+    TmplHashInit(&CtxB);                                                        /* Step 4. */
+    TmplHashUpdate(&CtxB, pszPhrase, cchPhrase);                                /* Step 5. */
+    TmplHashUpdate(&CtxB, pszSalt, cchSalt);                                    /* Step 6. */
+    TmplHashUpdate(&CtxB, pszPhrase, cchPhrase);                                /* Step 7. */
+    uint8_t abDigest[TMPL_HASH_SIZE];
+    TmplHashFinal(&CtxB, abDigest);                                             /* Step 8. */
+
+    size_t cbLeft = cchPhrase;
+    while (cbLeft > TMPL_HASH_SIZE)                                             /* Step 9. */
+    {
+        TmplHashUpdate(&CtxA, abDigest, sizeof(abDigest));
+        cbLeft -= TMPL_HASH_SIZE;
+    }
+    TmplHashUpdate(&CtxA, abDigest, cbLeft);                                    /* Step 10. */
+
+    size_t iPhraseBit = cchPhrase;
+    while (iPhraseBit)                                                          /* Step 11. */
+    {
+        if ((iPhraseBit & 1) != 0)
+            TmplHashUpdate(&CtxA, abDigest, sizeof(abDigest));                  /* a) */
+        else
+            TmplHashUpdate(&CtxA, pszPhrase, cchPhrase);                        /* b) */
+        iPhraseBit >>= 1;
+    }
+
+    TmplHashFinal(&CtxA, abDigest);                                             /* Step 12. */
+
+    TmplHashInit(&CtxB);                                                        /* Step 13. */
+    for (size_t i = 0; i < cchPhrase; i++)                                      /* Step 14. */
+        TmplHashUpdate(&CtxB, pszPhrase, cchPhrase);
+
+    uint8_t abDigestTemp[TMPL_HASH_SIZE];
+    TmplHashFinal(&CtxB, abDigestTemp);                                         /* Step 15. */
+
+    /*
+     * Byte sequence P (= password).
+     */
+    /* Step 16. */
+    size_t const cbSeqP  = cchPhrase;
+    uint8_t     *pabSeqP = (uint8_t *)RTMemTmpAllocZ(cbSeqP + 1);               /* +1 because the password may be empty */
+    uint8_t     *pb       = pabSeqP;
+    AssertPtrReturn(pabSeqP, VERR_NO_MEMORY);
+    cbLeft = cbSeqP;
+    while (cbLeft > TMPL_HASH_SIZE)
+    {
+        memcpy(pb, abDigestTemp, sizeof(abDigestTemp));                         /* a) */
+        pb     += TMPL_HASH_SIZE;
+        cbLeft -= TMPL_HASH_SIZE;
+    }
+    memcpy(pb, abDigestTemp, cbLeft);                                           /* b) */
+
+    TmplHashInit(&CtxB);                                                        /* Step 17. */
+
+    for (size_t i = 0; i < 16 + (unsigned)abDigest[0]; i++)                     /* Step 18. */
+        TmplHashUpdate(&CtxB, pszSalt, cchSalt);
+
+    TmplHashFinal(&CtxB, abDigestTemp);                                         /* Step 19. */
+
+    /*
+     * Byte sequence S (= salt).
+     */
+    /* Step 20. */
+    size_t   const  cbSeqS  = cchSalt;
+#if 0 /* Given that the salt has a fixed range (8 thru 16 bytes), and SHA-512/256
+       * producing 64 bytes, we can safely skip the loop part here (a) and go
+       * straight for step (b). Further, we can drop the whole memory allocation,
+       * let alone duplication (it's all overwritten!), and use an uninitalized
+       * stack buffer. */
+    uint8_t * const pabSeqS = (uint8_t *)RTMemDup(pszSalt, cbSeqS + 1);
+    AssertPtrReturn(pabSeqS, VERR_NO_MEMORY);
+
+    pb     = pabSeqS;
+    cbLeft = cbSeqS;
+    while (cbLeft > TMPL_HASH_SIZE)
+    {
+        memcpy(pb, (void *)abDigestTemp, sizeof(abDigestTemp));                 /* a) */
+        pb     += TMPL_HASH_SIZE;
+        cbLeft -= TMPL_HASH_SIZE
+    }
+    memcpy(pb, abDigestTemp, cbLeft);                                           /* b) */
+#else
+    AssertCompile(RT_SHACRYPT_SALT_MAX_LEN < TMPL_HASH_SIZE);
+    uint8_t         abSeqS[RT_SHACRYPT_SALT_MAX_LEN + 2];
+    uint8_t * const pabSeqS = abSeqS;
+    memcpy(abSeqS, abDigestTemp, cbSeqS);                                       /* b) */
+#endif
+
+    /* Step 21. */
+    for (uint32_t iRound = 0; iRound < cRounds; iRound++)
+    {
+        TMPL_HASH_CONTEXT_T CtxC;
+        TmplHashInit(&CtxC);                                                    /* a) */
+
+        if ((iRound & 1) != 0)
+            TmplHashUpdate(&CtxC, pabSeqP, cbSeqP);                             /* b) */
+        else
+            TmplHashUpdate(&CtxC, abDigest, sizeof(abDigest));                  /* c) */
+
+        if (iRound % 3 != 0)                                                    /* d) */
+            TmplHashUpdate(&CtxC, pabSeqS, cbSeqS);
+
+        if (iRound % 7 != 0)
+            TmplHashUpdate(&CtxC, pabSeqP, cbSeqP);                             /* e) */
+
+        if ((iRound & 1) != 0)
+            TmplHashUpdate(&CtxC, abDigest, sizeof(abDigest));                  /* f) */
+        else
+            TmplHashUpdate(&CtxC, pabSeqP, cbSeqP);                             /* g) */
+
+        TmplHashFinal(&CtxC, abDigest);                                         /* h) */
+    }
+
+    /*
+     * Done.
+     */
+    memcpy(pabHash, abDigest, TMPL_HASH_SIZE);
+
+    /*
+     * Cleanup.
+     */
+    RTMemWipeThoroughly(abDigestTemp, TMPL_HASH_SIZE, 3);
+    RTMemWipeThoroughly(pabSeqP, cbSeqP, 3);
+    RTMemTmpFree(pabSeqP);
+#if 0
+    RTMemWipeThoroughly(pabSeqS, cbSeqS, 3);
+    RTMemFree(pabSeqS);
+#else
+    RTMemWipeThoroughly(abSeqS, sizeof(abSeqS), 3);
+#endif
+
+    return VINF_SUCCESS;
+}
+
+
+RTR3DECL(int) RTCrShaCryptTmplToString(uint8_t const pabHash[TMPL_HASH_SIZE], const char *pszSalt, uint32_t cRounds,
+                                       char *pszString, size_t cbString)
+{
+    /*
+     * Validate and adjust input.
+     */
+    AssertPtrReturn(pszSalt, VERR_INVALID_POINTER);
+    size_t cchSalt;
+    pszSalt = rtCrShaCryptExtractSaltAndRounds(pszSalt, &cchSalt, &cRounds);
+    AssertReturn(pszSalt != NULL, VERR_INVALID_PARAMETER);
+    AssertReturn(cchSalt >= RT_SHACRYPT_SALT_MIN_LEN, VERR_BUFFER_UNDERFLOW);
+    AssertReturn(cchSalt <= RT_SHACRYPT_SALT_MAX_LEN, VERR_TOO_MUCH_DATA);
+    AssertReturn(cRounds >= RT_SHACRYPT_ROUNDS_MIN && cRounds <= RT_SHACRYPT_ROUNDS_MAX, VERR_OUT_OF_RANGE);
+
+    AssertPtrReturn(pszString, VERR_INVALID_POINTER);
+
+    /*
+     * Calc the necessary buffer space and check that the caller supplied enough.
+     */
+    char    szRounds[64];
+    ssize_t cchRounds = 0;
+    if (cRounds != RT_SHACRYPT_ROUNDS_DEFAULT)
+    {
+        cchRounds = RTStrFormatU32(szRounds, sizeof(szRounds), cRounds, 10, 0, 0, 0);
+        Assert(cchRounds > 0 && cchRounds <= 9);
+    }
+
+    size_t const cchNeeded = sizeof(TMPL_SHACRYPT_ID_STR) - 1
+                           + (cRounds != RT_SHACRYPT_ROUNDS_DEFAULT ? cchRounds + sizeof("rounds=$") - 1 : 0)
+                           + cchSalt + 1
+                           + TMPL_HASH_SIZE * 4 / 3
+                           + 1;
+    AssertReturn(cbString > cchNeeded, VERR_BUFFER_OVERFLOW);
+
+    /*
+     * Do the formatting.
+     */
+    memcpy(pszString, RT_STR_TUPLE(TMPL_SHACRYPT_ID_STR));
+    size_t off = sizeof(TMPL_SHACRYPT_ID_STR) - 1;
+
+    if (cRounds != RT_SHACRYPT_ROUNDS_DEFAULT)
+    {
+        memcpy(&pszString[off], RT_STR_TUPLE("rounds="));
+        off += sizeof("rounds=") - 1;
+
+        memcpy(&pszString[off], szRounds, cchRounds);
+        off += cchRounds;
+        pszString[off++] = '$';
+    }
+
+    memcpy(&pszString[off], pszSalt, cchSalt);
+    off += cchSalt;
+    pszString[off++] = '$';
+
+#if TMPL_HASH_BITS == 512
+    BASE64_ENCODE(pszString, off, pabHash[ 0], pabHash[21], pabHash[42], 4);
+    BASE64_ENCODE(pszString, off, pabHash[22], pabHash[43], pabHash[ 1], 4);
+    BASE64_ENCODE(pszString, off, pabHash[44], pabHash[ 2], pabHash[23], 4);
+    BASE64_ENCODE(pszString, off, pabHash[ 3], pabHash[24], pabHash[45], 4);
+    BASE64_ENCODE(pszString, off, pabHash[25], pabHash[46], pabHash[ 4], 4);
+    BASE64_ENCODE(pszString, off, pabHash[47], pabHash[ 5], pabHash[26], 4);
+    BASE64_ENCODE(pszString, off, pabHash[ 6], pabHash[27], pabHash[48], 4);
+    BASE64_ENCODE(pszString, off, pabHash[28], pabHash[49], pabHash[ 7], 4);
+    BASE64_ENCODE(pszString, off, pabHash[50], pabHash[ 8], pabHash[29], 4);
+    BASE64_ENCODE(pszString, off, pabHash[ 9], pabHash[30], pabHash[51], 4);
+    BASE64_ENCODE(pszString, off, pabHash[31], pabHash[52], pabHash[10], 4);
+    BASE64_ENCODE(pszString, off, pabHash[53], pabHash[11], pabHash[32], 4);
+    BASE64_ENCODE(pszString, off, pabHash[12], pabHash[33], pabHash[54], 4);
+    BASE64_ENCODE(pszString, off, pabHash[34], pabHash[55], pabHash[13], 4);
+    BASE64_ENCODE(pszString, off, pabHash[56], pabHash[14], pabHash[35], 4);
+    BASE64_ENCODE(pszString, off, pabHash[15], pabHash[36], pabHash[57], 4);
+    BASE64_ENCODE(pszString, off, pabHash[37], pabHash[58], pabHash[16], 4);
+    BASE64_ENCODE(pszString, off, pabHash[59], pabHash[17], pabHash[38], 4);
+    BASE64_ENCODE(pszString, off, pabHash[18], pabHash[39], pabHash[60], 4);
+    BASE64_ENCODE(pszString, off, pabHash[40], pabHash[61], pabHash[19], 4);
+    BASE64_ENCODE(pszString, off, pabHash[62], pabHash[20], pabHash[41], 4);
+    BASE64_ENCODE(pszString, off,           0,           0, pabHash[63], 2);
+
+#elif TMPL_HASH_BITS == 256
+    BASE64_ENCODE(pszString, off, pabHash[00], pabHash[10], pabHash[20], 4);
+    BASE64_ENCODE(pszString, off, pabHash[21], pabHash[ 1], pabHash[11], 4);
+    BASE64_ENCODE(pszString, off, pabHash[12], pabHash[22], pabHash[ 2], 4);
+    BASE64_ENCODE(pszString, off, pabHash[ 3], pabHash[13], pabHash[23], 4);
+    BASE64_ENCODE(pszString, off, pabHash[24], pabHash[ 4], pabHash[14], 4);
+    BASE64_ENCODE(pszString, off, pabHash[15], pabHash[25], pabHash[ 5], 4);
+    BASE64_ENCODE(pszString, off, pabHash[ 6], pabHash[16], pabHash[26], 4);
+    BASE64_ENCODE(pszString, off, pabHash[27], pabHash[ 7], pabHash[17], 4);
+    BASE64_ENCODE(pszString, off, pabHash[18], pabHash[28], pabHash[ 8], 4);
+    BASE64_ENCODE(pszString, off, pabHash[ 9], pabHash[19], pabHash[29], 4);
+    BASE64_ENCODE(pszString, off, 0,           pabHash[31], pabHash[30], 3);
+
+#else
+# error "TMPL_HASH_BITS"
+#endif
+
+    pszString[off] = '\0';
+    Assert(off < cbString);
+
+    return VINF_SUCCESS;
+}
+
+
+#undef TMPL_HASH_BITS
+#undef TMPL_HASH_SIZE
+#undef TMPL_HASH_CONTEXT_T
+#undef TmplHashInit
+#undef TmplHashUpdate
+#undef TmplHashFinal
+#undef TMPL_SHACRYPT_ID_STR
+#undef RTCrShaCryptTmpl
+#undef RTCrShaCryptTmplEx
+#undef RTCrShaCryptTmplToString
+
+
Index: trunk/src/VBox/Runtime/common/crypto/shacrypt.cpp
===================================================================
--- trunk/src/VBox/Runtime/common/crypto/shacrypt.cpp	(revision 102491)
+++ trunk/src/VBox/Runtime/common/crypto/shacrypt.cpp	(revision 102495)
@@ -128,6 +128,36 @@
 }
 
-#include "shacrypt-256.cpp.h"
-#include "shacrypt-512.cpp.h"
+
+/*
+ * The algorithm for the SHA-256 and SHA-512 encryption is identical, except for
+ * how the bytes are distributed in the final step.  So we use a pre-processor
+ * code template for the implementation.
+ */
+
+/* SHA-256*/
+#define TMPL_HASH_BITS              256
+#define TMPL_HASH_SIZE              RTSHA256_HASH_SIZE
+#define TMPL_HASH_CONTEXT_T         RTSHA256CONTEXT
+#define TmplHashInit                RTSha256Init
+#define TmplHashUpdate              RTSha256Update
+#define TmplHashFinal               RTSha256Final
+#define TMPL_SHACRYPT_ID_STR        RT_SHACRYPT_ID_STR_256
+#define RTCrShaCryptTmpl            RTCrShaCrypt256
+#define RTCrShaCryptTmplEx          RTCrShaCrypt256Ex
+#define RTCrShaCryptTmplToString    RTCrShaCrypt256ToString
+#include "shacrypt-tmpl.cpp.h"
+
+/* SHA-512*/
+#define TMPL_HASH_BITS              512
+#define TMPL_HASH_SIZE              RTSHA512_HASH_SIZE
+#define TMPL_HASH_CONTEXT_T         RTSHA512CONTEXT
+#define TmplHashInit                RTSha512Init
+#define TmplHashUpdate              RTSha512Update
+#define TmplHashFinal               RTSha512Final
+#define TMPL_SHACRYPT_ID_STR        RT_SHACRYPT_ID_STR_512
+#define RTCrShaCryptTmpl            RTCrShaCrypt512
+#define RTCrShaCryptTmplEx          RTCrShaCrypt512Ex
+#define RTCrShaCryptTmplToString    RTCrShaCrypt512ToString
+#include "shacrypt-tmpl.cpp.h"
 
 
