Changeset 102375 in vbox for trunk/src/VBox/Runtime
- Timestamp:
- Nov 29, 2023 10:58:18 AM (12 months ago)
- Location:
- trunk/src/VBox/Runtime
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/crypto/shacrypt.cpp
r102372 r102375 48 48 49 49 50 /** The digest prefix for SHAcrypt256 strings. */ 51 #define RT_SHACRYPT_DIGEST_PREFIX_256_STR "$5$" 52 /** The digest prefix for SHAcrypt512 strings. */ 53 #define RT_SHACRYPT_DIGEST_PREFIX_512_STR "$6$" 54 50 55 51 56 RTR3DECL(int) RTCrShaCryptGenerateSalt(char *pszSalt, size_t cchSalt) … … 63 68 64 69 70 /** 71 * Extracts the salt from a given string. 72 * 73 * @returns Pointer to the salt string, or NULL if not found / invalid. 74 * @param pszStr String to extract salt from. 75 * @param pcchSalt Where to reutrn the extracted salt length (in characters). 76 */ 77 static const char *rtCrShaCryptExtractSalt(const char *pszStr, size_t *pcchSalt) 78 { 79 size_t cchSalt = strlen(pszStr); 80 81 /* Searches for a known SHAcrypt string prefix and skips it. */ 82 #define BEGINS_WITH(a_szMatch) \ 83 (cchSalt >= sizeof(a_szMatch) - 1U && memcmp(pszStr, a_szMatch, sizeof(a_szMatch) - 1U) == 0) 84 if (BEGINS_WITH(RT_SHACRYPT_DIGEST_PREFIX_256_STR)) 85 { 86 cchSalt -= sizeof(RT_SHACRYPT_DIGEST_PREFIX_256_STR) - 1; 87 pszStr += sizeof(RT_SHACRYPT_DIGEST_PREFIX_256_STR) - 1; 88 } 89 else if (BEGINS_WITH(RT_SHACRYPT_DIGEST_PREFIX_512_STR)) 90 { 91 cchSalt -= sizeof(RT_SHACRYPT_DIGEST_PREFIX_512_STR) - 1; 92 pszStr += sizeof(RT_SHACRYPT_DIGEST_PREFIX_512_STR) - 1; 93 } 94 #undef BEGINS_WITH 95 96 /* Search for the end of the salt string, denoted by a '$'. */ 97 size_t cchLen = 0; 98 while ( cchLen < cchSalt 99 && pszStr[cchLen] != '$') 100 cchLen++; 101 102 AssertMsgReturn(cchLen >= RT_SHACRYPT_MIN_SALT_LEN && cchLen <= RT_SHACRYPT_MAX_SALT_LEN, ("len=%zu\n", cchLen), NULL); 103 *pcchSalt = cchLen; 104 105 return pszStr; 106 } 107 108 65 109 RTR3DECL(int) RTCrShaCrypt256(const char *pszKey, const char *pszSalt, uint32_t cRounds, uint8_t abHash[RTSHA256_HASH_SIZE]) 66 110 { … … 71 115 size_t const cchKey = strlen(pszKey); 72 116 AssertReturn(cchKey, VERR_INVALID_PARAMETER); 73 size_t const cchSalt = strlen(pszSalt); 74 AssertMsgReturn(cchSalt >= RT_SHACRYPT_MIN_SALT_LEN && cchSalt <= RT_SHACRYPT_MAX_SALT_LEN, ("len=%zu\n", cchSalt), 75 VERR_INVALID_PARAMETER); 117 118 size_t cchSalt; 119 pszSalt = rtCrShaCryptExtractSalt(pszSalt, &cchSalt); 120 AssertPtrReturn(pszSalt, VERR_INVALID_PARAMETER); 76 121 77 122 uint8_t abDigest[RTSHA256_HASH_SIZE]; … … 202 247 size_t cchPrefix; 203 248 if (cRounds == RT_SHACRYPT_DEFAULT_ROUNDS) 204 cchPrefix = RTStrPrintf2(psz, cchString, " $5$%s$", pszSalt);249 cchPrefix = RTStrPrintf2(psz, cchString, "%s%s$", RT_SHACRYPT_DIGEST_PREFIX_256_STR, pszSalt); 205 250 else 206 cchPrefix = RTStrPrintf2(psz, cchString, " $5$rounds=%RU32$%s$", cRounds, pszSalt);251 cchPrefix = RTStrPrintf2(psz, cchString, "%srounds=%RU32$%s$", RT_SHACRYPT_DIGEST_PREFIX_256_STR, cRounds, pszSalt); 207 252 AssertReturn(cchPrefix > 0, VERR_BUFFER_OVERFLOW); 208 253 AssertReturn(cch >= cchPrefix, VERR_BUFFER_OVERFLOW); … … 255 300 AssertReturn (cRounds, VERR_INVALID_PARAMETER); 256 301 257 size_t const cchKey 302 size_t const cchKey = strlen(pszKey); 258 303 AssertReturn(cchKey, VERR_INVALID_PARAMETER); 259 size_t const cchSalt = strlen(pszSalt); 260 AssertMsgReturn(cchSalt >= RT_SHACRYPT_MIN_SALT_LEN && cchSalt <= RT_SHACRYPT_MAX_SALT_LEN, ("len=%zu\n", cchSalt), 261 VERR_INVALID_PARAMETER); 304 305 size_t cchSalt; 306 pszSalt = rtCrShaCryptExtractSalt(pszSalt, &cchSalt); 307 AssertPtrReturn(pszSalt, VERR_INVALID_PARAMETER); 262 308 263 309 uint8_t abDigest[RTSHA512_HASH_SIZE]; … … 386 432 size_t cchPrefix; 387 433 if (cRounds == RT_SHACRYPT_DEFAULT_ROUNDS) 388 cchPrefix = RTStrPrintf2(psz, cchString, " $6$%s$", pszSalt);434 cchPrefix = RTStrPrintf2(psz, cchString, "%s%s$", RT_SHACRYPT_DIGEST_PREFIX_512_STR, pszSalt); 389 435 else 390 cchPrefix = RTStrPrintf2(psz, cchString, " $6$rounds=%RU32$%s$", cRounds, pszSalt);436 cchPrefix = RTStrPrintf2(psz, cchString, "%srounds=%RU32$%s$", RT_SHACRYPT_DIGEST_PREFIX_512_STR, cRounds, pszSalt); 391 437 AssertReturn(cchPrefix > 0, VERR_BUFFER_OVERFLOW); 392 438 AssertReturn(cch >= cchPrefix, VERR_BUFFER_OVERFLOW); -
trunk/src/VBox/Runtime/testcase/tstRTShaCrypt.cpp
r102360 r102375 247 247 if (RTStrCmp(szResult, g_aTests[i].pszResultStr)) 248 248 RTTestIFailed("#%u: Returns '%s', expected '%s'", i, szResult, g_aTests[i].pszResultStr); 249 250 /* Now do the same, but hand-in the result string as the salt. 251 * 252 * This approach is used by many *crypt implementations -- it allows feeding the user-provided password and the 253 * crypted password from "the password file" to the function. If it returns the same crypted password then the 254 * user-provided password must be the correct one. 255 */ 256 switch (enmType) 257 { 258 case TST_DIGESTTYPE_SHA256: 259 { 260 rc = RTCrShaCrypt256(g_aTests[i].pszPassword, g_aTests[i].pszResultStr, cRounds, abDigest); 261 if (RT_SUCCESS(rc)) 262 rc = RTCrShaCrypt256ToString(abDigest, pszSalt, cRounds, szResult, sizeof(szResult)); 263 break; 264 } 265 266 case TST_DIGESTTYPE_SHA512: 267 { 268 rc = RTCrShaCrypt512(g_aTests[i].pszPassword, g_aTests[i].pszResultStr, cRounds, abDigest); 269 if (RT_SUCCESS(rc)) 270 rc = RTCrShaCrypt512ToString(abDigest, pszSalt, cRounds, szResult, sizeof(szResult)); 271 break; 272 } 273 274 default: 275 AssertFailed(); 276 break; 277 } 278 279 if (RTStrCmp(szResult, g_aTests[i].pszResultStr)) 280 RTTestIFailed("#%u (result as hash): Returns '%s', expected '%s'", 281 i, szResult, g_aTests[i].pszResultStr); 249 282 } 250 283 }
Note:
See TracChangeset
for help on using the changeset viewer.