blob: 8f5fadb582ed89e2d16e41f0f9af28caa47305f0 [file] [log] [blame]
Steffen Jaeckel26dd9932021-07-08 15:57:33 +02001// SPDX-License-Identifier: GPL-2.0+
2/* Copyright (C) 2020 Steffen Jaeckel <jaeckel-floss@eyet-services.de> */
3
Steffen Jaeckel26dd9932021-07-08 15:57:33 +02004#include <crypt.h>
5#include "crypt-port.h"
6
Steffen Jaeckel29bbe712021-07-08 15:57:34 +02007typedef int (*crypt_fn)(const char *, size_t, const char *, size_t, uint8_t *,
8 size_t, void *, size_t);
Steffen Jaeckel26dd9932021-07-08 15:57:33 +02009
10const unsigned char ascii64[65] =
11 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
12
13static void equals_constant_time(const void *a_, const void *b_, size_t len,
14 int *equal)
15{
16 u8 ret = 0;
17 const u8 *a = a_, *b = b_;
18 int i;
19
20 for (i = 0; i < len; i++)
21 ret |= a[i] ^ b[i];
22
23 ret |= ret >> 4;
24 ret |= ret >> 2;
25 ret |= ret >> 1;
26 ret &= 1;
27
28 *equal = ret ^ 1;
29}
30
Steffen Jaeckel29bbe712021-07-08 15:57:34 +020031int crypt_compare(const char *should, const char *passphrase, int *equal)
Steffen Jaeckel26dd9932021-07-08 15:57:33 +020032{
33 u8 output[CRYPT_OUTPUT_SIZE], scratch[ALG_SPECIFIC_SIZE];
34 size_t n;
Steffen Jaeckel29bbe712021-07-08 15:57:34 +020035 int err;
Steffen Jaeckel26dd9932021-07-08 15:57:33 +020036 struct {
37 const char *prefix;
38 crypt_fn crypt;
39 } crypt_algos[] = {
40#if defined(CONFIG_CRYPT_PW_SHA256)
Steffen Jaeckel29bbe712021-07-08 15:57:34 +020041 { "$5$", crypt_sha256crypt_rn_wrapped },
Steffen Jaeckel26dd9932021-07-08 15:57:33 +020042#endif
43#if defined(CONFIG_CRYPT_PW_SHA512)
Steffen Jaeckel29bbe712021-07-08 15:57:34 +020044 { "$6$", crypt_sha512crypt_rn_wrapped },
Steffen Jaeckel26dd9932021-07-08 15:57:33 +020045#endif
46 { NULL, NULL }
47 };
48
49 *equal = 0;
50
51 for (n = 0; n < ARRAY_SIZE(crypt_algos); ++n) {
52 if (!crypt_algos[n].prefix)
53 continue;
54 if (strncmp(should, crypt_algos[n].prefix, 3) == 0)
55 break;
56 }
57
58 if (n >= ARRAY_SIZE(crypt_algos))
Steffen Jaeckel29bbe712021-07-08 15:57:34 +020059 return -EINVAL;
Steffen Jaeckel26dd9932021-07-08 15:57:33 +020060
Steffen Jaeckel29bbe712021-07-08 15:57:34 +020061 err = crypt_algos[n].crypt(passphrase, strlen(passphrase), should, 0,
62 output, sizeof(output), scratch,
63 sizeof(scratch));
Steffen Jaeckel26dd9932021-07-08 15:57:33 +020064 /* early return on error, nothing really happened inside the crypt() function */
Steffen Jaeckel29bbe712021-07-08 15:57:34 +020065 if (err)
66 return err;
Steffen Jaeckel26dd9932021-07-08 15:57:33 +020067
68 equals_constant_time(should, output, strlen((const char *)output),
69 equal);
70
71 memset(scratch, 0, sizeof(scratch));
72 memset(output, 0, sizeof(output));
Steffen Jaeckel29bbe712021-07-08 15:57:34 +020073
74 return 0;
Steffen Jaeckel26dd9932021-07-08 15:57:33 +020075}