1 #include <stdlib.h>
2 #include <string.h>
3 #include <stdio.h>
4 #include <stdint.h>
5 #include <float.h>
6 #include <stdint.h>
7 #include <math.h>
8
9 #ifndef S_SPLINT_S /* Including this here triggers a known bug in splint */
10 #include <unistd.h>
11 #endif
12
13 #include "libscrypt.h"
14
15 /* ilog2 for powers of two */
scrypt_ilog2(uint32_t n)16 static uint32_t scrypt_ilog2(uint32_t n)
17 {
18 #ifndef S_SPLINT_S
19
20 /* Check for a valid power of two */
21 if (n < 2 || (n & (n - 1)))
22 return -1;
23 #endif
24 uint32_t t = 1;
25 while (((uint32_t)1 << t) < n)
26 {
27 if(t > SCRYPT_SAFE_N)
28 return (uint32_t) -1; /* Check for insanity */
29 t++;
30 }
31
32 return t;
33 }
34
35 #ifdef _MSC_VER
36 #define SNPRINTF _snprintf
37 #else
38 #define SNPRINTF snprintf
39 #endif
40
libscrypt_mcf(uint32_t N,uint32_t r,uint32_t p,const char * salt,const char * hash,char * mcf)41 int libscrypt_mcf(uint32_t N, uint32_t r, uint32_t p, const char *salt,
42 const char *hash, char *mcf)
43 {
44
45 uint32_t t, params;
46 int s;
47
48 if(!mcf || !hash)
49 return 0;
50 /* Although larger values of r, p are valid in scrypt, this mcf format
51 * limits to 8 bits. If your number is larger, current computers will
52 * struggle
53 */
54 if(r > (uint8_t)(-1) || p > (uint8_t)(-1))
55 return 0;
56
57 t = scrypt_ilog2(N);
58 if (t < 1)
59 return 0;
60
61 params = (r << 8) + p;
62 params += (uint32_t)t << 16;
63
64 /* Using snprintf - not checking for overflows. We've already
65 * determined that mcf should be defined as at least SCRYPT_MCF_LEN
66 * in length
67 */
68 s = SNPRINTF(mcf, SCRYPT_MCF_LEN, SCRYPT_MCF_ID "$%06x$%s$%s", (unsigned int)params, salt, hash);
69 if (s >= SCRYPT_MCF_LEN)
70 return 0;
71
72 return 1;
73 }
74