Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.0/patches/2175910/?format=api
{ "id": 2175910, "url": "http://patchwork.ozlabs.org/api/1.0/patches/2175910/?format=api", "project": { "id": 58, "url": "http://patchwork.ozlabs.org/api/1.0/projects/58/?format=api", "name": "swupdate development", "link_name": "swupdate", "list_id": "swupdate.googlegroups.com", "list_email": "swupdate@googlegroups.com", "web_url": "https://github.com/sbabic/swupdate", "scm_url": "git://github.com/sbabic/swupdate", "webscm_url": "" }, "msgid": "<20251219112215.103862-3-bage@debian.org>", "date": "2025-12-19T11:21:57", "name": "[2/5] Increased PKCS#11 decryption performance with p11-kit", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": false, "hash": "6493f8fe6270563ae6dd4437b187b5f10f208f66", "submitter": { "id": 84118, "url": "http://patchwork.ozlabs.org/api/1.0/people/84118/?format=api", "name": "Bastian Germann", "email": "bage@debian.org" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/swupdate/patch/20251219112215.103862-3-bage@debian.org/mbox/", "series": [ { "id": 485984, "url": "http://patchwork.ozlabs.org/api/1.0/series/485984/?format=api", "date": "2025-12-19T11:22:00", "name": "pkcs11 decrypt provider based on p11-kit", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/485984/mbox/" } ], "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2175910/checks/", "tags": {}, "headers": { "Return-Path": "<swupdate+bncBCN5N5NJZ4BBB37KSTFAMGQEPOMXZWA@googlegroups.com>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=googlegroups.com header.i=@googlegroups.com\n header.a=rsa-sha256 header.s=20230601 header.b=sKLYZYj/;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=googlegroups.com\n (client-ip=2a00:1450:4864:20::13c; helo=mail-lf1-x13c.google.com;\n envelope-from=swupdate+bncbcn5n5njz4bbb37kstfamgqepomxzwa@googlegroups.com;\n receiver=patchwork.ozlabs.org)" ], "Received": [ "from mail-lf1-x13c.google.com (mail-lf1-x13c.google.com\n [IPv6:2a00:1450:4864:20::13c])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4dXlW96szGz1y3w\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 19 Dec 2025 22:22:29 +1100 (AEDT)", "by mail-lf1-x13c.google.com with SMTP id\n 2adb3069b0e04-59427b2fe85sf883773e87.1\n for <incoming@patchwork.ozlabs.org>;\n Fri, 19 Dec 2025 03:22:29 -0800 (PST)", "by 2002:ac2:46e9:0:b0:595:7e4e:45dc with SMTP id\n 2adb3069b0e04-598fa3fa69als1041989e87.1.-pod-prod-00-eu-canary;\n Fri, 19 Dec 2025 03:22:20 -0800 (PST)", "from stravinsky.debian.org (stravinsky.debian.org.\n [2001:41b8:202:deb::311:108])\n by gmr-mx.google.com with ESMTPS id\n 38308e7fff4ca-3812260ead6si310801fa.6.2025.12.19.03.22.20\n for <swupdate@googlegroups.com>\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Fri, 19 Dec 2025 03:22:20 -0800 (PST)", "from authenticated user\n\tby stravinsky.debian.org with esmtpsa\n (TLS1.3:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256)\n\t(Exim 4.94.2)\n\t(envelope-from <bage@debian.org>)\n\tid 1vWYYu-003BXm-Bv; Fri, 19 Dec 2025 11:22:19 +0000" ], "ARC-Seal": [ "i=2; a=rsa-sha256; t=1766143346; cv=pass;\n d=google.com; s=arc-20240605;\n b=BMIcSY4er1G0n/n293AMjP+4wMlwbxviRgg2eocBY6OCbtKtZzz+Dj1DQQEgBWYI01\n SabRQmWBIG+y2BMD5V7iiykPyZB2JCWgWIEikHt6/QX+x9M3T+DxiGnlwqPojzSWTdWF\n gorH1D5sjW/W+lzh9wo8g4GFiyNHNGBkHeB2gtVdcpLsKeVCpPPg7ytdWfc4Z/Oxb08M\n C1gC1b8RA3g5RTz5Z8YKK2kYge6ViktfZjd2XhH786R0GLGMHYJK1NyS7YQjBo7JyEMC\n Vgx2STx3ROp0A0YS+xeAShQra80/3W6iCbwAnATA4irUtDgvkWiL8pHKxve4+2l9NLuL\n HoBg==", "i=1; a=rsa-sha256; t=1766143340; cv=none;\n d=google.com; s=arc-20240605;\n b=db5IE4tAnh5bbWTu6mdWta6m8xk5hpByzQ1zLMBtsEJ3iCymr2irYwcrJ08lZts3/H\n 4u8HJeqmKbb0flGSZs74FWAM7DdeKplF7xPJCsMIp79gM7Ww0RBk6Tb9cKKjzAtaGb66\n 5buQywJ3I8/LXH/Yc9AiTMoNuh2uPrFSTTkXfqqMUAZ8BmJJcCLxWnwFwZB3QgDzpYbE\n apET/awD6g+LQB56IGnbEoo5tFmogJVvqkmAiidQukg3Z370f0SQwWNhDWrs3VUNRmeb\n Qgbmu8/OWZMrAXBnf+SqVgFpPfSyiodpqYl7115sjQxrgFY9ey9d5yhrLu4njcOKmzlk\n YozQ==" ], "ARC-Message-Signature": [ "i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com;\n s=arc-20240605;\n h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post\n :list-id:mailing-list:precedence:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:sender:dkim-signature;\n bh=qr+E3Wrl4s/n8sAFCYnCow+D4H/vyNfTdFFt2F9dCWk=;\n fh=nj3p41jiEtVq35TKuE054yv1wQWf5BoNbPkHxq2sL9o=;\n b=bVqk4Vhv2j/3wgQ6jIPuVrc9DocwmfN2Czqdvgk1j59VB2UXHoSByJoMJIjLCUrJJO\n Us1s5ivfW2KxOncnEzljsv9Kvb2DOhRZms0/Em1tZ7OkvVjgJRJxUZLZqHPaOvPuSwXJ\n SAcg6FIX2q2Xr8SBXsWnX7vlF5BGon+fq8JeOZmiwuDzpNust9rciAvZR/iBMHpIzGnQ\n ichxEDfe98vEm0wbeayOhDSt8DBzRx102TT0ljhpcZ9z15zmHYPV/YZah27HysadRuX9\n sH/eqZCegwmCnT3SnuvnGx+3u5OJHc2bLEhCQr4yA4+rzHEuzQbV8f8C65HgCx+UFQj0\n wZLg==;\n darn=patchwork.ozlabs.org", "i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com;\n s=arc-20240605;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:dkim-signature;\n bh=xYsTCQSUxUAlLXfiRTrneR3mKkU02bAcl7WkCH1ggKA=;\n fh=UiMPUQTMnx6PI4nmZFgZMMFA6HnOD31xG3jm6GedL40=;\n b=lG5HvxENT5ksCFXjc0jvdY3Fk1nVQh5rUiEuqEbpYblCGk7QWFQR2IypMrbEqq4+fd\n iD8uJxV3tDR/dkhiaWbDRRKpLyS2RHxPR+BKOEoWwEGWjgqQBJnHEwXKZka6M5B+bAE9\n M4bZ/8u6GMGCkFuRGlLJjVxuMGEucLP1BlxJ31h2Ca3BBNW5PVgV1CrKL1g91YsODj00\n TSMYgKEknIu5HAcj1Ssxhu+9grgO0zUTpwDghAKHDGDAv+lSkx2eVZ4rv2ChW/oQYyg/\n Egx5/oqzmKbd7lUm5Iv52E/dZOP/MSGPy67KT02Zj3fjlVfsKkqIgrIuBWfYyw/uoDvq\n qbyA==;\n dara=google.com" ], "ARC-Authentication-Results": [ "i=2; gmr-mx.google.com;\n dkim=pass header.i=@debian.org header.s=smtpauto.stravinsky\n header.b=srvDbTyZ;\n spf=none (google.com: bage@debian.org does not designate permitted\n sender hosts) smtp.mailfrom=bage@debian.org", "i=1; gmr-mx.google.com;\n dkim=pass header.i=@debian.org header.s=smtpauto.stravinsky\n header.b=srvDbTyZ;\n spf=none (google.com: bage@debian.org does not designate permitted\n sender hosts) smtp.mailfrom=bage@debian.org" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=googlegroups.com; s=20230601; t=1766143346; x=1766748146;\n darn=patchwork.ozlabs.org;\n h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post\n :list-id:mailing-list:precedence:x-original-authentication-results\n :x-original-sender:mime-version:references:in-reply-to:message-id\n :date:subject:cc:to:from:sender:from:to:cc:subject:date:message-id\n :reply-to;\n bh=qr+E3Wrl4s/n8sAFCYnCow+D4H/vyNfTdFFt2F9dCWk=;\n b=sKLYZYj/eEhkmokPr4RLm7dswUC6j5SDZSfL1kNNBcOJSxXPUQVQGus0gz2uUsJbup\n MVcHAOejPSe5nKNzWClSaRgN1MqVperDNWCoq+Gk85Ozsf5Jm7e/FrUKxLozeZR2/6ZN\n rzKWBO+siJ+qKZIyNTJrEse5C2AhAwkEMrAQTxfO23Te/Lot1uyawxq8pXUTRdc09CV9\n J/7GMriasXWwCU5AuRk4VeDqIzFAkqDTFC5GdYPGzFWmvpTFr4ms9HSUVHIvayCjZ525\n XHSRnRx92gm7XHFG6W8eQCpJN9alSCOaIWxldoM+666uo6BDEoxyGnhM5N5N9osP5RPb\n fugQ==", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20230601; t=1766143346; x=1766748146;\n h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post\n :x-spam-checked-in-group:list-id:mailing-list:precedence\n :x-original-authentication-results:x-original-sender:mime-version\n :references:in-reply-to:message-id:date:subject:cc:to:from\n :x-beenthere:x-gm-message-state:sender:from:to:cc:subject:date\n :message-id:reply-to;\n bh=qr+E3Wrl4s/n8sAFCYnCow+D4H/vyNfTdFFt2F9dCWk=;\n b=lxce/7XKh52+EdHMAkunQ+Z3fC8Xjl8Hi88e+zNTZ42KDBEZ/V9CtSpOX6/HBDJRPA\n qNBh+2JUZBB8Lfyw2OfTWjldOHG7YQG02IqoBnUVuPbwOb8e3j+vjPW+K4WIWsxnojsQ\n WlWClISkun8mpmvh6cJp3KKTRKcEvR8jb+GjgDrEvrXF+QrQdIr7CqQVH/2/NFALLbIL\n hrQje34UwJeLRd61FBgXvnjecwhQUxsseXyjPIbNEt8HFNH2qY8++/aI6Ryi+k265nh6\n 0F90+9Ip6vvkYFZ175wZRmQCcztN60ev1eoMIQN+xUS3tf+2IksNN61xhBmb+q1MV9lV\n NCrQ==", "Sender": "swupdate@googlegroups.com", "X-Forwarded-Encrypted": "i=2;\n AJvYcCUKl9WuXimYOLscwp3yH6mD5cF/o+oLosIaW8EgyWkEoraGNFIdZShaV35Z1F/CkPdz527bxfRe8Q==@patchwork.ozlabs.org", "X-Gm-Message-State": "AOJu0YyOWhjlS2bJilRXRXh9HuICZhCf/m13cW+Wg09j3LBDiHaemXHg\n\t+3QV/HZOrh2FFvZ9YFSnaI07V9yVn93MhkHsWE1Qv8sHj6my/l1vbjGP", "X-Google-Smtp-Source": "\n AGHT+IF6sQT8ZoV0t8wK1YvIirT1el9tCsJZzaII9tVYo1JGq/uaSbUzUoYLZndD/oc8wl58QQ7T4A==", "X-Received": [ "by 2002:a05:6512:224b:b0:594:524d:d966 with SMTP id\n 2adb3069b0e04-59a17d6809fmr999505e87.21.1766143345690;\n Fri, 19 Dec 2025 03:22:25 -0800 (PST)", "by 2002:a05:6512:2387:b0:598:ec8d:a53a with SMTP id\n 2adb3069b0e04-59a124e3f24mr2213946e87.6.1766143340477;\n Fri, 19 Dec 2025 03:22:20 -0800 (PST)" ], "X-BeenThere": "swupdate@googlegroups.com;\n h=\"AWVwgWZ7IVVDCDpUfsFOimnZ+fvbOuPGsA9NPB7T0MNE6g6fjg==\"", "Received-SPF": "none (google.com: bage@debian.org does not designate permitted\n sender hosts) client-ip=2001:41b8:202:deb::311:108;", "From": "Bastian Germann <bage@debian.org>", "To": "swupdate@googlegroups.com", "Cc": "Matej Zachar <zachar.matej@gmail.com>", "Subject": "[swupdate] [PATCH 2/5] Increased PKCS#11 decryption performance with\n p11-kit", "Date": "Fri, 19 Dec 2025 12:21:57 +0100", "Message-ID": "<20251219112215.103862-3-bage@debian.org>", "X-Mailer": "git-send-email 2.51.0", "In-Reply-To": "<20251219112215.103862-1-bage@debian.org>", "References": "<20251219112215.103862-1-bage@debian.org>", "MIME-Version": "1.0", "X-Debian-User": "bage", "X-Original-Sender": "bage@debian.org", "X-Original-Authentication-Results": "gmr-mx.google.com; dkim=pass\n header.i=@debian.org header.s=smtpauto.stravinsky header.b=srvDbTyZ;\n spf=none (google.com: bage@debian.org does not designate permitted\n sender hosts) smtp.mailfrom=bage@debian.org", "Content-Type": "text/plain; charset=\"UTF-8\"", "Precedence": "list", "Mailing-list": "list swupdate@googlegroups.com;\n contact swupdate+owners@googlegroups.com", "List-ID": "<swupdate.googlegroups.com>", "X-Spam-Checked-In-Group": "swupdate@googlegroups.com", "X-Google-Group-Id": "605343134186", "List-Post": "<https://groups.google.com/group/swupdate/post>,\n <mailto:swupdate@googlegroups.com>", "List-Help": "<https://groups.google.com/support/>,\n <mailto:swupdate+help@googlegroups.com>", "List-Archive": "<https://groups.google.com/group/swupdate", "List-Subscribe": "<https://groups.google.com/group/swupdate/subscribe>,\n <mailto:swupdate+subscribe@googlegroups.com>", "List-Unsubscribe": "\n <mailto:googlegroups-manage+605343134186+unsubscribe@googlegroups.com>,\n <https://groups.google.com/group/swupdate/subscribe>" }, "content": "From: Matej Zachar <zachar.matej@gmail.com>\n\nOn platforms using \"opTee + pkcs11 TA + RPMB\" the decryption\nspeed is increased by order of magnitude - as the C_DecryptInit\ncontext is not lost between decryption updates (C_DecryptUpdate).\nOn my board (iMX8MP) it went from 50min with wolfSSL to 3min with p11-kit\n\nSigned-off-by: Matej Zachar <zachar.matej@gmail.com>\n---\n Makefile.flags | 2 -\n crypto/Kconfig | 16 +-\n crypto/Makefile | 6 +-\n crypto/swupdate_decrypt_pkcs11_p11kit.c | 290 ++++++++++++++++++++++++\n test/Makefile | 32 ++-\n test/data/token/softhsm.conf | 2 +\n test/test_crypt_pkcs11.c | 98 ++++++++\n 7 files changed, 429 insertions(+), 17 deletions(-)\n create mode 100644 crypto/swupdate_decrypt_pkcs11_p11kit.c\n create mode 100644 test/data/token/softhsm.conf\n create mode 100644 test/test_crypt_pkcs11.c", "diff": "diff --git a/Makefile.flags b/Makefile.flags\nindex 65f112e8..40dd3b66 100644\n--- a/Makefile.flags\n+++ b/Makefile.flags\n@@ -163,8 +163,6 @@ endif\n ifeq ($(CONFIG_SSL_IMPL_WOLFSSL),y)\n KBUILD_CPPFLAGS += -DOPENSSL_ALL\n LDLIBS += wolfssl\n-else ifeq ($(CONFIG_PKCS11),y)\n-LDLIBS += wolfssl\n endif\n \n ifeq ($(CONFIG_SSL_IMPL_MBEDTLS),y)\ndiff --git a/crypto/Kconfig b/crypto/Kconfig\nindex 4b9db821..48eeb01c 100644\n--- a/crypto/Kconfig\n+++ b/crypto/Kconfig\n@@ -21,6 +21,10 @@ menu \"Crypto libraries\"\n \tconfig SSL_IMPL_GPGME\n \t\tbool \"gpgme\"\n \t\tdepends on HAVE_GPGME\n+\n+\tconfig PKCS11\n+\t\tbool \"PKCS#11 (p11-kit)\"\n+\t\tdepends on HAVE_P11KIT\n endmenu\n \n config HASH_VERIFY\n@@ -82,9 +86,9 @@ menu \"Encryption\"\n \n config ENCRYPTED_IMAGES\n \tbool \"Images can be encrypted with a symmetric key\"\n-\tdepends on SSL_IMPL_OPENSSL || SSL_IMPL_WOLFSSL || SSL_IMPL_MBEDTLS\n+\tdepends on SSL_IMPL_OPENSSL || SSL_IMPL_WOLFSSL || SSL_IMPL_MBEDTLS || PKCS11\n comment \"Image encryption needs an SSL implementation\"\n-\tdepends on !SSL_IMPL_OPENSSL && !SSL_IMPL_WOLFSSL && !SSL_IMPL_MBEDTLS\n+\tdepends on !SSL_IMPL_OPENSSL && !SSL_IMPL_WOLFSSL && !SSL_IMPL_MBEDTLS && !PKCS11\n \n config ENCRYPTED_SW_DESCRIPTION\n \tbool \"Even sw-description is encrypted\"\n@@ -126,13 +130,5 @@ config ENCRYPTED_IMAGES_HARDEN_LOGGING\n \t hash mismatch and errors in the decryption finalization (padding) of a\n \t streamed image are suppressed.\n \n-config PKCS11\n-\tbool \"Enable PKCS#11 cryptographic operations\"\n-\tdefault n\n-\tdepends on SSL_IMPL_WOLFSSL && HAVE_P11KIT && ENCRYPTED_IMAGES\n-\thelp\n-\t Enable using PKCS#11 for AES decryption instead of having the plain\n-\t key available in a file. This is implemented with wolfSSL independent\n-\t from the SSL implementation and replaces the plain key method.\n endmenu\n \ndiff --git a/crypto/Makefile b/crypto/Makefile\nindex 25ab3ab7..b591ff57 100644\n--- a/crypto/Makefile\n+++ b/crypto/Makefile\n@@ -14,10 +14,8 @@ endif\n ifeq ($(CONFIG_SSL_IMPL_WOLFSSL),y)\n obj-$(CONFIG_HASH_VERIFY)\t+= swupdate_HASH_wolfssl.o\n obj-$(CONFIG_SIGALG_CMS)\t+= swupdate_pkcs7_verify_wolfssl.o\n-ifeq ($(CONFIG_PKCS11),y)\n obj-$(CONFIG_ENCRYPTED_IMAGES)\t+= swupdate_decrypt_wolfssl.o\n endif\n-endif\n \n ifeq ($(CONFIG_SSL_IMPL_MBEDTLS),y)\n obj-$(CONFIG_HASH_VERIFY)\t+= swupdate_HASH_mbedtls.o\n@@ -28,3 +26,7 @@ endif\n ifeq ($(CONFIG_SSL_IMPL_GPGME),y)\n obj-$(CONFIG_SIGALG_GPG)\t+= swupdate_gpg_verify.o\n endif\n+\n+ifeq ($(CONFIG_PKCS11),y)\n+obj-$(CONFIG_ENCRYPTED_IMAGES)\t+= swupdate_decrypt_pkcs11_p11kit.o\n+endif\ndiff --git a/crypto/swupdate_decrypt_pkcs11_p11kit.c b/crypto/swupdate_decrypt_pkcs11_p11kit.c\nnew file mode 100644\nindex 00000000..f66426bc\n--- /dev/null\n+++ b/crypto/swupdate_decrypt_pkcs11_p11kit.c\n@@ -0,0 +1,290 @@\n+// SPDX-FileCopyrightText: 2024 Matej Zachar\n+//\n+// SPDX-License-Identifier: GPL-2.0-only\n+/*\n+ * Inspired by the wolfssl implementation done by Bastian Germann\n+ */\n+\n+#include <errno.h>\n+#include <stdio.h>\n+#include <stdlib.h>\n+#include <string.h>\n+#include \"swupdate_crypto.h\"\n+#include \"swupdate_pkcs11.h\"\n+#include \"util.h\"\n+\n+static CK_SLOT_ID find_slot(CK_FUNCTION_LIST_PTR module, P11KitUri *uri)\n+{\n+\tCK_RV rv;\n+\n+\tCK_SLOT_ID slot_id = p11_kit_uri_get_slot_id(uri);\n+\tif (slot_id != (CK_SLOT_ID)-1)\n+\t\treturn slot_id;\n+\n+\tsize_t slot_count;\n+\trv = module->C_GetSlotList(1, NULL_PTR, &slot_count);\n+\tif (rv != CKR_OK)\n+\t\treturn (CK_SLOT_ID)-1;\n+\n+\tCK_SLOT_ID slot_ids[slot_count];\n+\trv = module->C_GetSlotList(1, &slot_ids[0], &slot_count);\n+\tif (rv != CKR_OK)\n+\t\treturn (CK_SLOT_ID)-1;\n+\n+\tCK_TOKEN_INFO token_info;\n+\tfor (int i = 0; i < slot_count; ++i) {\n+\t\tslot_id = slot_ids[i];\n+\n+\t\trv = module->C_GetTokenInfo(slot_id, &token_info);\n+\t\tif (rv != CKR_OK)\n+\t\t\treturn (CK_SLOT_ID)-1;\n+\n+\t\tif (p11_kit_uri_match_token_info(uri, &token_info))\n+\t\t\treturn slot_id;\n+\t}\n+\n+\treturn (CK_SLOT_ID)-1;\n+}\n+\n+static CK_RV find_key(CK_FUNCTION_LIST_PTR module, CK_SESSION_HANDLE session,\n+\tCK_ATTRIBUTE_PTR key_id, CK_OBJECT_HANDLE *key_handle)\n+{\n+\tCK_RV rv;\n+\n+\tCK_ATTRIBUTE find_template[] = {\n+\t\t{ CKA_ID, key_id->pValue, key_id->ulValueLen }\n+\t};\n+\n+\trv = module->C_FindObjectsInit(session, find_template, 1);\n+\tif (rv != CKR_OK) {\n+\t\treturn rv;\n+\t}\n+\n+\tCK_ULONG object_count;\n+\trv = module->C_FindObjects(session, key_handle, 1, &object_count);\n+\tif (rv != CKR_OK) {\n+\t\treturn rv;\n+\t}\n+\n+\trv = module->C_FindObjectsFinal(session);\n+\tif (rv != CKR_OK) {\n+\t\treturn rv;\n+\t}\n+\n+\tif (object_count == 0) {\n+\t\treturn CKR_DATA_INVALID;\n+\t}\n+\n+\treturn CKR_OK;\n+}\n+\n+struct pkcs11_digest *pkcs11_DECRYPT_init(unsigned char *uri,\n+\tchar __attribute__ ((__unused__)) keylen, unsigned char *iv, cipher_t cipher)\n+{\n+\tstruct pkcs11_digest *dgst;\n+\tCK_SLOT_ID slot_id;\n+\tCK_ATTRIBUTE_PTR key_id;\n+\tconst char *pin;\n+\tconst char *module_path;\n+\tconst char *msg;\n+\tint err = 0;\n+\tCK_RV rv;\n+\n+\tif (uri == NULL || iv == NULL) {\n+\t\tERROR(\"PKCS#11 URI or AES IV missing for decryption!\");\n+\t\treturn NULL;\n+\t}\n+\n+\tdgst = calloc(1, sizeof(*dgst));\n+\tif (!dgst) {\n+\t\treturn NULL;\n+\t}\n+\n+\tdgst->uri = p11_kit_uri_new();\n+\terr = p11_kit_uri_parse((const char*)uri, P11_KIT_URI_FOR_OBJECT_ON_TOKEN_AND_MODULE, dgst->uri);\n+\tif (err) {\n+\t\tmsg = p11_kit_uri_message(err);\n+\t\tERROR(\"PKCS#11 URI: %s\", msg);\n+\t\tgoto free_digest;\n+\t}\n+\n+\tkey_id\t= p11_kit_uri_get_attribute(dgst->uri, CKA_ID);\n+\tpin\t= p11_kit_uri_get_pin_value(dgst->uri);\n+\tmodule_path = p11_kit_uri_get_module_path(dgst->uri);\n+\tif (key_id == NULL || pin == NULL || module_path == NULL) {\n+\t\tERROR(\"PKCS#11 URI must contain id, pin-value and module-path.\");\n+\t\tgoto free_digest;\n+\t}\n+\n+\tdgst->module = p11_kit_module_load(module_path, 0);\n+\tif (dgst->module == NULL) {\n+\t\tmsg = p11_kit_message();\n+\t\tERROR(\"Failed to load PKCS#11 module [%s]: %s\\n\", module_path, msg);\n+\t\tgoto free_digest;\n+\t}\n+\n+\trv = dgst->module->C_Initialize(NULL_PTR);\n+\tif (rv != CKR_OK)\n+\t\tgoto err_msg;\n+\n+\tslot_id = find_slot(dgst->module, dgst->uri);\n+\tif (slot_id == -1) {\n+\t\tERROR(\"PKCS#11 URI must contain slot-id or token identification such as token, model, serial, manufacturer.\");\n+\t\tgoto free_digest;\n+\t}\n+\n+\trv = dgst->module->C_OpenSession(slot_id, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &dgst->session);\n+\tif (rv != CKR_OK)\n+\t\tgoto err_msg;\n+\n+\trv = dgst->module->C_Login(dgst->session, CKU_USER, (unsigned char *)pin, strnlen(pin, 32));\n+\tif (rv != CKR_OK)\n+\t\tgoto err_msg;\n+\n+\tCK_OBJECT_HANDLE key;\n+\trv = find_key(dgst->module, dgst->session, key_id, &key);\n+\tif (rv != CKR_OK)\n+\t\tgoto err_msg;\n+\n+\t// Setup a valid PKCS#7 block plus one state octet\n+\tfor (int i = 0; i <= AES_BLK_SIZE; ++i) {\n+\t\tdgst->last[i] = AES_BLK_SIZE;\n+\t}\n+\n+\t// Setup IV vector & mechanism\n+\tmemcpy(dgst->iv, iv, AES_BLK_SIZE);\n+\tdgst->mechanism.mechanism = CKM_AES_CBC;\n+\tdgst->mechanism.pParameter = dgst->iv;\n+\tdgst->mechanism.ulParameterLen = AES_BLK_SIZE;\n+\n+\trv = dgst->module->C_DecryptInit(dgst->session, &dgst->mechanism, key);\n+\tif (rv != CKR_OK)\n+\t\tgoto err_msg;\n+\n+\tINFO(\"PKCS#11 key set up successfully.\");\n+\treturn dgst;\n+\n+err_msg:\n+\tmsg = p11_kit_strerror(rv);\n+\tERROR(\"PKCS#11 initialization failed: %s\", msg);\n+\n+free_digest:\n+\tif (dgst->uri)\n+\t\tp11_kit_uri_free(dgst->uri);\n+\n+\tif (dgst->session)\n+\t\tdgst->module->C_CloseSession(dgst->session);\n+\n+\tif (dgst->module) {\n+\t\tdgst->module->C_Finalize(NULL_PTR);\n+\t\tp11_kit_module_release(dgst->module);\n+\t}\n+\n+\tfree(dgst);\n+\n+\treturn NULL;\n+}\n+\n+int pkcs11_DECRYPT_update(struct pkcs11_digest *dgst, unsigned char *buf,\n+\tint *outlen, const unsigned char *cryptbuf, int inlen)\n+{\n+\t// precondition: len(buf) >= inlen + AES_BLK_SIZE\n+\tunsigned long buf_len = inlen + AES_BLK_SIZE;\n+\tCK_RV rv;\n+\n+\tif (inlen < AES_BLK_SIZE)\n+\t\treturn -EFAULT;\n+\n+\tif (dgst->last[AES_BLK_SIZE]) {\n+\t\tdgst->last[AES_BLK_SIZE] = 0;\n+\t\t// first run - there is no block to append\n+\t\t*outlen = 0;\n+\t} else {\n+\t\t// append previously decrypted last AES block\n+\t\tmemcpy(buf, dgst->last, AES_BLK_SIZE);\n+\t\tbuf += AES_BLK_SIZE;\n+\t\t*outlen = AES_BLK_SIZE;\n+\t}\n+\n+\trv = dgst->module->C_DecryptUpdate(dgst->session, (unsigned char*)cryptbuf, inlen, buf, &buf_len);\n+\tif (rv != CKR_OK) {\n+\t\tERROR(\"PKCS#11 AES decryption failed: %s\", p11_kit_strerror(rv));\n+\t\treturn -EFAULT;\n+\t}\n+\n+\t// strip and remember last AES block from decoded buffer\n+\t// it will get appended either in the next call to DECRYPT_update or DECRYPT_final\n+\tbuf_len -= AES_BLK_SIZE;\n+\tmemcpy(dgst->last, &buf[buf_len], AES_BLK_SIZE);\n+\n+\t// update iv for the next block\n+\tmemcpy(dgst->iv, cryptbuf + inlen - AES_BLK_SIZE, AES_BLK_SIZE);\n+\n+\t*outlen += (int)buf_len;\n+\treturn 0;\n+}\n+\n+int pkcs11_DECRYPT_final(struct pkcs11_digest *dgst, unsigned char *buf, int *outlen)\n+{\n+\tCK_RV rv;\n+\tunsigned long extra_len = 0;\n+\n+\tif (dgst->last[AES_BLK_SIZE]) {\n+#ifndef CONFIG_ENCRYPTED_IMAGES_HARDEN_LOGGING\n+\t\tERROR(\"AES: At least one call to pkcs11_DECRYPT_update was expected\");\n+#endif\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t// append previously decrypted last AES block if any\n+\tmemcpy(buf, dgst->last, AES_BLK_SIZE);\n+\n+\trv = dgst->module->C_DecryptFinal(dgst->session, &buf[AES_BLK_SIZE], &extra_len);\n+\tif (rv != CKR_OK)\n+\t\treturn -EFAULT;\n+\n+\t// obtain last AES block after C_DecryptFinal\n+\tCK_BYTE_PTR last = &buf[extra_len];\n+\n+\t// Handle manual PKCS#7 padding removal\n+\tCK_BYTE padding_value = last[AES_BLK_SIZE - 1];\n+\n+\tif (padding_value <= 0 || padding_value > AES_BLK_SIZE) {\n+#ifndef CONFIG_ENCRYPTED_IMAGES_HARDEN_LOGGING\n+\t\tERROR(\"AES: Invalid PKCS#7 padding value [%u]\", padding_value);\n+#endif\n+\t\treturn -EFAULT;\n+\t}\n+\n+\t// Verify that padding is correct\n+\tfor (CK_BYTE i = 0; i < padding_value; ++i) {\n+\t\tif (last[AES_BLK_SIZE - 1 - i] != padding_value) {\n+#ifndef CONFIG_ENCRYPTED_IMAGES_HARDEN_LOGGING\n+\t\t\tERROR(\"AES: Invalid PKCS#7 padding value [%u] at offset %u\", padding_value, i);\n+#endif\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\n+\t*outlen = (int)extra_len + AES_BLK_SIZE - padding_value;\n+\treturn 0;\n+}\n+\n+void pkcs11_DECRYPT_cleanup(struct pkcs11_digest *dgst)\n+{\n+\tif (dgst) {\n+\t\tif (dgst->uri)\n+\t\t\tp11_kit_uri_free(dgst->uri);\n+\n+\t\tif (dgst->session)\n+\t\t\tdgst->module->C_CloseSession(dgst->session);\n+\n+\t\tif (dgst->module) {\n+\t\t\tdgst->module->C_Finalize(NULL_PTR);\n+\t\t\tp11_kit_module_release(dgst->module);\n+\t\t}\n+\n+\t\tfree(dgst);\n+\t\tdgst = NULL;\n+\t}\n+}\ndiff --git a/test/Makefile b/test/Makefile\nindex 385efd85..8bdf50d6 100644\n--- a/test/Makefile\n+++ b/test/Makefile\n@@ -17,9 +17,10 @@\n ## along with this program; if not, write to the Free Software\n ## Foundation, Inc.\n \n-ifneq ($(CONFIG_PKCS11),y)\n-tests-$(CONFIG_ENCRYPTED_IMAGES) += test_crypt\n+ifeq ($(CONFIG_PKCS11),y)\n+tests-$(CONFIG_ENCRYPTED_IMAGES) += test_crypt_pkcs11\n endif\n+tests-$(CONFIG_ENCRYPTED_IMAGES) += test_crypt\n tests-$(CONFIG_HASH_VERIFY) += test_hash\n ifeq ($(CONFIG_SIGALG_RAWRSA),y)\n tests-$(CONFIG_SIGNED_IMAGES) += test_verify\n@@ -66,7 +67,7 @@ quiet_cmd_linktestexe = LD $(basename $@)\n \t\t\t\t\t\t\"$(SWLIBS)\" \\\n \t\t\t\t\t\t\"$(LDLIBS) cmocka\"\n \n-EXECUTE_TEST = echo \"RUN $(subst $(obj)/,,$(var))\"; LD_LIBRARY_PATH=$(objtree) CMOCKA_MESSAGE_OUTPUT=TAP $(var)\n+EXECUTE_TEST = echo \"RUN $(subst $(obj)/,,$(var))\"; LD_LIBRARY_PATH=$(objtree) CMOCKA_MESSAGE_OUTPUT=TAP SOFTHSM2_CONF=$(DATADIR)/token/softhsm.conf $(var)\n \n PHONY += default\n default:\n@@ -111,4 +112,29 @@ $(DATADIR)/signing-secret.pem:\n \t$(if $(Q),@echo \" GEN $@\")\n \t$(Q)openssl genrsa -out $@ 2>/dev/null\n \n+ifeq ($(CONFIG_PKCS11),y)\n+$(obj)/test_crypt_pkcs11.o: $(DATADIR)/softshm\n+\n+TOKEN_AES_KEY := dd020ce5ebd5c468556288d6a75169c88a5b335d9f569e30751c50401467d230\n+TOKEN_AES_IV := c1f390d21dd06118cbd333144a3318ca\n+\n+.INTERMEDIATE: $(DATADIR)/softshm\n+$(DATADIR)/softshm: export SOFTHSM2_CONF=$(DATADIR)/token/softhsm.conf\n+$(DATADIR)/softshm: $(DATADIR)/token/softhsm.conf\n+\t$(if $(Q),@echo \" INIT $@\")\n+\t$(Q)rm -rf $(DATADIR)/token/*/\n+\n+\t$(if $(Q),@echo \" GEN $(DATADIR)/token/original.data\")\n+\t$(Q)openssl rand 131075 > $(DATADIR)/token/original.data\n+\n+\t$(if $(Q),@echo \" ENCRYPT $(DATADIR)/token/original.data\")\n+\t$(Q)openssl enc -aes-256-cbc -in $(DATADIR)/token/original.data -out $(DATADIR)/token/encrypted.data -K $(TOKEN_AES_KEY) -iv $(TOKEN_AES_IV)\n+\t$(Q)echo -n \"$(TOKEN_AES_IV)\" | xxd -p -r > $(DATADIR)/token/encrypted.data.iv\n+\n+\t$(if $(Q),@echo \" IMPORT $(DATADIR)/token/aes.key\")\n+\t$(Q)echo -n \"$(TOKEN_AES_KEY)\" | xxd -p -r > $(DATADIR)/token/aes.key\n+\t$(Q)softhsm2-util --init-token --slot 0 --label \"TestToken\" --so-pin 123456 --pin 1234\n+\t$(Q)softhsm2-util --import $(DATADIR)/token/aes.key --aes --token \"TestToken\" --label \"AES key\" --id A1B2 --pin 1234\n+endif\n+\n .PHONY: $(PHONY)\ndiff --git a/test/data/token/softhsm.conf b/test/data/token/softhsm.conf\nnew file mode 100644\nindex 00000000..bd43fe45\n--- /dev/null\n+++ b/test/data/token/softhsm.conf\n@@ -0,0 +1,2 @@\n+directories.tokendir = test/data/token\n+objectstore.backend = file\n\\ No newline at end of file\ndiff --git a/test/test_crypt_pkcs11.c b/test/test_crypt_pkcs11.c\nnew file mode 100644\nindex 00000000..94ed92a8\n--- /dev/null\n+++ b/test/test_crypt_pkcs11.c\n@@ -0,0 +1,98 @@\n+// SPDX-FileCopyrightText: 2024 Matej Zachar\n+//\n+// SPDX-License-Identifier: GPL-2.0-only\n+\n+#include <stdlib.h>\n+#include <stdio.h>\n+#include <stdarg.h>\n+#include <stddef.h>\n+#include <setjmp.h>\n+#include <cmocka.h>\n+#include <util.h>\n+#include \"swupdate_crypto.h\"\n+\n+#define BUFFER_SIZE (AES_BLK_SIZE * 1024)\n+#define TOKENDIR \"test/data/token\"\n+\n+static int read_file(const char *path, unsigned char *buffer, size_t *size)\n+{\n+\tFILE *fp = fopen(path, \"r\");\n+\tif (!fp) {\n+\t\tfprintf(stderr, \"Failed to open file '%s'\\n\", path);\n+\t\treturn -1;\n+\t}\n+\n+\tsize_t len = fread(buffer, sizeof(char), *size, fp);\n+\tif (ferror(fp) != 0) {\n+\t\tfprintf(stderr, \"Error reading file '%s'\\n\", path);\n+\t\tfclose(fp);\n+\t\treturn -1;\n+\t}\n+\n+\t*size = len;\n+\tfclose(fp);\n+\n+\treturn 0;\n+}\n+\n+static void test_crypt_pkcs11_256(void **state)\n+{\n+\t(void) state;\n+\tint err;\n+\n+\tconst char * uri = \"pkcs11:token=TestToken;id=%A1%B2?pin-value=1234&module-path=/usr/lib/softhsm/libsofthsm2.so\";\n+\n+\tsize_t original_data_len = 128 * 1024;/* 128KiB */\n+\tunsigned char original_data[original_data_len];\n+\terr = read_file(TOKENDIR \"/original.data\", &original_data[0], &original_data_len);\n+\tassert_true(err == 0);\n+\n+\tsize_t encrypted_data_len = 128 * 1024 + AES_BLK_SIZE;/* 128KiB AES_BLK_SIZE(16B) */\n+\tunsigned char encrypted_data[encrypted_data_len];\n+\terr = read_file(TOKENDIR \"/encrypted.data\", &encrypted_data[0], &encrypted_data_len);\n+\tassert_true(err == 0);\n+\n+\tunsigned char decrypted_data[encrypted_data_len];\n+\n+\tsize_t iv_size = 16;\n+\tunsigned char iv[iv_size];\n+\terr = read_file(TOKENDIR \"/encrypted.data.iv\", &iv[0], &iv_size);\n+\tassert_true(err == 0);\n+\n+\tunsigned char buffer[BUFFER_SIZE + AES_BLK_SIZE];\n+\n+\tstruct swupdate_digest *dgst = swupdate_DECRYPT_init((unsigned char *)uri, 0, &iv[0], AES_CBC_256);\n+\tassert_non_null(dgst);\n+\n+\tint len;\n+\tsize_t e_offset = 0;\n+\tsize_t d_offset = 0;\n+\twhile (e_offset < encrypted_data_len) {\n+\t\tsize_t chunk_size = (encrypted_data_len - e_offset > BUFFER_SIZE) ? BUFFER_SIZE : encrypted_data_len - e_offset;\n+\n+\t\terr = swupdate_DECRYPT_update(dgst, buffer, &len, encrypted_data + e_offset, chunk_size);\n+\t\tassert_true(err == 0);\n+\t\tassert_true(len >= AES_BLK_SIZE && len <= chunk_size);\n+\t\te_offset += chunk_size;\n+\n+\t\tmemcpy(&decrypted_data[d_offset], buffer, len);\n+\t\td_offset += len;\n+\t}\n+\n+\terr = swupdate_DECRYPT_final(dgst, buffer, &len);\n+\tassert_true(err == 0);\n+\tassert_true(len == 3); /* as the size is 128*1024+3 */\n+\n+\tmemcpy(&decrypted_data[d_offset], buffer, len);\n+\td_offset += len;\n+\n+\tassert_true(strncmp((const char *)decrypted_data, (const char *)original_data, original_data_len) == 0);\n+}\n+\n+int main(void)\n+{\n+\tconst struct CMUnitTest crypt_pkcs11_tests[] = {\n+\t\tcmocka_unit_test(test_crypt_pkcs11_256)\n+\t};\n+\treturn cmocka_run_group_tests_name(\"crypt_pkcs11\", crypt_pkcs11_tests, NULL, NULL);\n+}\n", "prefixes": [ "2/5" ] }