Imported Upstream version 2.6.1
[platform/upstream/cryptsetup.git] / lib / crypto_backend / cipher_generic.c
1 /*
2  * Linux kernel cipher generic utilities
3  *
4  * Copyright (C) 2018-2023 Red Hat, Inc. All rights reserved.
5  * Copyright (C) 2018-2023 Milan Broz
6  *
7  * This file is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This file is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this file; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21
22 #include <string.h>
23 #include <stdbool.h>
24 #include <errno.h>
25 #include "crypto_backend.h"
26
27 struct cipher_alg {
28         const char *name;
29         const char *mode;
30         int blocksize;
31         bool wrapped_key;
32 };
33
34 static const struct cipher_alg cipher_algs[] = {
35         { "cipher_null", NULL, 16, false },
36         { "aes",         NULL, 16, false },
37         { "serpent",     NULL, 16, false },
38         { "twofish",     NULL, 16, false },
39         { "anubis",      NULL, 16, false },
40         { "blowfish",    NULL,  8, false },
41         { "camellia",    NULL, 16, false },
42         { "cast5",       NULL,  8, false },
43         { "cast6",       NULL, 16, false },
44         { "des",         NULL,  8, false },
45         { "des3_ede",    NULL,  8, false },
46         { "khazad",      NULL,  8, false },
47         { "seed",        NULL, 16, false },
48         { "tea",         NULL,  8, false },
49         { "xtea",        NULL,  8, false },
50         { "paes",        NULL, 16,  true }, /* protected AES, s390 wrapped key scheme */
51         { "xchacha12,aes", "adiantum", 32, false },
52         { "xchacha20,aes", "adiantum", 32, false },
53         { "sm4",         NULL, 16, false },
54         { NULL,          NULL,  0, false }
55 };
56
57 static const struct cipher_alg *_get_alg(const char *name, const char *mode)
58 {
59         int i = 0;
60
61         while (name && cipher_algs[i].name) {
62                 if (!strcasecmp(name, cipher_algs[i].name))
63                         if (!mode || !cipher_algs[i].mode ||
64                             !strncasecmp(mode, cipher_algs[i].mode, strlen(cipher_algs[i].mode)))
65                                 return &cipher_algs[i];
66                 i++;
67         }
68         return NULL;
69 }
70
71 int crypt_cipher_ivsize(const char *name, const char *mode)
72 {
73         const struct cipher_alg *ca = _get_alg(name, mode);
74
75         if (!ca)
76                 return -EINVAL;
77
78         if (mode && !strcasecmp(mode, "ecb"))
79                 return 0;
80
81         return ca->blocksize;
82 }
83
84 int crypt_cipher_wrapped_key(const char *name, const char *mode)
85 {
86         const struct cipher_alg *ca = _get_alg(name, mode);
87
88         return ca ? (int)ca->wrapped_key : 0;
89 }