[v2,12/13] qcrypto-luks: use g_autowipe
diff mbox series

Message ID 20190826135103.22410-13-mlevitsk@redhat.com
State New
Headers show
Series
  • RFC crypto/luks: preparation for encryption key managment
Related show

Commit Message

Maxim Levitsky Aug. 26, 2019, 1:51 p.m. UTC
This patch makes the luks crypto driver use the g_autowipe to erase the master keys,
and the passwords from the memory.

Note that this is not a complete solution, since these keys are also present in the
chipers, and in the secrets.

Some of them still can be erased, at least at driver instance close.

Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
---
 crypto/block-luks.c | 61 ++++++++++++++++-----------------------------
 1 file changed, 22 insertions(+), 39 deletions(-)

Patch
diff mbox series

diff --git a/crypto/block-luks.c b/crypto/block-luks.c
index 6a43d97ce5..db0fb764b4 100644
--- a/crypto/block-luks.c
+++ b/crypto/block-luks.c
@@ -32,6 +32,7 @@ 
 #include "qemu/uuid.h"
 
 #include "qemu/coroutine.h"
+#include "autowipe.h"
 
 /*
  * Reference for the LUKS format implemented here is
@@ -698,19 +699,18 @@  qcrypto_block_luks_store_key(QCryptoBlock *block,
 {
     QCryptoBlockLUKS *luks = block->opaque;
     QCryptoBlockLUKSKeySlot *slot = &luks->header.key_slots[slot_idx];
-    g_autofree uint8_t *splitkey = NULL;
+    g_autowipe uint8_t *splitkey = NULL;
     size_t splitkeylen;
-    g_autofree uint8_t *slotkey = NULL;
+    g_autowipe uint8_t *slotkey = NULL;
     g_autoptr(QCryptoCipher) cipher = NULL;
     g_autoptr(QCryptoIVGen) ivgen = NULL;
     Error *local_err = NULL;
     uint64_t iters;
-    int ret = -1;
 
     if (qcrypto_random_bytes(slot->salt,
                              QCRYPTO_BLOCK_LUKS_SALT_LEN,
                              errp) < 0) {
-        goto cleanup;
+        return -1;
     }
 
     splitkeylen = luks->header.master_key_len * slot->stripes;
@@ -728,14 +728,14 @@  qcrypto_block_luks_store_key(QCryptoBlock *block,
                                        &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
-        goto cleanup;
+        return -1;
     }
 
     if (iters > (ULLONG_MAX / iter_time)) {
         error_setg_errno(errp, ERANGE,
                          "PBKDF iterations %llu too large to scale",
                          (unsigned long long)iters);
-        goto cleanup;
+        return -1;
     }
 
     /* iter_time was in millis, but count_iters reported for secs */
@@ -745,7 +745,7 @@  qcrypto_block_luks_store_key(QCryptoBlock *block,
         error_setg_errno(errp, ERANGE,
                          "PBKDF iterations %llu larger than %u",
                          (unsigned long long)iters, UINT32_MAX);
-        goto cleanup;
+        return -1;
     }
 
     slot->iterations =
@@ -764,7 +764,7 @@  qcrypto_block_luks_store_key(QCryptoBlock *block,
                        slot->iterations,
                        slotkey, luks->header.master_key_len,
                        errp) < 0) {
-        goto cleanup;
+        return -1;
     }
 
 
