"Fossies" - the Fresh Open Source Software Archive

Member "cryptsetup-2.4.3/lib/crypt_plain.c" (13 Jan 2022, 3059 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 "crypt_plain.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * cryptsetup plain device helper functions
    3  *
    4  * Copyright (C) 2004 Jana Saout <jana@saout.de>
    5  * Copyright (C) 2010-2021 Red Hat, Inc. All rights reserved.
    6  * Copyright (C) 2010-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 <string.h>
   24 #include <stdio.h>
   25 #include <errno.h>
   26 
   27 #include "libcryptsetup.h"
   28 #include "internal.h"
   29 
   30 static int hash(const char *hash_name, size_t key_size, char *key,
   31         size_t passphrase_size, const char *passphrase)
   32 {
   33     struct crypt_hash *md = NULL;
   34     size_t len;
   35     int round, i, r = 0;
   36 
   37     if (crypt_hash_init(&md, hash_name))
   38         return -ENOENT;
   39 
   40     len = crypt_hash_size(hash_name);
   41 
   42     for(round = 0; key_size && !r; round++) {
   43         /* hack from hashalot to avoid null bytes in key */
   44         for(i = 0; i < round; i++)
   45             if (crypt_hash_write(md, "A", 1))
   46                 r = 1;
   47 
   48         if (crypt_hash_write(md, passphrase, passphrase_size))
   49             r = 1;
   50 
   51         if (len > key_size)
   52             len = key_size;
   53 
   54         if (crypt_hash_final(md, key, len))
   55             r = 1;
   56 
   57         key += len;
   58         key_size -= len;
   59     }
   60 
   61     crypt_hash_destroy(md);
   62     return r;
   63 }
   64 
   65 #define PLAIN_HASH_LEN_MAX 256
   66 
   67 int crypt_plain_hash(struct crypt_device *cd,
   68              const char *hash_name,
   69              char *key, size_t key_size,
   70              const char *passphrase, size_t passphrase_size)
   71 {
   72     char hash_name_buf[PLAIN_HASH_LEN_MAX], *s;
   73     size_t hash_size, pad_size;
   74     int r;
   75 
   76     log_dbg(cd, "Plain: hashing passphrase using %s.", hash_name);
   77 
   78     if (strlen(hash_name) >= PLAIN_HASH_LEN_MAX)
   79         return -EINVAL;
   80     strncpy(hash_name_buf, hash_name, PLAIN_HASH_LEN_MAX);
   81     hash_name_buf[PLAIN_HASH_LEN_MAX - 1] = '\0';
   82 
   83     /* hash[:hash_length] */
   84     if ((s = strchr(hash_name_buf, ':'))) {
   85         *s = '\0';
   86         s++;
   87         if (!*s || sscanf(s, "%zd", &hash_size) != 1) {
   88             log_dbg(cd, "Hash length is not a number");
   89             return -EINVAL;
   90         }
   91         if (hash_size > key_size) {
   92             log_dbg(cd, "Hash length %zd > key length %zd",
   93                 hash_size, key_size);
   94             return -EINVAL;
   95         }
   96         pad_size = key_size - hash_size;
   97     } else {
   98         hash_size = key_size;
   99         pad_size = 0;
  100     }
  101 
  102     /* No hash, copy passphrase directly */
  103     if (!strcmp(hash_name_buf, "plain")) {
  104         if (passphrase_size < hash_size) {
  105             log_dbg(cd, "Too short plain passphrase.");
  106             return -EINVAL;
  107         }
  108         memcpy(key, passphrase, hash_size);
  109         r = 0;
  110     } else
  111         r = hash(hash_name_buf, hash_size, key, passphrase_size, passphrase);
  112 
  113     if (r == 0 && pad_size)
  114         memset(key + hash_size, 0, pad_size);
  115 
  116     return r;
  117 }