Imported Upstream version 2.3.3
[platform/upstream/cryptsetup.git] / lib / crypt_plain.c
index 8c13192..77d72fc 100644 (file)
@@ -1,12 +1,14 @@
 /*
  * cryptsetup plain device helper functions
  *
- * Copyright (C) 2004 Christophe Saout <christophe@saout.de>
- * Copyright (C) 2010-2011 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004 Jana Saout <jana@saout.de>
+ * Copyright (C) 2010-2020 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2010-2020 Milan Broz
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
 #include <string.h>
-#include <stdlib.h>
+#include <stdio.h>
 #include <errno.h>
 
+#include "libcryptsetup.h"
 #include "internal.h"
-#include "crypto_backend.h"
 
 static int hash(const char *hash_name, size_t key_size, char *key,
                size_t passphrase_size, const char *passphrase)
@@ -54,8 +56,6 @@ static int hash(const char *hash_name, size_t key_size, char *key,
 
                key += len;
                key_size -= len;
-               if (key_size && crypt_hash_restart(md))
-                       r = 1;
        }
 
        crypt_hash_destroy(md);
@@ -64,7 +64,7 @@ static int hash(const char *hash_name, size_t key_size, char *key,
 
 #define PLAIN_HASH_LEN_MAX 256
 
-int crypt_plain_hash(struct crypt_device *ctx,
+int crypt_plain_hash(struct crypt_device *cd,
                     const char *hash_name,
                     char *key, size_t key_size,
                     const char *passphrase, size_t passphrase_size)
@@ -73,7 +73,7 @@ int crypt_plain_hash(struct crypt_device *ctx,
        size_t hash_size, pad_size;
        int r;
 
-       log_dbg("Plain: hashing passphrase using %s.", hash_name);
+       log_dbg(cd, "Plain: hashing passphrase using %s.", hash_name);
 
        if (strlen(hash_name) >= PLAIN_HASH_LEN_MAX)
                return -EINVAL;
@@ -83,9 +83,13 @@ int crypt_plain_hash(struct crypt_device *ctx,
        /* hash[:hash_length] */
        if ((s = strchr(hash_name_buf, ':'))) {
                *s = '\0';
-               hash_size = atoi(++s);
+               s++;
+               if (!*s || sscanf(s, "%zd", &hash_size) != 1) {
+                       log_dbg(cd, "Hash length is not a number");
+                       return -EINVAL;
+               }
                if (hash_size > key_size) {
-                       log_dbg("Hash length %zd > key length %zd",
+                       log_dbg(cd, "Hash length %zd > key length %zd",
                                hash_size, key_size);
                        return -EINVAL;
                }
@@ -95,7 +99,16 @@ int crypt_plain_hash(struct crypt_device *ctx,
                pad_size = 0;
        }
 
-       r = hash(hash_name_buf, hash_size, key, passphrase_size, passphrase);
+       /* No hash, copy passphrase directly */
+       if (!strcmp(hash_name_buf, "plain")) {
+               if (passphrase_size < hash_size) {
+                       log_dbg(cd, "Too short plain passphrase.");
+                       return -EINVAL;
+               }
+               memcpy(key, passphrase, hash_size);
+               r = 0;
+       } else
+               r = hash(hash_name_buf, hash_size, key, passphrase_size, passphrase);
 
        if (r == 0 && pad_size)
                memset(key + hash_size, 0, pad_size);