Imported Upstream version 2.3.3
[platform/upstream/cryptsetup.git] / lib / crypt_plain.c
index dc4fac3..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
@@ -19,7 +21,7 @@
  */
 
 #include <string.h>
-#include <stdlib.h>
+#include <stdio.h>
 #include <errno.h>
 
 #include "libcryptsetup.h"
@@ -62,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 __attribute__((unused)),
+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)
@@ -71,7 +73,7 @@ int crypt_plain_hash(struct crypt_device *ctx __attribute__((unused)),
        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;
@@ -81,9 +83,13 @@ int crypt_plain_hash(struct crypt_device *ctx __attribute__((unused)),
        /* 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;
                }
@@ -93,7 +99,16 @@ int crypt_plain_hash(struct crypt_device *ctx __attribute__((unused)),
                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);