@@ -777,7 +777,7 @@  qcrypto_block_luks_store_key(QCryptoBlock *block,
                                 slotkey, luks->header.master_key_len,
                                 errp);
     if (!cipher) {
-        goto cleanup;
+        return -1;
     }
 
     ivgen = qcrypto_ivgen_new(luks->ivgen_alg,
@@ -786,7 +786,7 @@  qcrypto_block_luks_store_key(QCryptoBlock *block,
                               slotkey, luks->header.master_key_len,
                               errp);
     if (!ivgen) {
-        goto cleanup;
+        return -1;
     }
 
     /*
@@ -802,7 +802,7 @@  qcrypto_block_luks_store_key(QCryptoBlock *block,
                                masterkey,
                                splitkey,
                                errp) < 0) {
-        goto cleanup;
+        return -1;
     }
 
     /*
@@ -815,7 +815,7 @@  qcrypto_block_luks_store_key(QCryptoBlock *block,
                                             splitkey,
                                             splitkeylen,
                                             errp) < 0) {
-        goto cleanup;
+        return -1;
     }
 
     /* Write out the slot's master key material. */
@@ -825,25 +825,16 @@  qcrypto_block_luks_store_key(QCryptoBlock *block,
                   splitkey, splitkeylen,
                   opaque,
                   errp) != splitkeylen) {
-        goto cleanup;
+        return -1;
     }
 
     slot->active = QCRYPTO_BLOCK_LUKS_KEY_SLOT_ENABLED;
 
     if (qcrypto_block_luks_store_header(block,  writefunc, opaque, errp)) {
-        goto cleanup;
+        return -1;
     }
 
-    ret = 0;
-
-cleanup:
-    if (slotkey) {
-        memset(slotkey, 0, luks->header.master_key_len);
-    }
-    if (splitkey) {
-        memset(splitkey, 0, splitkeylen);
-    }
-    return ret;
+    return 0;
 }
 
 /*
@@ -868,9 +859,9 @@  qcrypto_block_luks_load_key(QCryptoBlock *block,
 {
     QCryptoBlockLUKS *luks = block->opaque;
     const QCryptoBlockLUKSKeySlot *slot = &luks->header.key_slots[slot_idx];
-    g_autofree uint8_t *splitkey = NULL;
+    g_autowipe uint8_t *splitkey = NULL;
     size_t splitkeylen;
-    g_autofree uint8_t *possiblekey = NULL;
+    g_autowipe uint8_t *possiblekey = NULL;
     ssize_t rv;
     g_autoptr(QCryptoCipher) cipher = NULL;
     uint8_t keydigest[QCRYPTO_BLOCK_LUKS_DIGEST_LEN];
@@ -1059,8 +1050,8 @@  qcrypto_block_luks_open(QCryptoBlock *block,
 {
     QCryptoBlockLUKS *luks = NULL;
     int ret = 0;
-    g_autofree uint8_t *masterkey = NULL;
-    g_autofree char *password = NULL;
+    g_autowipe uint8_t *masterkey = NULL;
+    g_autowipe char *password = NULL;
 
     if (!(flags & QCRYPTO_BLOCK_OPEN_NO_IO)) {
         if (!options->u.luks.key_secret) {
@@ -1151,6 +1142,7 @@  qcrypto_block_luks_open(QCryptoBlock *block,
  fail:
     qcrypto_block_free_cipher(block);
     qcrypto_ivgen_free(block->ivgen);
+
     g_free(luks);
     return ret;
 }
@@ -1176,11 +1168,11 @@  qcrypto_block_luks_create(QCryptoBlock *block,
     QCryptoBlockLUKS *luks;
     QCryptoBlockCreateOptionsLUKS luks_opts;
     Error *local_err = NULL;
-    g_autofree uint8_t *masterkey = NULL;
+    g_autowipe uint8_t *masterkey = NULL;
     size_t header_sectors;
     size_t split_key_sectors;
     size_t i;
-    g_autofree char *password;
+    g_autowipe char *password;
     const char *cipher_alg;
     const char *cipher_mode;
     const char *ivgen_alg;
@@ -1445,23 +1437,14 @@  qcrypto_block_luks_create(QCryptoBlock *block,
         goto error;
      }
 
-
-    memset(masterkey, 0, luks->header.master_key_len);
     return 0;
-
  error:
-    if (masterkey) {
-        memset(masterkey, 0, luks->header.master_key_len);
-    }
-
     qcrypto_block_free_cipher(block);
     qcrypto_ivgen_free(block->ivgen);
-
     g_free(luks);
     return -1;
 }
 
-
 static int qcrypto_block_luks_get_info(QCryptoBlock *block,
                                        QCryptoBlockInfo *info,
                                        Error **errp)