"Fossies" - the Fresh Open Source Software Archive

Member "cryptsetup-2.4.3/lib/utils_crypt.c" (13 Jan 2022, 4557 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 "utils_crypt.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 2.3.6_vs_2.4.0.

    1 /*
    2  * utils_crypt - cipher utilities for cryptsetup
    3  *
    4  * Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
    5  * Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved.
    6  * Copyright (C) 2009-2021 Milan Broz
    7  *
    8  * This program is free software; you can redistribute it and/or
    9  * modify it under the terms of the GNU General Public License
   10  * as published by the Free Software Foundation; either version 2
   11  * of the License, or (at your option) any later version.
   12  *
   13  * This program is distributed in the hope that it will be useful,
   14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16  * GNU General Public License for more details.
   17  *
   18  * You should have received a copy of the GNU General Public License
   19  * along with this program; if not, write to the Free Software
   20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   21  */
   22 
   23 #include <stdlib.h>
   24 #include <stdio.h>
   25 #include <string.h>
   26 #include <strings.h>
   27 #include <unistd.h>
   28 #include <ctype.h>
   29 #include <errno.h>
   30 
   31 #include "libcryptsetup.h"
   32 #include "utils_crypt.h"
   33 
   34 int crypt_parse_name_and_mode(const char *s, char *cipher, int *key_nums,
   35                   char *cipher_mode)
   36 {
   37     if (!s || !cipher || !cipher_mode)
   38         return -EINVAL;
   39 
   40     if (sscanf(s, "%" MAX_CIPHER_LEN_STR "[^-]-%" MAX_CIPHER_LEN_STR "s",
   41            cipher, cipher_mode) == 2) {
   42         if (!strcmp(cipher_mode, "plain"))
   43             strcpy(cipher_mode, "cbc-plain");
   44         if (key_nums) {
   45             char *tmp = strchr(cipher, ':');
   46             *key_nums = tmp ? atoi(++tmp) : 1;
   47             if (!*key_nums)
   48                 return -EINVAL;
   49         }
   50 
   51         return 0;
   52     }
   53 
   54     /* Short version for "empty" cipher */
   55     if (!strcmp(s, "null") || !strcmp(s, "cipher_null")) {
   56         strcpy(cipher, "cipher_null");
   57         strcpy(cipher_mode, "ecb");
   58         if (key_nums)
   59             *key_nums = 0;
   60         return 0;
   61     }
   62 
   63     if (sscanf(s, "%" MAX_CIPHER_LEN_STR "[^-]", cipher) == 1) {
   64         strcpy(cipher_mode, "cbc-plain");
   65         if (key_nums)
   66             *key_nums = 1;
   67         return 0;
   68     }
   69 
   70     return -EINVAL;
   71 }
   72 
   73 int crypt_parse_hash_integrity_mode(const char *s, char *integrity)
   74 {
   75     char mode[MAX_CIPHER_LEN], hash[MAX_CIPHER_LEN];
   76     int r;
   77 
   78     if (!s || !integrity || strchr(s, '(') || strchr(s, ')'))
   79         return -EINVAL;
   80 
   81     r = sscanf(s, "%" MAX_CIPHER_LEN_STR "[^-]-%" MAX_CIPHER_LEN_STR "s", mode, hash);
   82     if (r == 2 && !isdigit(hash[0]))
   83         r = snprintf(integrity, MAX_CIPHER_LEN, "%s(%s)", mode, hash);
   84     else if (r == 2)
   85         r = snprintf(integrity, MAX_CIPHER_LEN, "%s-%s", mode, hash);
   86     else if (r == 1)
   87         r = snprintf(integrity, MAX_CIPHER_LEN, "%s", mode);
   88     else
   89         return -EINVAL;
   90 
   91     if (r < 0 || r >= MAX_CIPHER_LEN)
   92         return -EINVAL;
   93 
   94     return 0;
   95 }
   96 
   97 int crypt_parse_integrity_mode(const char *s, char *integrity,
   98                    int *integrity_key_size)
   99 {
  100     int ks = 0, r = 0;
  101 
  102     if (!s || !integrity)
  103         return -EINVAL;
  104 
  105     /* AEAD modes */
  106     if (!strcmp(s, "aead") ||
  107         !strcmp(s, "poly1305") ||
  108         !strcmp(s, "none")) {
  109         strncpy(integrity, s, MAX_CIPHER_LEN);
  110         ks = 0;
  111     } else if (!strcmp(s, "hmac-sha1")) {
  112         strncpy(integrity, "hmac(sha1)", MAX_CIPHER_LEN);
  113         ks = 20;
  114     } else if (!strcmp(s, "hmac-sha256")) {
  115         strncpy(integrity, "hmac(sha256)", MAX_CIPHER_LEN);
  116         ks = 32;
  117     } else if (!strcmp(s, "hmac-sha512")) {
  118         ks = 64;
  119         strncpy(integrity, "hmac(sha512)", MAX_CIPHER_LEN);
  120     } else if (!strcmp(s, "cmac-aes")) {
  121         ks = 16;
  122         strncpy(integrity, "cmac(aes)", MAX_CIPHER_LEN);
  123     } else
  124         r = -EINVAL;
  125 
  126     if (integrity_key_size)
  127         *integrity_key_size = ks;
  128 
  129     return r;
  130 }
  131 
  132 int crypt_parse_pbkdf(const char *s, const char **pbkdf)
  133 {
  134     const char *tmp = NULL;
  135 
  136     if (!s)
  137         return -EINVAL;
  138 
  139     if (!strcasecmp(s, CRYPT_KDF_PBKDF2))
  140         tmp = CRYPT_KDF_PBKDF2;
  141     else if (!strcasecmp(s, CRYPT_KDF_ARGON2I))
  142         tmp = CRYPT_KDF_ARGON2I;
  143     else if (!strcasecmp(s, CRYPT_KDF_ARGON2ID))
  144         tmp = CRYPT_KDF_ARGON2ID;
  145 
  146     if (!tmp)
  147         return -EINVAL;
  148 
  149     if (pbkdf)
  150         *pbkdf = tmp;
  151 
  152     return 0;
  153 }
  154 
  155 ssize_t crypt_hex_to_bytes(const char *hex, char **result, int safe_alloc)
  156 {
  157     char buf[3] = "xx\0", *endp, *bytes;
  158     size_t i, len;
  159 
  160     len = strlen(hex);
  161     if (len % 2)
  162         return -EINVAL;
  163     len /= 2;
  164 
  165     bytes = safe_alloc ? crypt_safe_alloc(len) : malloc(len);
  166     if (!bytes)
  167         return -ENOMEM;
  168 
  169     for (i = 0; i < len; i++) {
  170         memcpy(buf, &hex[i * 2], 2);
  171         bytes[i] = strtoul(buf, &endp, 16);
  172         if (endp != &buf[2]) {
  173             safe_alloc ? crypt_safe_free(bytes) : free(bytes);
  174             return -EINVAL;
  175         }
  176     }
  177     *result = bytes;
  178     return i;
  179 }
  180 
  181 bool crypt_is_cipher_null(const char *cipher_spec)
  182 {
  183     if (!cipher_spec)
  184         return false;
  185     return (strstr(cipher_spec, "cipher_null") || !strcmp(cipher_spec, "null"));
  186 }