"Fossies" - the Fresh Open Source Software Archive

Member "cryptsetup-2.4.3/lib/crypto_backend/crypto_kernel.c" (13 Jan 2022, 9161 Bytes) of package /linux/misc/cryptsetup-2.4.3.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "crypto_kernel.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 2.4.0_vs_2.4.1.

    1 /*
    2  * Linux kernel userspace API crypto backend implementation
    3  *
    4  * Copyright (C) 2010-2021 Red Hat, Inc. All rights reserved.
    5  * Copyright (C) 2010-2021 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 <stdlib.h>
   24 #include <stdio.h>
   25 #include <errno.h>
   26 #include <unistd.h>
   27 #include <sys/socket.h>
   28 #include <sys/utsname.h>
   29 #include <linux/if_alg.h>
   30 #include "crypto_backend_internal.h"
   31 
   32 #ifndef AF_ALG
   33 #define AF_ALG 38
   34 #endif
   35 #ifndef SOL_ALG
   36 #define SOL_ALG 279
   37 #endif
   38 
   39 static int crypto_backend_initialised = 0;
   40 static char version[256];
   41 
   42 struct hash_alg {
   43     const char *name;
   44     const char *kernel_name;
   45     int length;
   46     unsigned int block_length;
   47 };
   48 
   49 static struct hash_alg hash_algs[] = {
   50     { "sha1",      "sha1",        20,  64 },
   51     { "sha224",    "sha224",      28,  64 },
   52     { "sha256",    "sha256",      32,  64 },
   53     { "sha384",    "sha384",      48, 128 },
   54     { "sha512",    "sha512",      64, 128 },
   55     { "ripemd160", "rmd160",      20,  64 },
   56     { "whirlpool", "wp512",       64,  64 },
   57     { "sha3-224",  "sha3-224",    28, 144 },
   58     { "sha3-256",  "sha3-256",    32, 136 },
   59     { "sha3-384",  "sha3-384",    48, 104 },
   60     { "sha3-512",  "sha3-512",    64,  72 },
   61     { "stribog256","streebog256", 32,  64 },
   62     { "stribog512","streebog512", 64,  64 },
   63     { "sm3",       "sm3",         32,  64 },
   64     { "blake2b-160","blake2b-160",20, 128 },
   65     { "blake2b-256","blake2b-256",32, 128 },
   66     { "blake2b-384","blake2b-384",48, 128 },
   67     { "blake2b-512","blake2b-512",64, 128 },
   68     { "blake2s-128","blake2s-128",16,  64 },
   69     { "blake2s-160","blake2s-160",20,  64 },
   70     { "blake2s-224","blake2s-224",28,  64 },
   71     { "blake2s-256","blake2s-256",32,  64 },
   72     { NULL,        NULL,           0,   0 }
   73 };
   74 
   75 struct crypt_hash {
   76     int tfmfd;
   77     int opfd;
   78     int hash_len;
   79 };
   80 
   81 struct crypt_hmac {
   82     int tfmfd;
   83     int opfd;
   84     int hash_len;
   85 };
   86 
   87 struct crypt_cipher {
   88     struct crypt_cipher_kernel ck;
   89 };
   90 
   91 static int crypt_kernel_socket_init(struct sockaddr_alg *sa, int *tfmfd, int *opfd,
   92                     const void *key, size_t key_length)
   93 {
   94     *tfmfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
   95     if (*tfmfd < 0)
   96         return -ENOTSUP;
   97 
   98     if (bind(*tfmfd, (struct sockaddr *)sa, sizeof(*sa)) < 0) {
   99         close(*tfmfd);
  100         *tfmfd = -1;
  101         return -ENOENT;
  102     }
  103 
  104     if (key && setsockopt(*tfmfd, SOL_ALG, ALG_SET_KEY, key, key_length) < 0) {
  105         close(*tfmfd);
  106         *tfmfd = -1;
  107         return -EINVAL;
  108     }
  109 
  110     *opfd = accept(*tfmfd, NULL, 0);
  111     if (*opfd < 0) {
  112         close(*tfmfd);
  113         *tfmfd = -1;
  114         return -EINVAL;
  115     }
  116 
  117     return 0;
  118 }
  119 
  120 int crypt_backend_init(bool fips __attribute__((unused)))
  121 {
  122     struct utsname uts;
  123     struct sockaddr_alg sa = {
  124         .salg_family = AF_ALG,
  125         .salg_type = "hash",
  126         .salg_name = "sha256",
  127     };
  128     int r, tfmfd = -1, opfd = -1;
  129 
  130     if (crypto_backend_initialised)
  131         return 0;
  132 
  133     if (uname(&uts) == -1 || strcmp(uts.sysname, "Linux"))
  134         return -EINVAL;
  135 
  136     r = snprintf(version, sizeof(version), "%s %s kernel cryptoAPI",
  137         uts.sysname, uts.release);
  138     if (r < 0 || (size_t)r >= sizeof(version))
  139         return -EINVAL;
  140 
  141     if (crypt_kernel_socket_init(&sa, &tfmfd, &opfd, NULL, 0) < 0)
  142         return -EINVAL;
  143 
  144     close(tfmfd);
  145     close(opfd);
  146 
  147     crypto_backend_initialised = 1;
  148     return 0;
  149 }
  150 
  151 void crypt_backend_destroy(void)
  152 {
  153     crypto_backend_initialised = 0;
  154 }
  155 
  156 uint32_t crypt_backend_flags(void)
  157 {
  158     return CRYPT_BACKEND_KERNEL;
  159 }
  160 
  161 const char *crypt_backend_version(void)
  162 {
  163     return crypto_backend_initialised ? version : "";
  164 }
  165 
  166 static struct hash_alg *_get_alg(const char *name)
  167 {
  168     int i = 0;
  169 
  170     while (name && hash_algs[i].name) {
  171         if (!strcmp(name, hash_algs[i].name))
  172             return &hash_algs[i];
  173         i++;
  174     }
  175     return NULL;
  176 }
  177 
  178 /* HASH */
  179 int crypt_hash_size(const char *name)
  180 {
  181     struct hash_alg *ha = _get_alg(name);
  182 
  183     return ha ? ha->length : -EINVAL;
  184 }
  185 
  186 int crypt_hash_init(struct crypt_hash **ctx, const char *name)
  187 {
  188     struct crypt_hash *h;
  189     struct hash_alg *ha;
  190     struct sockaddr_alg sa = {
  191         .salg_family = AF_ALG,
  192         .salg_type = "hash",
  193     };
  194 
  195     h = malloc(sizeof(*h));
  196     if (!h)
  197         return -ENOMEM;
  198 
  199     ha = _get_alg(name);
  200     if (!ha) {
  201         free(h);
  202         return -EINVAL;
  203     }
  204     h->hash_len = ha->length;
  205 
  206     strncpy((char *)sa.salg_name, ha->kernel_name, sizeof(sa.salg_name)-1);
  207 
  208     if (crypt_kernel_socket_init(&sa, &h->tfmfd, &h->opfd, NULL, 0) < 0) {
  209         free(h);
  210         return -EINVAL;
  211     }
  212 
  213     *ctx = h;
  214     return 0;
  215 }
  216 
  217 int crypt_hash_write(struct crypt_hash *ctx, const char *buffer, size_t length)
  218 {
  219     ssize_t r;
  220 
  221     r = send(ctx->opfd, buffer, length, MSG_MORE);
  222     if (r < 0 || (size_t)r < length)
  223         return -EIO;
  224 
  225     return 0;
  226 }
  227 
  228 int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length)
  229 {
  230     ssize_t r;
  231 
  232     if (length > (size_t)ctx->hash_len)
  233         return -EINVAL;
  234 
  235     r = read(ctx->opfd, buffer, length);
  236     if (r < 0)
  237         return -EIO;
  238 
  239     return 0;
  240 }
  241 
  242 void crypt_hash_destroy(struct crypt_hash *ctx)
  243 {
  244     if (ctx->tfmfd >= 0)
  245         close(ctx->tfmfd);
  246     if (ctx->opfd >= 0)
  247         close(ctx->opfd);
  248     memset(ctx, 0, sizeof(*ctx));
  249     free(ctx);
  250 }
  251 
  252 /* HMAC */
  253 int crypt_hmac_size(const char *name)
  254 {
  255     return crypt_hash_size(name);
  256 }
  257 
  258 int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
  259             const void *key, size_t key_length)
  260 {
  261     struct crypt_hmac *h;
  262     struct hash_alg *ha;
  263     struct sockaddr_alg sa = {
  264         .salg_family = AF_ALG,
  265         .salg_type = "hash",
  266     };
  267     int r;
  268 
  269     h = malloc(sizeof(*h));
  270     if (!h)
  271         return -ENOMEM;
  272 
  273     ha = _get_alg(name);
  274     if (!ha) {
  275         free(h);
  276         return -EINVAL;
  277     }
  278     h->hash_len = ha->length;
  279 
  280     r = snprintf((char *)sa.salg_name, sizeof(sa.salg_name),
  281          "hmac(%s)", ha->kernel_name);
  282     if (r < 0 || (size_t)r >= sizeof(sa.salg_name)) {
  283         free(h);
  284         return -EINVAL;
  285     }
  286 
  287     if (crypt_kernel_socket_init(&sa, &h->tfmfd, &h->opfd, key, key_length) < 0) {
  288         free(h);
  289         return -EINVAL;
  290     }
  291 
  292     *ctx = h;
  293     return 0;
  294 }
  295 
  296 int crypt_hmac_write(struct crypt_hmac *ctx, const char *buffer, size_t length)
  297 {
  298     ssize_t r;
  299 
  300     r = send(ctx->opfd, buffer, length, MSG_MORE);
  301     if (r < 0 || (size_t)r < length)
  302         return -EIO;
  303 
  304     return 0;
  305 }
  306 
  307 int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
  308 {
  309     ssize_t r;
  310 
  311     if (length > (size_t)ctx->hash_len)
  312         return -EINVAL;
  313 
  314     r = read(ctx->opfd, buffer, length);
  315     if (r < 0)
  316         return -EIO;
  317 
  318     return 0;
  319 }
  320 
  321 void crypt_hmac_destroy(struct crypt_hmac *ctx)
  322 {
  323     if (ctx->tfmfd >= 0)
  324         close(ctx->tfmfd);
  325     if (ctx->opfd >= 0)
  326         close(ctx->opfd);
  327     memset(ctx, 0, sizeof(*ctx));
  328     free(ctx);
  329 }
  330 
  331 /* RNG - N/A */
  332 int crypt_backend_rng(char *buffer __attribute__((unused)), size_t length __attribute__((unused)),
  333     int quality __attribute__((unused)), int fips __attribute__((unused)))
  334 {
  335     return -EINVAL;
  336 }
  337 
  338 /* PBKDF */
  339 int crypt_pbkdf(const char *kdf, const char *hash,
  340         const char *password, size_t password_length,
  341         const char *salt, size_t salt_length,
  342         char *key, size_t key_length,
  343         uint32_t iterations, uint32_t memory, uint32_t parallel)
  344 {
  345     struct hash_alg *ha;
  346 
  347     if (!kdf)
  348         return -EINVAL;
  349 
  350     if (!strcmp(kdf, "pbkdf2")) {
  351         ha = _get_alg(hash);
  352         if (!ha)
  353             return -EINVAL;
  354 
  355         return pkcs5_pbkdf2(hash, password, password_length, salt, salt_length,
  356                     iterations, key_length, key, ha->block_length);
  357     } else if (!strncmp(kdf, "argon2", 6)) {
  358         return argon2(kdf, password, password_length, salt, salt_length,
  359                   key, key_length, iterations, memory, parallel);
  360     }
  361 
  362     return -EINVAL;
  363 }
  364 
  365 /* Block ciphers */
  366 int crypt_cipher_init(struct crypt_cipher **ctx, const char *name,
  367             const char *mode, const void *key, size_t key_length)
  368 {
  369     struct crypt_cipher *h;
  370     int r;
  371 
  372     h = malloc(sizeof(*h));
  373     if (!h)
  374         return -ENOMEM;
  375 
  376     r = crypt_cipher_init_kernel(&h->ck, name, mode, key, key_length);
  377     if (r < 0) {
  378         free(h);
  379         return r;
  380     }
  381 
  382     *ctx = h;
  383     return 0;
  384 }
  385 
  386 void crypt_cipher_destroy(struct crypt_cipher *ctx)
  387 {
  388     crypt_cipher_destroy_kernel(&ctx->ck);
  389     free(ctx);
  390 }
  391 
  392 int crypt_cipher_encrypt(struct crypt_cipher *ctx,
  393              const char *in, char *out, size_t length,
  394              const char *iv, size_t iv_length)
  395 {
  396     return crypt_cipher_encrypt_kernel(&ctx->ck, in, out, length, iv, iv_length);
  397 }
  398 
  399 int crypt_cipher_decrypt(struct crypt_cipher *ctx,
  400              const char *in, char *out, size_t length,
  401              const char *iv, size_t iv_length)
  402 {
  403     return crypt_cipher_decrypt_kernel(&ctx->ck, in, out, length, iv, iv_length);
  404 }
  405 
  406 bool crypt_cipher_kernel_only(struct crypt_cipher *ctx __attribute__((unused)))
  407 {
  408     return true;
  409 }
  410 
  411 int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
  412                 const char *in, char *out, size_t length,
  413                 const char *iv, size_t iv_length,
  414                 const char *tag, size_t tag_length)
  415 {
  416     return crypt_bitlk_decrypt_key_kernel(key, key_length, in, out, length,
  417                           iv, iv_length, tag, tag_length);
  418 }