From patchwork Sun Nov 16 21:23:24 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 724 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=Le9NOw3J; dkim-atps=neutral Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 223A6685C6 for ; Sun, 16 Nov 2025 14:24:14 -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 gSlIIwcAgM9M for ; Sun, 16 Nov 2025 14:24:14 -0700 (MST) Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 551EA6864C for ; Sun, 16 Nov 2025 14:24:12 -0700 (MST) Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 64CF86864A 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 3AKlvL8zr5QC for ; Sun, 16 Nov 2025 14:24:11 -0700 (MST) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=209.85.166.54; helo=mail-io1-f54.google.com; envelope-from=sjg@chromium.org; receiver=u-boot.org Received: from mail-io1-f54.google.com (mail-io1-f54.google.com [209.85.166.54]) by mail.u-boot.org (Postfix) with ESMTPS id 80437684C5 for ; Sun, 16 Nov 2025 14:24:10 -0700 (MST) Received: by mail-io1-f54.google.com with SMTP id ca18e2360f4ac-949031532f9so29654739f.0 for ; Sun, 16 Nov 2025 13:24:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1763328249; x=1763933049; 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=F+e/o9Y81iU1s4yM57ZnV7qqpArG3la/EKKkLc1wjeM=; b=Le9NOw3JRzS9G02jxNNrARri+VkISkT6lhki1thLyoxQj7/VEldpOtqbXtp7RiFYDE NnwTrd/UtsGzmRD0SX7Y5d3K9dqpKA2hrSIPQJHpLbVmv1fJGSI9+9S1a0saXGcxn/wB Vrsf3MzkrWN1L0ZlxrZSUdKg6VACPcFrf0g4c= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763328249; x=1763933049; 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=F+e/o9Y81iU1s4yM57ZnV7qqpArG3la/EKKkLc1wjeM=; b=kAF9Zee8GuUTIa9Ygl6Q0oHRuOQywV59UFxlm5khJpG63GV99BggZB87ZGGYkG6QJA pWE9xjPCo+W5gVXUpIXDVUV1q5ZkLjyAJuG5rtPeP0X8xZ470R6CvlD3iPSm0y0r3eKI 4gUjqrfITBiZaOfoUZkyf28Jmc+eCDufsC/Aj/j7gm7JPIAcEdjKlNd0l+DrRYP6zdSe mLWPmrSwUxO1VrTKGeUZOgz5HPsZ4+suJVGIlqsO0g+z5i4Z9YuX4uDybH5cwt3bQaRx t9zPwoYp/E59nuDarDFvrVr81SSUmYZDH472NW3mRnF6xhivd0SJpUZoyQ6230CvEErS izNQ== X-Gm-Message-State: AOJu0YxkAHd4clTzMXBB8pUWKbveC23ALje6CuyumuM2EkGFKSgQrz/I fILPPI3/KUcH4S1m/cxLl7i8Rbh5UKTl3yuAjdBPR3NhY0AOfZkeVq7OlUB6kqX9tarlEkAzTEW R8ag= X-Gm-Gg: ASbGncsTeMEYzJBWqRgpTnkQ4b78GDfxVqvXESkW+GUg5Yk24Mgozhvi9YSVho0+OU2 hqPCpZpKLUnpZonz+7BD1bLCMe2Z1btswBbmj2MEjYtu5JXgDMhlIB5wKEE1H5GutAmUqaFDA6W Z/ezB84K5uBstd4bXeTEmA/Iol4fdRQ8T+o/1thPBZsBY4oX3DeIsO0zBNy3oFtB31tIjJeLhHR w4gXBgnF2E0YLjIBYZDUolVjfGAsWHBjdjyLSUfuxBys5WE+PBK9eRDWkZ7Mlaueg+NXegb8S/R Z2NEQqJZ7ghoaNjKpluFimQKUVK2VnKz1ca7VzYzV7XV7qUKpAsxrV46Sr7tZz5RsV4fSs1LT9A k9zfe1yCBvWTmG6BVq9IFNqVdhKCViFIxgofdWuq/K2XOGPibLEQx9BlxfHaia4YKo/rnPsFb1S Rxn0aM5NM1ITa8+0PhC8KYUwL4sck= X-Google-Smtp-Source: AGHT+IGIKw139g+ZstLlO5448GmlKKLN4bs8XojXmrU5Na68eOm22bDfKwE4N3qbW0UE3wLPWqac1A== X-Received: by 2002:a05:6638:300e:b0:5b7:1afc:dd10 with SMTP id 8926c6da1cb9f-5b7c82cb38bmr6915780173.5.1763328248950; Sun, 16 Nov 2025 13:24:08 -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.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 16 Nov 2025 13:24:07 -0800 (PST) From: Simon Glass X-Google-Original-From: Simon Glass To: U-Boot Concept Date: Sun, 16 Nov 2025 14:23:24 -0700 Message-ID: <20251116212334.1603490-11-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: YDRS7HI4MFMKX2YWJ7TYRGDCKTYFBA6K X-Message-ID-Hash: YDRS7HI4MFMKX2YWJ7TYRGDCKTYFBA6K 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 10/14] luks: Support a pre-derived key with LUKSv1 List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: In some cases we may wish to provide a pre-derived key, e.g. obtained from a TKey. Provide an option for this with LUKSv1. For now it is not exported. Co-developed-by: Claude Signed-off-by: Simon Glass --- drivers/block/luks.c | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/drivers/block/luks.c b/drivers/block/luks.c index a3c86c5a197..3fc54dbbb9a 100644 --- a/drivers/block/luks.c +++ b/drivers/block/luks.c @@ -329,8 +329,9 @@ static int derive_key_pbkdf2(struct luks1_keyslot *slot, const u8 *pass, * @blk: Block device * @pinfo: Partition information * @hdr: LUKS1 header (already read) - * @pass: Passphrase + * @pass: Passphrase or pre-derived key * @pass_len: Length of passphrase + * @pre_derived: True if pass is a pre-derived key, false for passphrase * @master_key: Buffer to receive master key * @key_size: Output for key size * @@ -338,7 +339,7 @@ static int derive_key_pbkdf2(struct luks1_keyslot *slot, const u8 *pass, */ static int unlock_luks1(struct udevice *blk, struct disk_partition *pinfo, struct luks1_phdr *hdr, const u8 *pass, size_t pass_len, - u8 *master_key, u32 *key_size); + bool pre_derived, u8 *master_key, u32 *key_size); /** * try_keyslot() - Try to unlock a LUKS key slot with a derived key @@ -447,14 +448,16 @@ static int try_keyslot(struct udevice *blk, struct disk_partition *pinfo, * unlock_luks1() - Unlock a LUKSv1 partition * * Attempts to unlock a LUKSv1 encrypted partition by trying each active - * key slot with the provided passphrase. Uses PBKDF2 for key derivation - * and supports CBC cipher mode with optional ESSIV. + * key slot with the provided passphrase or pre-derived key. When pre_derived + * is false, uses PBKDF2 for key derivation. When true, uses the pass data + * directly as the derived key. Supports CBC cipher mode with optional ESSIV. * * @blk: Block device containing the partition * @pinfo: Partition information * @hdr: LUKSv1 header (already read and validated) - * @pass: Passphrase (binary data) + * @pass: Passphrase (binary data) or pre-derived key * @pass_len: Length of passphrase in bytes + * @pre_derived: True if pass is a pre-derived key, false for passphrase * @master_key: Buffer to receive unlocked master key (min 128 bytes) * @key_sizep: Output for master key size in bytes (set only on success) * @@ -462,7 +465,7 @@ static int try_keyslot(struct udevice *blk, struct disk_partition *pinfo, */ static int unlock_luks1(struct udevice *blk, struct disk_partition *pinfo, struct luks1_phdr *hdr, const u8 *pass, size_t pass_len, - u8 *master_key, u32 *key_sizep) + bool pre_derived, u8 *master_key, u32 *key_sizep) { uint split_key_size, km_blocks, key_size; u8 *split_key, *derived_key; @@ -524,6 +527,17 @@ static int unlock_luks1(struct udevice *blk, struct disk_partition *pinfo, goto out; } + /* If using pre-derived key, use it directly */ + if (pre_derived) { + if (pass_len != key_size) { + log_debug("Pre-derived key size mismatch: got %zu, need %u\n", + pass_len, key_size); + ret = -EINVAL; + goto out; + } + memcpy(derived_key, pass, key_size); + } + /* Try each key slot */ for (i = 0; i < LUKS_NUMKEYS; i++) { struct luks1_keyslot *slot = &hdr->key_slot[i]; @@ -532,11 +546,13 @@ static int unlock_luks1(struct udevice *blk, struct disk_partition *pinfo, 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; + /* Derive key for this slot if not pre-derived */ + if (!pre_derived) { + 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, @@ -610,7 +626,7 @@ int luks_unlock(struct udevice *blk, struct disk_partition *pinfo, case LUKS_VERSION_1: hdr = (struct luks1_phdr *)buffer; ret = unlock_luks1(blk, pinfo, hdr, pass, pass_len, master_key, - key_sizep); + false, key_sizep); break; case LUKS_VERSION_2: ret = unlock_luks2(blk, pinfo, pass, pass_len, master_key,