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