{"id":2225947,"url":"http://patchwork.ozlabs.org/api/patches/2225947/?format=json","web_url":"http://patchwork.ozlabs.org/project/uboot/patch/20260421210954.1170437-2-philippe.reynes@softathome.com/","project":{"id":18,"url":"http://patchwork.ozlabs.org/api/projects/18/?format=json","name":"U-Boot","link_name":"uboot","list_id":"u-boot.lists.denx.de","list_email":"u-boot@lists.denx.de","web_url":null,"scm_url":null,"webscm_url":null,"list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<20260421210954.1170437-2-philippe.reynes@softathome.com>","list_archive_url":null,"date":"2026-04-21T21:09:40","name":"[v5,01/15] ecdsa: fix support of secp521r1","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"e02ea6ffc68838c4904fdb3fc372b680188bd7cc","submitter":{"id":74351,"url":"http://patchwork.ozlabs.org/api/people/74351/?format=json","name":"Philippe Reynes","email":"philippe.reynes@softathome.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/uboot/patch/20260421210954.1170437-2-philippe.reynes@softathome.com/mbox/","series":[{"id":500895,"url":"http://patchwork.ozlabs.org/api/series/500895/?format=json","web_url":"http://patchwork.ozlabs.org/project/uboot/list/?series=500895","date":"2026-04-21T21:09:51","name":"add software ecdsa support","version":5,"mbox":"http://patchwork.ozlabs.org/series/500895/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2225947/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2225947/checks/","tags":{},"related":[],"headers":{"Return-Path":"<u-boot-bounces@lists.denx.de>","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=softathome1.onmicrosoft.com header.i=@softathome1.onmicrosoft.com\n header.a=rsa-sha256 header.s=selector1-softathome1-onmicrosoft-com\n header.b=m2GACnT8;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de\n (client-ip=85.214.62.61; helo=phobos.denx.de;\n envelope-from=u-boot-bounces@lists.denx.de; receiver=patchwork.ozlabs.org)","phobos.denx.de;\n dmarc=none (p=none dis=none) header.from=softathome.com","phobos.denx.de;\n spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de","phobos.denx.de;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=softathome1.onmicrosoft.com header.i=@softathome1.onmicrosoft.com\n header.b=\"m2GACnT8\";\n\tdkim-atps=neutral","phobos.denx.de; dmarc=none (p=none dis=none)\n header.from=softathome.com","phobos.denx.de;\n spf=pass smtp.mailfrom=philippe.reynes@softathome.com"],"Received":["from phobos.denx.de (phobos.denx.de [85.214.62.61])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g0Zkp2DBQz1yGs\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 22 Apr 2026 07:10:26 +1000 (AEST)","from h2850616.stratoserver.net (localhost [IPv6:::1])\n\tby phobos.denx.de (Postfix) with ESMTP id EE309842FC;\n\tTue, 21 Apr 2026 23:10:10 +0200 (CEST)","by phobos.denx.de (Postfix, from userid 109)\n id 16550842FC; Tue, 21 Apr 2026 23:10:09 +0200 (CEST)","from MRZP264CU002.outbound.protection.outlook.com\n (mail-francesouthazlp170100001.outbound.protection.outlook.com\n [IPv6:2a01:111:f403:c207::1])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))\n (No client certificate requested)\n by phobos.denx.de (Postfix) with ESMTPS id E9E4D8419C\n for <u-boot@lists.denx.de>; Tue, 21 Apr 2026 23:10:01 +0200 (CEST)","from PA7P264CA0357.FRAP264.PROD.OUTLOOK.COM (2603:10a6:102:37c::22)\n by MRZP264MB3130.FRAP264.PROD.OUTLOOK.COM (2603:10a6:501:1b::21) with\n Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9846.18; Tue, 21 Apr\n 2026 21:09:57 +0000","from PA1PEPF000CC3FB.FRAP264.PROD.OUTLOOK.COM\n (2603:10a6:102:37c:cafe::89) by PA7P264CA0357.outlook.office365.com\n (2603:10a6:102:37c::22) with Microsoft SMTP Server (version=TLS1_3,\n cipher=TLS_AES_256_GCM_SHA384) id 15.20.9791.48 via Frontend Transport; Tue,\n 21 Apr 2026 21:09:57 +0000","from proxy.softathome.com (149.6.166.170) by\n PA1PEPF000CC3FB.mail.protection.outlook.com (10.167.242.6) with Microsoft\n SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9846.18\n via Frontend Transport; Tue, 21 Apr 2026 21:09:56 +0000","from sah1lpt726.softathome.com (unknown [192.168.72.32])\n by proxy.softathome.com (Postfix) with ESMTPSA id BD06C20737;\n Tue, 21 Apr 2026 23:09:56 +0200 (CEST)"],"X-Spam-Checker-Version":"SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de","X-Spam-Level":"","X-Spam-Status":"No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED,\n DKIM_VALID,RCVD_IN_DNSWL_BLOCKED,SPF_HELO_PASS,SPF_PASS autolearn=ham\n autolearn_force=no version=3.4.2","ARC-Seal":"i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none;\n b=Wp5ks2N0IyhU0NMKKLMTlCMtri5j7QnHaikSnFmoKd/fm2acGkmQDZrkFbUK3EkG7S4DO4tLjmuzNQZAfYVQLHMPp4o9yDZLmjQUJ6TO5oH8EakISBoRJrUIERLE2HPDqNP+wSo+NKF3rPup+swLpvTr/iP+z/WY37RmPc9yQRjboIk0CP2wRZ72MGwSVNjkZLJC6RWyg21c6DmOdPEpN8gDjR20jWZezaOzq7bRvSvEG82iW6d/5FK/0Dfk4XVMZ0VEwqS45CmQ9WgFEq/WpYVYP8dht16bDaFfpVqr9fhFxQXfY0rk+fNyYSGsjxkv4DjSXLixobIk8GxqNs/HbA==","ARC-Message-Signature":"i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;\n s=arcselector10001;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1;\n bh=PvTJku6PMIRbxkq4cbaXX+4C09UoHKoAWQrp9fCXYxc=;\n b=TS33DcpIdVIMGzWHpcvy5jBmGAJrDOunUgZMahhHbHb4oFggIQ5JQx4CH+IrcC7QFzvab+2rl22UbexyNn2gbOF+JquqQidrTg9YJH60gsStMrr/Slr1Sgtid3Yz2ihITK4z+aAvBQOgQkaNMhbEa75+t8PRk/iq1swXHuldOhATgkveONRjhspN+Azzw6ndtOZBlVidLpzOalBSIep/hW2Q9XvYQ2BnwlCN8cxCGDtNKCyXr2acNAP1cvg3PEievvjxSBc0Op/4fcmr+av7TMiD29rox3H14TrsubHxW7diOf1kD6Nfqm7sFh72QTkDat28crZ6wbweHT20A0azsg==","ARC-Authentication-Results":"i=1; mx.microsoft.com 1; spf=pass (sender ip is\n 149.6.166.170) smtp.rcpttodomain=canonical.com smtp.mailfrom=softathome.com;\n dmarc=bestguesspass action=none header.from=softathome.com; dkim=none\n (message not signed); arc=none (0)","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=softathome1.onmicrosoft.com; s=selector1-softathome1-onmicrosoft-com;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n bh=PvTJku6PMIRbxkq4cbaXX+4C09UoHKoAWQrp9fCXYxc=;\n b=m2GACnT8QYKqYbYAb0Th/DKmziWERco+4X5q9XCCz7AOhfwhA9vIKpsuUB3EhnrhsHiXWNHNRNCXnPrF558dRri1XzpAVFJO9rW2iVwVsKtylPYQutgbJX46VqHqrW2Mnr16BnzHVr7nXrFPE4Ykhw9tUQddseORAt8PKj2c5R2Iky7qtpSuBRmnD3/Y4px1aP9OfYHF+bCqtHZjydW+2Ma6rRT+TgJvzlvCE9tTEYoHpuUbxFtu03QHvHD3VXT654YufB4+FQwkulmiqO/2NDVK3QN8I0+NHuolApQ1wBwdJt387ZpvLat7K163QXl7kbl1NojD4b8q+i+M7wpc2Q==","X-MS-Exchange-Authentication-Results":"spf=pass (sender IP is 149.6.166.170)\n smtp.mailfrom=softathome.com; dkim=none (message not signed)\n header.d=none;dmarc=bestguesspass action=none header.from=softathome.com;","Received-SPF":"Pass (protection.outlook.com: domain of softathome.com\n designates 149.6.166.170 as permitted sender)\n receiver=protection.outlook.com; client-ip=149.6.166.170;\n helo=proxy.softathome.com; pr=C","From":"Philippe Reynes <philippe.reynes@softathome.com>","To":"marko.makela@iki.fi, jonny.green@keytechinc.com, raymondmaoca@gmail.com,\n trini@konsulko.com, simon.glass@canonical.com","Cc":"u-boot@lists.denx.de,\n\tPhilippe Reynes <philippe.reynes@softathome.com>","Subject":"[PATCH v5 01/15] ecdsa: fix support of secp521r1","Date":"Tue, 21 Apr 2026 23:09:40 +0200","Message-ID":"<20260421210954.1170437-2-philippe.reynes@softathome.com>","X-Mailer":"git-send-email 2.43.0","In-Reply-To":"<20260421210954.1170437-1-philippe.reynes@softathome.com>","References":"<20260421210954.1170437-1-philippe.reynes@softathome.com>","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit","X-EOPAttributedMessage":"0","X-MS-PublicTrafficType":"Email","X-MS-TrafficTypeDiagnostic":"PA1PEPF000CC3FB:EE_|MRZP264MB3130:EE_","Content-Type":"text/plain","X-MS-Office365-Filtering-Correlation-Id":"e618216d-1d1f-446c-4a75-08de9fea5759","X-MS-Exchange-SenderADCheck":"1","X-MS-Exchange-AntiSpam-Relay":"0","X-Microsoft-Antispam":"BCL:0;\n ARA:13230040|82310400026|36860700016|1800799024|376014|18002099003|22082099003|56012099003;","X-Microsoft-Antispam-Message-Info":"\n C1UG7eCTDz4/kcBfFKExzpYAZnzjbL8/+dOilsRRWtywg6nYwRE4b4RKOcxCPTgDu/hxbSapBs/04yVVAnsErxjtYKfm6dFDjpGNYMTVuXzuqhjRI/bKPTgzhrMSUH1ewG/0uDT8qsF10tY36PUrHQcyrxn1Lp9NZtH25DaNeqQGPZ6SazaO4nHjSgI3eevAcbF25fXyh/SZDbpwtK8zvxwbSey6T1JKSkyLMDupp8yOBwF8VBeVYe+T/E8zWm93FmwUxNDvZMvfz28/ZJH16JngIgSbVibUfN3ZoMO2+EMikzgnw+oillbJI4Xr5mSvUyAp5gUQOxjWLM+DzIbbdXeB4iPbeV3Uh0vALUEfZMhPpvpae+oKsw77WECuPVoehRTHELdLkNqA0kMvz+JL5pgC5+1eIaOxStEIZy128J/DJZ4fk1FzihNCi1iSDljsyNYnFLRItLy2VihCwhR24Wy9+NicaS5z3HGLr1bPGr4bJG2XeCldwtF+v7hE0VMUoMwsY8qKGFgzUzxCYm2HRvSd2B0QbqZfIuoESrRIArl/jk3Py8TRQUUJ1ANSMb0lo6exen5tpxn3cN2mixyTd97MzXN7+9FZsj/z/bzE+Df5HGp4T2aiJ9gao/Y2y3laVKlLQfUG3vE3UPihP7LzbxorjGUCCF7xVPEaXnFGR6kt8d7sXpREcowxOtq8sjsCU3/EiS7Ijuyp5p/0ThmuMt0GcRXDHNX4LqAdU2N+JbPbOJVxxk0eSDIWcR8O/b0axVvOM97nFtBinJxnxeIx3w==","X-Forefront-Antispam-Report":"CIP:149.6.166.170; CTRY:FR; LANG:en; SCL:1; SRV:;\n IPV:CAL; SFV:NSPM; H:proxy.softathome.com; PTR:InfoDomainNonexistent;\n CAT:NONE;\n SFS:(13230040)(82310400026)(36860700016)(1800799024)(376014)(18002099003)(22082099003)(56012099003);\n DIR:OUT; SFP:1101;","X-MS-Exchange-AntiSpam-MessageData-ChunkCount":"1","X-MS-Exchange-AntiSpam-MessageData-0":"\n GEtUzWdo6CQ/3vDebMRy7cMnmaBpmrZcjRbybX1F+K0iV5nxT6kHYSell6VOcTs+Y95VYXQ0oa4uH+niGdzXcr1iz9rHKd/tLvQvsMvIF6/AMGg8ni4sUZdOcjBU2O0MmLLDpNE5cFJOkswGFgHuoNgsVtmS7fvHRJP9AKwls5GO3lEdTGxWPCF2WPfxr/p3OoVAo9/Y9JKu+EX1it9bPzXxXYi86pjH6wU9J7RvPxobo31WLIbCVbQNV0/q9u83LDnE/imouc+gHpZHEagctNGCx3WwTaGiYXrpysU38cNYAzUgv4swbKF6dcve0fcfA4lVRyE8B4h2l6W5Ynk90xSmuQ6qO/t9HN/CD/tG5yj/bAfCvsU8EXh9iHGbJjYMAFgtLMk3rg6Xt5sz0ZBwmW6Xze1FVkGHgQQ9W3K4Yraw2oprCwpF1fhWEN0xpaD0","X-OriginatorOrg":"softathome.com","X-MS-Exchange-CrossTenant-OriginalArrivalTime":"21 Apr 2026 21:09:56.9294 (UTC)","X-MS-Exchange-CrossTenant-Network-Message-Id":"\n e618216d-1d1f-446c-4a75-08de9fea5759","X-MS-Exchange-CrossTenant-Id":"aa10e044-e405-4c10-8353-36b4d0cce511","X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp":"\n TenantId=aa10e044-e405-4c10-8353-36b4d0cce511; Ip=[149.6.166.170];\n Helo=[proxy.softathome.com]","X-MS-Exchange-CrossTenant-AuthSource":"PA1PEPF000CC3FB.FRAP264.PROD.OUTLOOK.COM","X-MS-Exchange-CrossTenant-AuthAs":"Anonymous","X-MS-Exchange-CrossTenant-FromEntityHeader":"HybridOnPrem","X-MS-Exchange-Transport-CrossTenantHeadersStamped":"MRZP264MB3130","X-BeenThere":"u-boot@lists.denx.de","X-Mailman-Version":"2.1.39","Precedence":"list","List-Id":"U-Boot discussion <u-boot.lists.denx.de>","List-Unsubscribe":"<https://lists.denx.de/options/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=unsubscribe>","List-Archive":"<https://lists.denx.de/pipermail/u-boot/>","List-Post":"<mailto:u-boot@lists.denx.de>","List-Help":"<mailto:u-boot-request@lists.denx.de?subject=help>","List-Subscribe":"<https://lists.denx.de/listinfo/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=subscribe>","Errors-To":"u-boot-bounces@lists.denx.de","Sender":"\"U-Boot\" <u-boot-bounces@lists.denx.de>","X-Virus-Scanned":"clamav-milter 0.103.8 at phobos.denx.de","X-Virus-Status":"Clean"},"content":"Current implementation of ecdsa only supports key len aligned on\n8 bits. But the curve secp521r1 uses a key of 521 bits which is not\naligned on 8 bits. In this commit, we update the keys management\nfor ecdsa to support keys that are not aligned on 8 bits.\n\nSigned-off-by: Philippe Reynes <philippe.reynes@softathome.com>\n---\nv2:\n- intitial version\nv3:\n- fix typo in comments\nv4:\n- fix commit message\n- clean code with DIV_ROUND_UP-\n- duplicate data before shifting\n- support ecdsa521 and secp521r1\n- clean code\nv5:\n- check that x and y are not null before using them\n- free keys when keys not found\n\n lib/ecdsa/ecdsa-libcrypto.c | 63 ++++++++++++++++++++++++++++++-\n lib/ecdsa/ecdsa-verify.c    | 75 +++++++++++++++++++++++++++++++++----\n lib/fdt-libcrypto.c         |  2 +-\n tools/image-sig-host.c      |  7 ++++\n 4 files changed, 137 insertions(+), 10 deletions(-)","diff":"diff --git a/lib/ecdsa/ecdsa-libcrypto.c b/lib/ecdsa/ecdsa-libcrypto.c\nindex c4bfb2cec61..41590d22a51 100644\n--- a/lib/ecdsa/ecdsa-libcrypto.c\n+++ b/lib/ecdsa/ecdsa-libcrypto.c\n@@ -26,6 +26,8 @@\n #include <openssl/ec.h>\n #include <openssl/bn.h>\n \n+#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))\n+\n /* Image signing context for openssl-libcrypto */\n struct signer {\n \tEVP_PKEY *evp_key;\t/* Pointer to EVP_PKEY object */\n@@ -41,10 +43,26 @@ struct ecdsa_public_key {\n \tint size_bits;\n };\n \n+static char *memdup(char *buf, size_t size)\n+{\n+\tchar *dup;\n+\n+\tdup = malloc(size);\n+\tif (dup)\n+\t\tmemcpy(dup, buf, size);\n+\n+\treturn dup;\n+}\n+\n static int fdt_get_key(struct ecdsa_public_key *key, const void *fdt, int node)\n {\n+\tconst char *x;\n+\tconst char *y;\n \tint x_len;\n \tint y_len;\n+\tint expected_len;\n+\n+\tmemset(key, 0, sizeof(*key));\n \n \tkey->curve_name = fdt_getprop(fdt, node, \"ecdsa,curve\", NULL);\n \tif (!key->curve_name)\n@@ -54,6 +72,8 @@ static int fdt_get_key(struct ecdsa_public_key *key, const void *fdt, int node)\n \t\tkey->size_bits = 256;\n \telse if (!strcmp(key->curve_name, \"secp384r1\"))\n \t\tkey->size_bits = 384;\n+\telse if (!strcmp(key->curve_name, \"secp521r1\"))\n+\t\tkey->size_bits = 521;\n \telse\n \t\treturn -EINVAL;\n \n@@ -63,12 +83,43 @@ static int fdt_get_key(struct ecdsa_public_key *key, const void *fdt, int node)\n \tif (!key->x || !key->y)\n \t\treturn -EINVAL;\n \n-\tif (x_len != key->size_bits / 8 || y_len != key->size_bits / 8)\n+\t/*\n+\t * The public key is stored as an array of u32, so if the key size is\n+\t * not a multiple of 32 (for example 521), we may have extra bytes.\n+\t * To avoid any issue later, we shift the x and y pointer to the first\n+\t * useful byte.\n+\t */\n+\texpected_len = DIV_ROUND_UP(key->size_bits, 8);\n+\n+\tif (x_len < expected_len || y_len < expected_len)\n \t\treturn -EINVAL;\n \n+\tx = memdup((char *)key->x + (x_len - expected_len), expected_len);\n+\tif (!x) {\n+\t\tfprintf(stderr, \"Cannot allocate memory for point X\");\n+\t\treturn -ENOMEM;\n+\t}\n+\tkey->x = (const uint8_t *)x;\n+\n+\ty = memdup((char *)key->y + (y_len - expected_len), expected_len);\n+\tif (!y) {\n+\t\tfprintf(stderr, \"Cannot allocate memory for point Y\");\n+\t\tfree((char *)x);\n+\t\treturn -ENOMEM;\n+\t}\n+\tkey->y = (const uint8_t *)y;\n+\n \treturn 0;\n }\n \n+static void fdt_free_key(struct ecdsa_public_key *key)\n+{\n+\tif (!key)\n+\t\treturn;\n+\tfree((char *)key->x);\n+\tfree((char *)key->y);\n+}\n+\n static int read_key_from_fdt(struct signer *ctx, const void *fdt, int node)\n {\n \tstruct ecdsa_public_key pubkey;\n@@ -89,8 +140,11 @@ static int read_key_from_fdt(struct signer *ctx, const void *fdt, int node)\n \t\tnid = NID_X9_62_prime256v1;\n \t} else if (!strcmp(pubkey.curve_name, \"secp384r1\")) {\n \t\tnid = NID_secp384r1;\n+\t} else if (!strcmp(pubkey.curve_name, \"secp521r1\")) {\n+\t\tnid = NID_secp521r1;\n \t} else {\n \t\tfprintf(stderr, \"Unsupported curve name: '%s'\\n\", pubkey.curve_name);\n+\t\tfdt_free_key(&pubkey);\n \t\treturn -EINVAL;\n \t}\n \n@@ -100,6 +154,7 @@ static int read_key_from_fdt(struct signer *ctx, const void *fdt, int node)\n \tec_key = EC_KEY_new_by_curve_name(nid);\n \tif (!ec_key) {\n \t\tfprintf(stderr, \"Failed to allocate EC_KEY for curve %s\\n\", pubkey.curve_name);\n+\t\tfdt_free_key(&pubkey);\n \t\treturn -ENOMEM;\n \t}\n \n@@ -108,10 +163,11 @@ static int read_key_from_fdt(struct signer *ctx, const void *fdt, int node)\n \tif (!point) {\n \t\tfprintf(stderr, \"Failed to allocate EC_POINT\\n\");\n \t\tEC_KEY_free(ec_key);\n+\t\tfdt_free_key(&pubkey);\n \t\treturn -ENOMEM;\n \t}\n \n-\tlen = pubkey.size_bits / 8;\n+\tlen = DIV_ROUND_UP(pubkey.size_bits, 8);\n \n \tuint8_t buf[1 + len * 2];\n \n@@ -123,6 +179,7 @@ static int read_key_from_fdt(struct signer *ctx, const void *fdt, int node)\n \t\tfprintf(stderr, \"Failed to convert (x,y) point to EC_POINT\\n\");\n \t\tEC_POINT_free(point);\n \t\tEC_KEY_free(ec_key);\n+\t\tfdt_free_key(&pubkey);\n \t\treturn -EINVAL;\n \t}\n \n@@ -130,11 +187,13 @@ static int read_key_from_fdt(struct signer *ctx, const void *fdt, int node)\n \t\tfprintf(stderr, \"Failed to set EC_POINT as public key\\n\");\n \t\tEC_POINT_free(point);\n \t\tEC_KEY_free(ec_key);\n+\t\tfdt_free_key(&pubkey);\n \t\treturn -EINVAL;\n \t}\n \n \tfprintf(stderr, \"Successfully loaded ECDSA key from FDT node %d\\n\", node);\n \tEC_POINT_free(point);\n+\tfdt_free_key(&pubkey);\n \tctx->ecdsa_key = ec_key;\n \n \treturn 0;\ndiff --git a/lib/ecdsa/ecdsa-verify.c b/lib/ecdsa/ecdsa-verify.c\nindex 629b662cf6c..e503627f490 100644\n--- a/lib/ecdsa/ecdsa-verify.c\n+++ b/lib/ecdsa/ecdsa-verify.c\n@@ -10,6 +10,7 @@\n \n #include <crypto/ecdsa-uclass.h>\n #include <dm/uclass.h>\n+#include <malloc.h>\n #include <u-boot/ecdsa.h>\n \n /*\n@@ -24,13 +25,19 @@ static int ecdsa_key_size(const char *curve_name)\n \t\treturn 256;\n \telse if (!strcmp(curve_name, \"secp384r1\"))\n \t\treturn 384;\n+\telse if (!strcmp(curve_name, \"secp521r1\"))\n+\t\treturn 521;\n \n \treturn 0;\n }\n \n static int fdt_get_key(struct ecdsa_public_key *key, const void *fdt, int node)\n {\n-\tint x_len, y_len;\n+\tint expected_len, x_len, y_len;\n+\tconst char *x;\n+\tconst char *y;\n+\n+\tmemset(key, 0, sizeof(*key));\n \n \tkey->curve_name = fdt_getprop(fdt, node, \"ecdsa,curve\", NULL);\n \tif (!key->curve_name) {\n@@ -50,15 +57,46 @@ static int fdt_get_key(struct ecdsa_public_key *key, const void *fdt, int node)\n \tif (!key->x || !key->y)\n \t\treturn -EINVAL;\n \n-\tif (x_len != (key->size_bits / 8) || y_len != (key->size_bits / 8)) {\n+\t/*\n+\t * The public key is stored as an array of u32, so if the key size is\n+\t * not a multiple of 32 (for example 521), we may have extra bytes.\n+\t * To avoid any issue later, we shift the x and y pointer to the first\n+\t * useful byte.\n+\t */\n+\texpected_len = DIV_ROUND_UP(key->size_bits, 8);\n+\n+\tif (x_len < expected_len || y_len < expected_len) {\n \t\tprintf(\"%s: node=%d, curve@%p x@%p+%i y@%p+%i\\n\", __func__,\n \t\t       node, key->curve_name, key->x, x_len, key->y, y_len);\n \t\treturn -EINVAL;\n \t}\n \n+\tx = memdup((char *)key->x + (x_len - expected_len), expected_len);\n+\tif (!x) {\n+\t\tdebug(\"Cannot allocate memory for point X\");\n+\t\treturn -ENOMEM;\n+\t}\n+\tkey->x = (const uint8_t *)x;\n+\n+\ty = memdup((char *)key->y + (y_len - expected_len), expected_len);\n+\tif (!y) {\n+\t\tdebug(\"Cannot allocate memory for point Y\");\n+\t\tfree((char *)x);\n+\t\treturn -ENOMEM;\n+\t}\n+\tkey->y = (const uint8_t *)y;\n+\n \treturn 0;\n }\n \n+static void fdt_free_key(struct ecdsa_public_key *key)\n+{\n+\tif (!key)\n+\t\treturn;\n+\tfree((char *)key->x);\n+\tfree((char *)key->y);\n+}\n+\n static int ecdsa_verify_hash(struct udevice *dev,\n \t\t\t     const struct image_sign_info *info,\n \t\t\t     const void *hash, const void *sig, uint sig_len)\n@@ -73,11 +111,16 @@ static int ecdsa_verify_hash(struct udevice *dev,\n \n \tif (info->required_keynode > 0) {\n \t\tret = fdt_get_key(&key, info->fdt_blob, info->required_keynode);\n-\t\tif (ret < 0)\n+\t\tif (ret < 0) {\n+\t\t\tfdt_free_key(&key);\n \t\t\treturn ret;\n+\t\t}\n+\n+\t\tret = ops->verify(dev, &key, hash, algo->checksum_len,\n+\t\t\t\t  sig, sig_len);\n+\t\tfdt_free_key(&key);\n \n-\t\treturn ops->verify(dev, &key, hash, algo->checksum_len,\n-\t\t\t\t   sig, sig_len);\n+\t\treturn ret;\n \t}\n \n \tsig_node = fdt_subnode_offset(info->fdt_blob, 0, FIT_SIG_NODENAME);\n@@ -87,15 +130,21 @@ static int ecdsa_verify_hash(struct udevice *dev,\n \t/* Try all possible keys under the \"/signature\" node */\n \tfdt_for_each_subnode(key_node, info->fdt_blob, sig_node) {\n \t\tret = fdt_get_key(&key, info->fdt_blob, key_node);\n-\t\tif (ret < 0)\n+\t\tif (ret < 0) {\n+\t\t\tfdt_free_key(&key);\n \t\t\tcontinue;\n+\t\t}\n \n \t\tret = ops->verify(dev, &key, hash, algo->checksum_len,\n \t\t\t\t  sig, sig_len);\n \n \t\t/* On success, don't worry about remaining keys */\n-\t\tif (!ret)\n+\t\tif (!ret) {\n+\t\t\tfdt_free_key(&key);\n \t\t\treturn 0;\n+\t\t}\n+\n+\t\tfdt_free_key(&key);\n \t}\n \n \treturn -EPERM;\n@@ -135,6 +184,18 @@ U_BOOT_CRYPTO_ALGO(ecdsa384) = {\n \t.verify = ecdsa_verify,\n };\n \n+U_BOOT_CRYPTO_ALGO(ecdsa521) = {\n+\t.name = \"ecdsa521\",\n+\t.key_len = ECDSA521_BYTES,\n+\t.verify = ecdsa_verify,\n+};\n+\n+U_BOOT_CRYPTO_ALGO(secp521r1) = {\n+\t.name = \"secp521r1\",\n+\t.key_len = ECDSA521_BYTES,\n+\t.verify = ecdsa_verify,\n+};\n+\n /*\n  * uclass definition for ECDSA API\n  *\ndiff --git a/lib/fdt-libcrypto.c b/lib/fdt-libcrypto.c\nindex ecb0344c8f6..090246b44e9 100644\n--- a/lib/fdt-libcrypto.c\n+++ b/lib/fdt-libcrypto.c\n@@ -10,7 +10,7 @@\n int fdt_add_bignum(void *blob, int noffset, const char *prop_name,\n \t\t   BIGNUM *num, int num_bits)\n {\n-\tint nwords = num_bits / 32;\n+\tint nwords = (num_bits + 31) / 32;\n \tint size;\n \tuint32_t *buf, *ptr;\n \tBIGNUM *tmp, *big2, *big32, *big2_32;\ndiff --git a/tools/image-sig-host.c b/tools/image-sig-host.c\nindex 5285263c616..285547994ca 100644\n--- a/tools/image-sig-host.c\n+++ b/tools/image-sig-host.c\n@@ -83,6 +83,13 @@ struct crypto_algo crypto_algos[] = {\n \t\t.add_verify_data = ecdsa_add_verify_data,\n \t\t.verify = ecdsa_verify,\n \t},\n+\t{\n+\t\t.name = \"ecdsa521\",\n+\t\t.key_len = ECDSA521_BYTES,\n+\t\t.sign = ecdsa_sign,\n+\t\t.add_verify_data = ecdsa_add_verify_data,\n+\t\t.verify = ecdsa_verify,\n+\t},\n \t{\n \t\t.name = \"secp521r1\",\n \t\t.key_len = ECDSA521_BYTES,\n","prefixes":["v5","01/15"]}