0ddec59b16fbf35e60661cec1433264d5481c8eb
[platform/upstream/cryptsetup.git] / lib / crypto_backend / cipher_generic.c
1 /*
2  * Linux kernel cipher generic utilities
3  *
4  * Copyright (C) 2018-2020 Red Hat, Inc. All rights reserved.
5  * Copyright (C) 2018-2020 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 /* FIXME: Getting block size should be dynamic from cipher backend. */
35 static const struct cipher_alg cipher_algs[] = {
36         { "cipher_null", NULL, 16, false },
37         { "aes",         NULL, 16, false },
38         { "serpent",     NULL, 16, false },
39         { "twofish",     NULL, 16, false },
40         { "anubis",      NULL, 16, false },
41         { "blowfish",    NULL,  8, false },
42         { "camellia",    NULL, 16, false },
43         { "cast5",       NULL,  8, false },
44         { "cast6",       NULL, 16, false },
45         { "des",         NULL,  8, false },
46         { "des3_ede",    NULL,  8, false },
47         { "khazad",      NULL,  8, false },
48         { "seed",        NULL, 16, false },
49         { "tea",         NULL,  8, false },
50         { "xtea",        NULL,  8, false },
51         { "paes",        NULL, 16,  true }, /* protected AES, s390 wrapped key scheme */
52         { "xchacha12,aes", "adiantum", 32, false },
53         { "xchacha20,aes", "adiantum", 32, false },
54         { "sm4",         NULL, 16, false },
55         { NULL,          NULL,  0, false }
56 };
57
58 static const struct cipher_alg *_get_alg(const char *name, const char *mode)
59 {
60         int i = 0;
61
62         while (name && cipher_algs[i].name) {
63                 if (!strcasecmp(name, cipher_algs[i].name))
64                         if (!mode || !cipher_algs[i].mode ||
65                             !strncasecmp(mode, cipher_algs[i].mode, strlen(cipher_algs[i].mode)))
66                                 return &cipher_algs[i];
67                 i++;
68         }
69         return NULL;
70 }
71
72 int crypt_cipher_ivsize(const char *name, const char *mode)
73 {
74         const struct cipher_alg *ca = _get_alg(name, mode);
75
76         if (!ca)
77                 return -EINVAL;
78
79         if (mode && !strcasecmp(mode, "ecb"))
80                 return 0;
81
82         return ca->blocksize;
83 }
84
85 int crypt_cipher_wrapped_key(const char *name, const char *mode)
86 {
87         const struct cipher_alg *ca = _get_alg(name, mode);
88
89         return ca ? (int)ca->wrapped_key : 0;
90 }