From patchwork Sun Nov 16 21:23:22 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 722 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org Authentication-Results: mail.u-boot.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.a=rsa-sha256 header.s=google header.b=G4loMmMH; dkim-atps=neutral Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 785DF684C5 for ; Sun, 16 Nov 2025 14:24:11 -0700 (MST) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id DzeqDW0BqUtQ for ; Sun, 16 Nov 2025 14:24:11 -0700 (MST) Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id D103F685BF for ; Sun, 16 Nov 2025 14:24:10 -0700 (MST) Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 41DD46864C for ; Sun, 16 Nov 2025 14:24:09 -0700 (MST) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id 3LslgEaXFc4N for ; Sun, 16 Nov 2025 14:24:09 -0700 (MST) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=209.85.166.44; helo=mail-io1-f44.google.com; envelope-from=sjg@chromium.org; receiver=u-boot.org Received: from mail-io1-f44.google.com (mail-io1-f44.google.com [209.85.166.44]) by mail.u-boot.org (Postfix) with ESMTPS id 995D8685BF for ; Sun, 16 Nov 2025 14:24:04 -0700 (MST) Received: by mail-io1-f44.google.com with SMTP id ca18e2360f4ac-9490a482b7bso11893339f.1 for ; Sun, 16 Nov 2025 13:24:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1763328243; x=1763933043; darn=u-boot.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=GiBjr1H7KWTRMc/cXkRBV7ljw6t6o02DxD3en/kIAX0=; b=G4loMmMHlsYNG2oaY96t+CoPgnB5TMLjPqGXldrO92wUrqaKz5D6/fQVKjuuH49iF8 RCi2vbk1w2sfXlGC7H9ElU+MYER8MUb/TR9nmMIdpIuvDNjgXz1EW3OZv/HCoiHGCVct YEzmJHTnIPztZBtwmk6ILMhYKM1aWwA+Ml0Vk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763328243; x=1763933043; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=GiBjr1H7KWTRMc/cXkRBV7ljw6t6o02DxD3en/kIAX0=; b=cnmPXjkXNXlsZr6pwRtuem9lh6UsituQNRLPIgOnwR5z3IpQEbzQEcYNZABfxq4ulW MvVTStk1gCnX4yf6NOHPx2WSx7GeLiv1eoSyRWbRa5W+15xiZKX5FT3PZwfDbxYZrl5n JbN6wAv9YErO+Jv9QZn7iiqiMOLKPgkHAjP6Jk7jL5Lov/483kvh+HO5/Ogesn5z2bES zl1Rma6PHXHsI3CmJcAJ6QsaWVeXj68e43v5ezgqXKJZIMYKkPZx5O9PVITm5c7GPfyX KwSrI1hcjgecJ9t5rJrJjaY2hQO+q8eeOUd1C4mLvgCA2dSafiYuspV9wZKe/JG0FqJB LjAA== X-Gm-Message-State: AOJu0Yyl1b2SSoG/SMGOOhU97wfiqPMancmUlyKpGLF0CxblB0kPd5PR Ho5SKYKZQxISNRs6y/lT6bqysWXz2rVUZGg1EcgKtclYowSaq8JSikVvNbBiDfvHCaWrU2kvfE1 Jf28= X-Gm-Gg: ASbGncstWTU++u3fYrIt/Pbb3mIFl0tLBK5Ipe+bo1JzMAZGmPQzz9slav9XWldhquu AvZq5nDVgELYSBTJTKLB95LuEZ7o1BlWv938JKl+DrBm2Iv7EOwUun6xlgQTHD+u+T0UXfkXixD Hp7S/ypiQAmAvT9dyzgmbE/Ut852dV+5Cyc3SJQWwn5eLtG34P2/ceKlLdYkZGuyU5wn3XBBBxY M21c/6u33H/UVdbowGRR+n7fPn1WsGaLYA75pHsv0dEVv97yXX3gx5IVX0l9l2pvBh8RCNIzDsP sYffKkZdNoMb6s7W5i1UBF3nvQfXb5Tw2hR7ulHISrkEIIcdiQH+RrYx38FAfOcK2TaR+fpqr+O EqY/XAzxg1qrxn+0rrNEet5zbb9XhgJCuk9Xfs05+u9Cfrql2WsRo4yU4fyd8ZB1il9zBmBWeos 7//r3McP6Dnh3CeGp8 X-Google-Smtp-Source: AGHT+IGhifmmkk+/jrOwhk0khXs9ECOR2njWonUymhxrHCh9gC2CbnF1UAUWrG4kCGAUfsjk0PSrqQ== X-Received: by 2002:a05:6602:640d:b0:948:8be8:a8d7 with SMTP id ca18e2360f4ac-948e0da72e6mr1475006439f.13.1763328243107; Sun, 16 Nov 2025 13:24:03 -0800 (PST) Received: from chromium.org ([73.34.74.121]) by smtp.gmail.com with ESMTPSA id ca18e2360f4ac-948d2d162dcsm577962339f.13.2025.11.16.13.24.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 16 Nov 2025 13:24:01 -0800 (PST) From: Simon Glass X-Google-Original-From: Simon Glass To: U-Boot Concept Date: Sun, 16 Nov 2025 14:23:22 -0700 Message-ID: <20251116212334.1603490-9-simon.glass@canonical.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251116212334.1603490-1-simon.glass@canonical.com> References: <20251116212334.1603490-1-simon.glass@canonical.com> MIME-Version: 1.0 Message-ID-Hash: LKK52JB43PFEPIINYINYLNPOII7ZVI2K X-Message-ID-Hash: LKK52JB43PFEPIINYINYLNPOII7ZVI2K X-MailFrom: sjg@chromium.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Simon Glass , Claude X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 08/14] luks: Move key derivation to the caller of try_keyslot() List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Move the derive_key_pbkdf2() call from inside try_keyslot() to the caller, luks_unlock() With this change luks_unlock() deals with key derivation and try_keyslot() only handles the decryption part, using a supplied derived key. Co-developed-by: Claude Signed-off-by: Simon Glass --- drivers/block/luks.c | 49 ++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/drivers/block/luks.c b/drivers/block/luks.c index 48f281ef77c..c23b6f50671 100644 --- a/drivers/block/luks.c +++ b/drivers/block/luks.c @@ -324,31 +324,27 @@ static int derive_key_pbkdf2(struct luks1_keyslot *slot, const u8 *pass, } /** - * try_keyslot() - Unlock a LUKS key slot with a passphrase + * try_keyslot() - Try to unlock a LUKS key slot with a derived key * * @blk: Block device * @pinfo: Partition information * @hdr: LUKS header * @slot_idx: Key slot index to try - * @pass: Passphrase to try - * @pass_len: Length of passphrase - * @md_type: Hash algorithm type + * @md_type: Hash algorithm type for master key verification * @key_size: Size of the key - * @derived_key: Buffer for derived key (key_size bytes) + * @derived_key: Pre-derived key from PBKDF2 (key_size bytes) * @km: Buffer for encrypted key material * @km_blocks: Size of km buffer in blocks * @split_key: Buffer for AF-split key * @candidate_key: Buffer to receive decrypted master key * - * Return: 0 on success (correct passphrase), -EPROTO on mbedtls error, -ve on - * other error + * Return: 0 on success (correct key), -ve on error */ static int try_keyslot(struct udevice *blk, struct disk_partition *pinfo, struct luks1_phdr *hdr, int slot_idx, - const u8 *pass, size_t pass_len, - mbedtls_md_type_t md_type, - uint key_size, u8 *derived_key, u8 *km, - uint km_blocks, u8 *split_key, u8 *candidate_key) + mbedtls_md_type_t md_type, uint key_size, + const u8 *derived_key, u8 *km, uint km_blocks, + u8 *split_key, u8 *candidate_key) { struct luks1_keyslot *slot = &hdr->key_slot[slot_idx]; uint km_offset, stripes, split_key_size; @@ -358,22 +354,12 @@ static int try_keyslot(struct udevice *blk, struct disk_partition *pinfo, u8 iv[AES_BLOCK_LENGTH]; int ret; - /* Check if slot is active */ - if (be32_to_cpu(slot->active) != LUKS_KEY_ENABLED) - return -ENOENT; - - log_debug("trying key slot %d (pass len=%zu)...\n", slot_idx, pass_len); + log_debug("trying key slot %d with derived key\n", slot_idx); km_offset = be32_to_cpu(slot->key_material_offset); stripes = be32_to_cpu(slot->stripes); split_key_size = key_size * stripes; - /* Derive key from passphrase using PBKDF2 */ - ret = derive_key_pbkdf2(slot, pass, pass_len, md_type, key_size, - derived_key); - if (ret) - return ret; - /* Read encrypted key material */ ret = blk_read(blk, pinfo->start + km_offset, km_blocks, km); if (ret != km_blocks) { @@ -543,9 +529,22 @@ int luks_unlock(struct udevice *blk, struct disk_partition *pinfo, /* Try each key slot */ for (i = 0; i < LUKS_NUMKEYS; i++) { - ret = try_keyslot(blk, pinfo, hdr, i, pass, pass_len, md_type, - *key_size, derived_key, km, km_blocks, - split_key, candidate_key); + struct luks1_keyslot *slot = &hdr->key_slot[i]; + + /* Skip inactive slots */ + if (be32_to_cpu(slot->active) != LUKS_KEY_ENABLED) + continue; + + /* Derive key for this slot */ + ret = derive_key_pbkdf2(slot, pass, pass_len, md_type, + *key_size, derived_key); + if (ret) + continue; + + /* Try to unlock with the derived key */ + ret = try_keyslot(blk, pinfo, hdr, i, md_type, *key_size, + derived_key, km, km_blocks, split_key, + candidate_key); if (!ret) { /* Successfully unlocked */