| 248 | /* ARGSUSED4 */ |
| 249 | extern "C" |
| 250 | char * |
| 251 | my_crypt_genhash(char *ctbuffer, |
| 252 | size_t ctbufflen, |
| 253 | const char *plaintext, |
| 254 | int plaintext_len, |
| 255 | const char *switchsalt, |
| 256 | const char **params) |
| 257 | { |
| 258 | int salt_len, i; |
| 259 | char *salt; |
| 260 | unsigned char A[DIGEST_LEN]; |
| 261 | unsigned char B[DIGEST_LEN]; |
| 262 | unsigned char DP[DIGEST_LEN]; |
| 263 | unsigned char DS[DIGEST_LEN]; |
| 264 | DIGEST_CTX ctxA, ctxB, ctxC, ctxDP, ctxDS; |
| 265 | int rounds = ROUNDS_DEFAULT; |
| 266 | int srounds = 0; |
| 267 | bool custom_rounds= false; |
| 268 | char *p; |
| 269 | char *P, *Pp; |
| 270 | char *S, *Sp; |
| 271 | |
| 272 | /* Refine the salt */ |
| 273 | salt = (char *)switchsalt; |
| 274 | |
| 275 | /* skip our magic string */ |
| 276 | if (strncmp((char *)salt, crypt_alg_magic, crypt_alg_magic_len) == 0) |
| 277 | { |
| 278 | salt += crypt_alg_magic_len + 1; |
| 279 | } |
| 280 | |
| 281 | srounds = getrounds(salt); |
| 282 | if (srounds != 0) { |
| 283 | rounds = MAX(ROUNDS_MIN, MIN(srounds, ROUNDS_MAX)); |
| 284 | custom_rounds= true; |
| 285 | p = strchr(salt, '$'); |
| 286 | if (p != NULL) |
| 287 | salt = p + 1; |
| 288 | } |
| 289 | |
| 290 | salt_len = MIN(strcspn(salt, "$"), CRYPT_SALT_LENGTH); |
| 291 | //plaintext_len = strlen(plaintext); |
| 292 | |
| 293 | /* 1. */ |
| 294 | DIGESTInit(&ctxA); |
| 295 | |
| 296 | /* 2. The password first, since that is what is most unknown */ |
| 297 | DIGESTUpdate(&ctxA, plaintext, plaintext_len); |
| 298 | |
| 299 | /* 3. Then the raw salt */ |
| 300 | DIGESTUpdate(&ctxA, salt, salt_len); |
| 301 | |
| 302 | /* 4. - 8. */ |
| 303 | DIGESTInit(&ctxB); |
| 304 | DIGESTUpdate(&ctxB, plaintext, plaintext_len); |
| 305 | DIGESTUpdate(&ctxB, salt, salt_len); |
| 306 | DIGESTUpdate(&ctxB, plaintext, plaintext_len); |
| 307 | DIGESTFinal(B, &ctxB); |
no test coverage detected