diff --git a/lib/luks1/keymanage.c b/lib/luks1/keymanage.c index 982b189d..7b000999 100644 --- a/lib/luks1/keymanage.c +++ b/lib/luks1/keymanage.c @@ -962,12 +962,12 @@ static int LUKS_open_key(unsigned int keyIndex, const char *password, size_t passwordLen, struct luks_phdr *hdr, - struct volume_key *vk, + struct volume_key **vk, struct crypt_device *ctx) { crypt_keyslot_info ki = LUKS_keyslot_info(hdr, keyIndex); struct volume_key *derived_key; - char *AfKey; + char *AfKey = NULL; size_t AFEKSize; int r; @@ -981,8 +981,13 @@ static int LUKS_open_key(unsigned int keyIndex, if (!derived_key) return -ENOMEM; - assert(vk->keylength == hdr->keyBytes); - AFEKSize = AF_split_sectors(vk->keylength, hdr->keyblock[keyIndex].stripes) * SECTOR_SIZE; + *vk = crypt_alloc_volume_key(hdr->keyBytes, NULL); + if (!*vk) { + r = -ENOMEM; + goto out; + } + + AFEKSize = AF_split_sectors(hdr->keyBytes, hdr->keyblock[keyIndex].stripes) * SECTOR_SIZE; AfKey = crypt_safe_alloc(AFEKSize); if (!AfKey) { r = -ENOMEM; @@ -1008,16 +1013,20 @@ static int LUKS_open_key(unsigned int keyIndex, if (r < 0) goto out; - r = AF_merge(ctx, AfKey, vk->key, vk->keylength, hdr->keyblock[keyIndex].stripes, hdr->hashSpec); + r = AF_merge(ctx, AfKey, (*vk)->key, (*vk)->keylength, hdr->keyblock[keyIndex].stripes, hdr->hashSpec); if (r < 0) goto out; - r = LUKS_verify_volume_key(hdr, vk); + r = LUKS_verify_volume_key(hdr, *vk); /* Allow only empty passphrase with null cipher */ if (!r && crypt_is_cipher_null(hdr->cipherName) && passwordLen) r = -EPERM; out: + if (r < 0) { + crypt_free_volume_key(*vk); + *vk = NULL; + } crypt_safe_free(AfKey); crypt_free_volume_key(derived_key); return r; @@ -1033,16 +1042,14 @@ int LUKS_open_key_with_hdr(int keyIndex, unsigned int i, tried = 0; int r; - *vk = crypt_alloc_volume_key(hdr->keyBytes, NULL); - if (keyIndex >= 0) { - r = LUKS_open_key(keyIndex, password, passwordLen, hdr, *vk, ctx); + r = LUKS_open_key(keyIndex, password, passwordLen, hdr, vk, ctx); return (r < 0) ? r : keyIndex; } for (i = 0; i < LUKS_NUMKEYS; i++) { - r = LUKS_open_key(i, password, passwordLen, hdr, *vk, ctx); - if(r == 0) + r = LUKS_open_key(i, password, passwordLen, hdr, vk, ctx); + if (r == 0) return i; /* Do not retry for errors that are no -EPERM or -ENOENT,