forked from besser82/libxcrypt
-
Notifications
You must be signed in to change notification settings - Fork 0
/
crypt-yescrypt.c
109 lines (100 loc) · 3.07 KB
/
crypt-yescrypt.c
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
/* Copyright (C) 2018 [email protected]
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "crypt-port.h"
#include "crypt-private.h"
#include "byteorder.h"
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "yescrypt.h"
#if INCLUDE_yescrypt
/*
* As OUTPUT is initialized with a failure token before gensalt_yescrypt_rn
* is called, in case of an error we could just set an appropriate errno
* and return.
* Since O_SIZE is guaranteed to be greater than 2, we may fill OUTPUT
* with a short failure token when need.
*/
void
gensalt_yescrypt_rn(unsigned long count,
const uint8_t *rbytes, size_t nrbytes,
uint8_t *output, size_t o_size)
{
/* Use one of recommended parameter sets as the 'low default'. */
yescrypt_params_t params = { .flags = YESCRYPT_DEFAULTS,
.N = 4096, .r = 32, .p = 1 };
if (count) {
/*
* `1 << (count - 1)` is MiB usage in range of 1MiB..1GiB,
* thus, count is in range of 1..11
*/
if (count <= 2) {
params.r = 8; /* N in 1KiB */
params.N = 512ULL << count;
} else if (count <= 11) {
params.r = 32; /* N in 4KiB */
params.N = 128ULL << count;
} else {
errno = EINVAL;
return;
}
}
if (!yescrypt_encode_params_r(¶ms, rbytes, nrbytes, output, o_size)) {
/*
* As the output could have already been written,
* overwrite it with a short failure token.
*/
output[0] = '*';
output[1] = '\0';
errno = ERANGE;
return;
}
}
void
crypt_yescrypt_rn(const char *phrase, size_t ARG_UNUSED (phr_size),
const char *setting, size_t ARG_UNUSED (set_size),
uint8_t *output, size_t o_size,
ARG_UNUSED(void *scratch), ARG_UNUSED(size_t s_size))
{
yescrypt_local_t local;
uint8_t *retval;
if (o_size < 3) {
errno = ERANGE;
return;
}
if (yescrypt_init_local(&local)) {
errno = ENOMEM;
return;
}
retval = yescrypt_r(NULL, &local,
(const uint8_t *)phrase, strlen(phrase),
(const uint8_t *)setting, NULL,
output, o_size);
if (yescrypt_free_local(&local) ||
!retval) {
/*
* As the output could have already been written,
* overwrite it with a failure token.
*/
output[0] = '*';
output[1] = '0';
output[2] = '\0';
errno = EINVAL;
}
}
#endif /* INCLUDE_yescrypt */