aboutsummaryrefslogtreecommitdiffstats
path: root/librecrypt_settings_prefix.c
blob: 7568bb352643392a2567a1ac0f5c0dbb0612201f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/* See LICENSE file for copyright and license details. */
#include "common.h"
#ifndef TEST


size_t
librecrypt_settings_prefix(const char *hash, size_t *hashsize_out)
{
	size_t i, len, ret = 0u;
	size_t last_offset = 0u;
	const struct algorithm *algo;
	uintmax_t hashsize;

	/* Find last algorithm, and beginning of result */
	for (i = 0u; hash[i]; i++) {
		if (hash[i] == LIBRECRYPT_HASH_COMPOSITION_DELIMITER)
			ret = i + 1u;
		else if (hash[i] == LIBRECRYPT_ALGORITHM_LINK_DELIMITER)
			last_offset = ret = i + 1u;
	}
	/* and get `strlen(hash)` */
	len = i;

	/* TODO "_" is a prefix that is being used */

	/* Return if hash size is not required */
	if (!hashsize_out)
		goto out;
	/* Return 0 as hash size if default is specified */
	if (ret == i)
		goto zero;
	/* Return 0 as hash size if algorithm cannot be identified or has fixed hash size */
	algo = librecrypt_find_first_algorithm_(&hash[last_offset], len - last_offset);
	if (!algo || !algo->flexible_hash_size)
		goto zero;

	/* Get the hash size */
	if (!librecrypt_check_settings_(&hash[ret], len - ret, "%^b",
	                                &hashsize, (uintmax_t)1u, (uintmax_t)SIZE_MAX,
	                                algo->decoding_lut, algo->pad, algo->strict_pad))
		goto zero;

	*hashsize_out = (size_t)hashsize;
	goto out;

zero:
	*hashsize_out = 0u;
out:
	return ret;
}


#else


#define CHECK_NULL(PREFIX, SUFFIX)\
	do {\
		EXPECT(librecrypt_settings_prefix(PREFIX SUFFIX, NULL) == sizeof(PREFIX) - 1u);\
		EXPECT(librecrypt_settings_prefix(PREFIX, NULL) == sizeof(PREFIX) - 1u); \
	} while (0)

#if 0
#define CHECK_ASTERISK(PREFIX, SUFFIX, HASH)\
	do {\
		size_t hashsize = 99999u;\
		EXPECT(librecrypt_settings_prefix(PREFIX SUFFIX #HASH, &hashsize) == sizeof(PREFIX) - 1u);\
		EXPECT(hashsize == HASH##u);\
	} while (0)

#define CHECK_ZERO(PREFIX, SUFFIX)\
	do {\
		size_t hashsize = 99999u;\
		EXPECT(librecrypt_settings_prefix(PREFIX SUFFIX, &hashsize) == sizeof(PREFIX) - 1u);\
		EXPECT(hashsize == 0u);\
	} while (0)

#define CHECK_HASHED(PREFIX, SUFFIX, HASH)\
	do {\
		size_t hashsize = 99999u;\
		EXPECT(librecrypt_settings_prefix(PREFIX SUFFIX, &hashsize) == sizeof(PREFIX) - 1u);\
		EXPECT(hashsize == HASH##u);\
	} while (0)
#endif


int
main(void)
{
	SET_UP_ALARM();

	/* Simple cases */
	CHECK_NULL("", "result");
	CHECK_NULL(">", "double-des result");
	CHECK_NULL("$", "x");
	CHECK_NULL("y$", "x");
	CHECK_NULL("y>", "x");
	CHECK_NULL("a$b$c>d$e$", "x");
	CHECK_NULL("a$b$c>", "x");

	/* Discard asterisk-notation */
	CHECK_NULL("", "*10");
	CHECK_NULL(">", "*11");
	CHECK_NULL("$", "*12");
	CHECK_NULL("y$", "*13");
	CHECK_NULL("y>", "*012");
	CHECK_NULL("a$b$c>d$e$", "*1");
	CHECK_NULL("a$b$c>", "*2");
	CHECK_NULL("a$b$c>*10$", "*2");

	/* TODO test hash size output (requires algorithms) */

	return 0;
}


#endif