[{"id":3679176,"web_url":"http://patchwork.ozlabs.org/comment/3679176/","msgid":"<CAFLszTiUbdORp3SFCr1306tgST7-VjucxhDnTgdB0Zy6ePFs7A@mail.gmail.com>","list_archive_url":null,"date":"2026-04-20T02:11:51","subject":"Re: [PATCH v4 05/14] ecdsa: fix support of secp521r1","submitter":{"id":6170,"url":"http://patchwork.ozlabs.org/api/people/6170/","name":"Simon Glass","email":"sjg@chromium.org"},"content":"Hi Philippe,\n\nOn 2026-04-17T13:02:04, Philippe Reynes <philippe.reynes@softathome.com> wrote:\n> ecdsa: fix support of secp521r1\n>\n> Current implementation of ecdsa only supports key len aligned on\n> 8 bits. But the curve secp521r1 uses a key of 521 bits which is not\n> aligned on 8 bits. In this commit, we update the keys management\n> for ecdsa to support keys that are not aligned on 8 bits.\n>\n> Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>\n>\n> lib/ecdsa/ecdsa-libcrypto.c | 54 ++++++++++++++++++++++++++++++++++++--\n>  lib/ecdsa/ecdsa-verify.c    | 64 ++++++++++++++++++++++++++++++++++++++++-----\n>  lib/fdt-libcrypto.c         |  2 +-\n>  tools/image-sig-host.c      |  7 +++++\n>  4 files changed, 117 insertions(+), 10 deletions(-)\n\n> diff --git a/lib/ecdsa/ecdsa-verify.c b/lib/ecdsa/ecdsa-verify.c\n> @@ -87,15 +121,19 @@ static int ecdsa_verify_hash(struct udevice *dev,\n> +             ret = ops->verify(dev, &key, hash, algo->checksum_len,\n> +                               sig, sig_len);\n> +\n> +             /* On success, don't worry about remaining keys */\n> +             if (!ret) {\n> +                     fdt_free_key(&key);\n> +                     return 0;\n> +             }\n> +     }\n\nWhen ops->verify() returns non-zero, the loop continues but does not\ncall fdt_free_key(), leaking memory allocated by memdup() for each\nfailed attempt. Please can you add fdt_free_key(&key) for the failure\ncase.\n\n> diff --git a/lib/ecdsa/ecdsa-verify.c b/lib/ecdsa/ecdsa-verify.c\n> @@ -50,15 +57,37 @@ static int fdt_get_key(struct ecdsa_public_key *key, const void *fdt, int node)\n> +     x = memdup((char *)key->x + (x_len - expected_len), expected_len);\n> +     key->x = (const uint8_t *)x;\n> +\n> +     y = memdup((char *)key->y + (y_len - expected_len), expected_len);\n> +     key->y = (const uint8_t *)y;\n\nThe memdup() calls are not checked for allocation failure. If x\nsucceeds but y fails, x is leaked. Please can you check return values\nand return -ENOMEM on failure.\n\n> diff --git a/lib/ecdsa/ecdsa-libcrypto.c b/lib/ecdsa/ecdsa-libcrypto.c\n> @@ -63,12 +83,34 @@ static int fdt_get_key(struct ecdsa_public_key *key, const void *fdt, int node)\n> +     x = memdup((char *)key->x + (x_len - expected_len), expected_len);\n> +     key->x = (const uint8_t *)x;\n> +\n> +     y = memdup((char *)key->y + (y_len - expected_len), expected_len);\n> +     key->y = (const uint8_t *)y;\n\nSame issue here - missing error handling for memdup() failures.\n\nRegards,\nSimon","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 (1024-bit key;\n unprotected) header.d=chromium.org header.i=@chromium.org header.a=rsa-sha256\n header.s=google header.b=QAr55JdN;\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=pass (p=none dis=none) header.from=chromium.org","phobos.denx.de;\n spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de","phobos.denx.de;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=chromium.org header.i=@chromium.org\n header.b=\"QAr55JdN\";\n\tdkim-atps=neutral","phobos.denx.de;\n dmarc=pass (p=none dis=none) header.from=chromium.org","phobos.denx.de;\n spf=pass smtp.mailfrom=sjg@chromium.org"],"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 4fzTXJ03nKz1yGt\n\tfor <incoming@patchwork.ozlabs.org>; Mon, 20 Apr 2026 12:12:31 +1000 (AEST)","from h2850616.stratoserver.net (localhost [IPv6:::1])\n\tby phobos.denx.de (Postfix) with ESMTP id 8654E8425F;\n\tMon, 20 Apr 2026 04:12:28 +0200 (CEST)","by phobos.denx.de (Postfix, from userid 109)\n id C633284297; Mon, 20 Apr 2026 04:12:26 +0200 (CEST)","from mail-ej1-x62f.google.com (mail-ej1-x62f.google.com\n [IPv6:2a00:1450:4864:20::62f])\n (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits))\n (No client certificate requested)\n by phobos.denx.de (Postfix) with ESMTPS id D1C2882BF2\n for <u-boot@lists.denx.de>; Mon, 20 Apr 2026 04:12:24 +0200 (CEST)","by mail-ej1-x62f.google.com with SMTP id\n a640c23a62f3a-b9910707d82so378730566b.1\n for <u-boot@lists.denx.de>; Sun, 19 Apr 2026 19:12:24 -0700 (PDT)"],"X-Spam-Checker-Version":"SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de","X-Spam-Level":"","X-Spam-Status":"No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,\n DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,\n RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS autolearn=ham\n autolearn_force=no version=3.4.2","ARC-Seal":"i=1; a=rsa-sha256; t=1776651144; cv=none;\n d=google.com; s=arc-20240605;\n b=Bj2ITj8w3kkoZ0+zkO+IOAirbANu48QTxRATOGcG0FZK5GC7EQxYJ4u3nf+HpqhJnG\n 22bV03diSiSWJkkmuB1WE9sj5n4pEEOYtqJ33n9v4zrkX60q+vNacBf3WHDLjqK5Q2Um\n L4BWIfbaF3kEZd+0YcQDN+43ffdkdZHkKthxWppkwj5eVMSTLhHfvYp2PrcXomA5xuax\n eZw7atof+E+7RRMS5PdNuxyU0Dzwf3yQYXXJxN/2tXGevvsGxbk0xUjAS19dqMeoo4+H\n tAJhgCwzeERy7fbxcF3BQnLl8y51AhDzoGKHJ7X6fSoVmd+DNe/vbNLcf3MxvibuHTSb\n 7QtQ==","ARC-Message-Signature":"i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com;\n s=arc-20240605;\n h=cc:to:subject:message-id:date:from:in-reply-to:references\n :mime-version:dkim-signature;\n bh=GKJKrct7jmiq1kAOUPsEwubOVojz0+bWYL8SONUayO8=;\n fh=ERIzv2E6p98XY+3py7ZK3V+bKncc/D+mGuiYvQmJjR0=;\n b=PnYEJ1lUYVh5qv/QI93rTth6UDXaqOAj/f6ytftR6guAtocE0pfcfSAjZeWjpa1Wsj\n VcviZuka9YuEwyHpL7TDGAeBhYIAlUk3iPt+QTehUrpTzRw4Y3VX1otxBiPloISHL5wJ\n pTD71K/c+d0i5IPGs22LKKBmDRtO4RHpfJKPMP+fHli87D8d4D2RdCaX1PUABpzkP8yS\n PJAW8imveIJ0jPpw6FU+pZfzZs8BWoUOW4HmYb3mH6MiEs+x2/VvxQgAu7FBfkD/V+Zr\n uvoipRycHuGMVus5u6d9u/85sXggIsGfOdQ8vkiFg2p6muOz87ueIrPOhu+L6Ipkpshu\n FSAA==; darn=lists.denx.de","ARC-Authentication-Results":"i=1; mx.google.com; arc=none","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=chromium.org; s=google; t=1776651144; x=1777255944; darn=lists.denx.de;\n h=cc:to:subject:message-id:date:from:in-reply-to:references\n :mime-version:from:to:cc:subject:date:message-id:reply-to;\n bh=GKJKrct7jmiq1kAOUPsEwubOVojz0+bWYL8SONUayO8=;\n b=QAr55JdNJxWVokiwBQZph80Jzj4GLLYGhWvltuWJn/zoAbCUvfQf86cWnxQ1oQhQF0\n 8+kTqa9CUsCN8AYRmTckvzRsgXwaFrz85b00RlaXidhmq77M3yomZadaxJvP+LeCN8DG\n rXf6cABE/AAZB1asSVQiSaeNNwGzHLivr9FQY=","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1776651144; x=1777255944;\n h=cc:to:subject:message-id:date:from:in-reply-to:references\n :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date\n :message-id:reply-to;\n bh=GKJKrct7jmiq1kAOUPsEwubOVojz0+bWYL8SONUayO8=;\n b=mvbuwmvW+L8z3oSti9bR3YZuXtQOO1O1+xmWuU1HP22ZgvXBEQplZAS3L/NHnX6Rwa\n 7+8Ac1XXyikdFtfharWS57ZxCehos01GH52ojR4KPWFDrQOFfYQe8p/CWlp6jDGL8BXG\n wIQlhIf6ok54OIOkwLvJE2lzegi1yAu1gHoePMIRhFjXXTdzCD4dphcfTB8QprL9a/NC\n 2h1waMMUgsM2xiyE6UoSkp/DkNfk8QfYHxEUsR+xmFjgWJDrqberKpXPDGDISvZu/Wv4\n CdH5CzvVnL4l3/pNUjHLtMajFn7DkBACS4RLm5afx3GHMZsq0Yvd5HgkPARsLJaI1deG\n 7efw==","X-Forwarded-Encrypted":"i=1;\n AFNElJ8dYzdzLrIdc5lfeepreNt3zci7SCjv0ZCuUJ0gUAoIkiukOQE/FJILoTnadbBhaAcDfNHkpAY=@lists.denx.de","X-Gm-Message-State":"AOJu0Yx0OpEYp0fJbjHdrPN0070EoXmJBGRk0i0RhyX3BRO6zGCkgSPz\n wrIg9OkAkq6yuQ4xF54Fcvko7gBnGd8/5lDQk31dU/ZDXMjgX9wU3fPC8/udqAs9ZKhG9OTd/Lf\n /TZ2eIdzYVAn5ro2b8FJfbWCqZUrVCrkysQxGik/w","X-Gm-Gg":"AeBDieugFSsMZg9OyZJ6zv3uL/WIIA/yx3r4mVss8gZY16OoQjEVhU3v2lAapzVCHR7\n g+BLMdf2vtG4qj8LVbtqa+vTocIv4SV8BQ6vzR0QCa4rDhAUysHKZic2CxIR5an+4s1UB12hrGV\n Y7U7BNXw1JiatHo1SjEe3z8J48NSQW4xMIfl0bVc5TsnJFBhjzU9CngzwBi2N6XT6KXWnXj8lvi\n uiUxBpvRIOpHfSt8Z12TgHRCEOrhJo2SBKB/fl/sGxvQvq+q1eV8kJZAGzT9oyxIg7EgaifeKSN\n GJ94VQ0G8HZ9RHv1C12j","X-Received":"by 2002:a17:907:d40e:b0:ba2:e022:c146 with SMTP id\n a640c23a62f3a-ba41b3e451amr557545266b.43.1776651144184; Sun, 19 Apr 2026\n 19:12:24 -0700 (PDT)","MIME-Version":"1.0","References":"<20260417130204.49896-1-philippe.reynes@softathome.com>\n <20260417130204.49896-6-philippe.reynes@softathome.com>","In-Reply-To":"<20260417130204.49896-6-philippe.reynes@softathome.com>","From":"Simon Glass <sjg@chromium.org>","Date":"Mon, 20 Apr 2026 14:11:51 +1200","X-Gm-Features":"AQROBzAmEWVbbDpVVbrVDliuTlXf3GW7m0qPns5XWd6aeEXXFBgevxowLsBLsy0","Message-ID":"\n <CAFLszTiUbdORp3SFCr1306tgST7-VjucxhDnTgdB0Zy6ePFs7A@mail.gmail.com>","Subject":"Re: [PATCH v4 05/14] ecdsa: fix support of secp521r1","To":"philippe.reynes@softathome.com","Cc":"marko.makela@iki.fi, jonny.green@keytechinc.com, raymondmaoca@gmail.com,\n trini@konsulko.com, simon.glass@canonical.com, u-boot@lists.denx.de","Content-Type":"text/plain; charset=\"UTF-8\"","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"}},{"id":3679488,"web_url":"http://patchwork.ozlabs.org/comment/3679488/","msgid":"<CAMDkj5y8_bKy3tt7eHiweVyh=GoXn5JWd+TGw6WnKYTeJ0qrJg@mail.gmail.com>","list_archive_url":null,"date":"2026-04-20T17:10:14","subject":"Re: [PATCH v4 05/14] ecdsa: fix support of secp521r1","submitter":{"id":91989,"url":"http://patchwork.ozlabs.org/api/people/91989/","name":"Raymond Mao","email":"raymondmaoca@gmail.com"},"content":"Hi Philippe,\n\nOn Fri, Apr 17, 2026 at 9:02 AM Philippe Reynes\n<philippe.reynes@softathome.com> wrote:\n>\n> Current implementation of ecdsa only supports key len aligned on\n> 8 bits. But the curve secp521r1 uses a key of 521 bits which is not\n> aligned on 8 bits. In this commit, we update the keys management\n> for ecdsa to support keys that are not aligned on 8 bits.\n>\n> Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>\n> ---\n> v2:\n> - intitial version\n> v3:\n> - fix typo in comments\n> v4:\n> - fix commit message\n> - clean code with DIV_ROUND_UP-\n> - duplicate data before shifting\n> - support ecdsa521 and secp521r1\n> - clean code\n>\n>  lib/ecdsa/ecdsa-libcrypto.c | 54 +++++++++++++++++++++++++++++--\n>  lib/ecdsa/ecdsa-verify.c    | 64 +++++++++++++++++++++++++++++++++----\n>  lib/fdt-libcrypto.c         |  2 +-\n>  tools/image-sig-host.c      |  7 ++++\n>  4 files changed, 117 insertions(+), 10 deletions(-)\n>\n> diff --git a/lib/ecdsa/ecdsa-libcrypto.c b/lib/ecdsa/ecdsa-libcrypto.c\n> index c4bfb2cec61..9218d06bda0 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>         EVP_PKEY *evp_key;      /* Pointer to EVP_PKEY object */\n> @@ -41,10 +43,26 @@ struct ecdsa_public_key {\n>         int size_bits;\n>  };\n>\n> +static char *memdup(char *buf, size_t size)\n> +{\n> +       char *dup;\n> +\n> +       dup = malloc(size);\n> +       if (dup)\n> +               memcpy(dup, buf, size);\n> +\n> +       return dup;\n> +}\n> +\n>  static int fdt_get_key(struct ecdsa_public_key *key, const void *fdt, int node)\n>  {\n> +       const char *x;\n> +       const char *y;\n>         int x_len;\n>         int y_len;\n> +       int expected_len;\n> +\n> +       memset(key, 0, sizeof(*key));\n>\n>         key->curve_name = fdt_getprop(fdt, node, \"ecdsa,curve\", NULL);\n>         if (!key->curve_name)\n> @@ -54,6 +72,8 @@ static int fdt_get_key(struct ecdsa_public_key *key, const void *fdt, int node)\n>                 key->size_bits = 256;\n>         else if (!strcmp(key->curve_name, \"secp384r1\"))\n>                 key->size_bits = 384;\n> +       else if (!strcmp(key->curve_name, \"secp521r1\"))\n> +               key->size_bits = 521;\n>         else\n>                 return -EINVAL;\n>\n> @@ -63,12 +83,34 @@ static int fdt_get_key(struct ecdsa_public_key *key, const void *fdt, int node)\n>         if (!key->x || !key->y)\n>                 return -EINVAL;\n>\n> -       if (x_len != key->size_bits / 8 || y_len != key->size_bits / 8)\n> +       /*\n> +        * The public key is stored as an array of u32, so if the key size is\n> +        * not a multiple of 32 (for example 521), we may have extra bytes.\n> +        * To avoid any issue later, we shift the x and y pointer to the first\n> +        * useful byte.\n> +        */\n> +       expected_len = DIV_ROUND_UP(key->size_bits, 8);\n> +\n> +       if (x_len < expected_len || y_len < expected_len)\n>                 return -EINVAL;\n>\n> +       x = memdup((char *)key->x + (x_len - expected_len), expected_len);\n> +       key->x = (const uint8_t *)x;\n\nmemdup() result for x is not checked before assigning it to key->x.\n\n> +\n> +       y = memdup((char *)key->y + (y_len - expected_len), expected_len);\n> +       key->y = (const uint8_t *)y;\n> +\n\nDitto.\n\n>         return 0;\n>  }\n>\n> +static void fdt_free_key(struct ecdsa_public_key *key)\n> +{\n> +       if (!key)\n> +               return;\n> +       free((char *)key->x);\n> +       free((char *)key->y);\n> +}\n> +\n>  static int read_key_from_fdt(struct signer *ctx, const void *fdt, int node)\n>  {\n>         struct ecdsa_public_key pubkey;\n> @@ -89,8 +131,11 @@ static int read_key_from_fdt(struct signer *ctx, const void *fdt, int node)\n>                 nid = NID_X9_62_prime256v1;\n>         } else if (!strcmp(pubkey.curve_name, \"secp384r1\")) {\n>                 nid = NID_secp384r1;\n> +       } else if (!strcmp(pubkey.curve_name, \"secp521r1\")) {\n> +               nid = NID_secp521r1;\n>         } else {\n>                 fprintf(stderr, \"Unsupported curve name: '%s'\\n\", pubkey.curve_name);\n> +               fdt_free_key(&pubkey);\n>                 return -EINVAL;\n>         }\n>\n> @@ -100,6 +145,7 @@ static int read_key_from_fdt(struct signer *ctx, const void *fdt, int node)\n>         ec_key = EC_KEY_new_by_curve_name(nid);\n>         if (!ec_key) {\n>                 fprintf(stderr, \"Failed to allocate EC_KEY for curve %s\\n\", pubkey.curve_name);\n> +               fdt_free_key(&pubkey);\n>                 return -ENOMEM;\n>         }\n>\n> @@ -108,10 +154,11 @@ static int read_key_from_fdt(struct signer *ctx, const void *fdt, int node)\n>         if (!point) {\n>                 fprintf(stderr, \"Failed to allocate EC_POINT\\n\");\n>                 EC_KEY_free(ec_key);\n> +               fdt_free_key(&pubkey);\n>                 return -ENOMEM;\n>         }\n>\n> -       len = pubkey.size_bits / 8;\n> +       len = DIV_ROUND_UP(pubkey.size_bits, 8);\n>\n>         uint8_t buf[1 + len * 2];\n>\n> @@ -123,6 +170,7 @@ static int read_key_from_fdt(struct signer *ctx, const void *fdt, int node)\n>                 fprintf(stderr, \"Failed to convert (x,y) point to EC_POINT\\n\");\n>                 EC_POINT_free(point);\n>                 EC_KEY_free(ec_key);\n> +               fdt_free_key(&pubkey);\n>                 return -EINVAL;\n>         }\n>\n> @@ -130,11 +178,13 @@ static int read_key_from_fdt(struct signer *ctx, const void *fdt, int node)\n>                 fprintf(stderr, \"Failed to set EC_POINT as public key\\n\");\n>                 EC_POINT_free(point);\n>                 EC_KEY_free(ec_key);\n> +               fdt_free_key(&pubkey);\n>                 return -EINVAL;\n>         }\n>\n>         fprintf(stderr, \"Successfully loaded ECDSA key from FDT node %d\\n\", node);\n>         EC_POINT_free(point);\n> +       fdt_free_key(&pubkey);\n>         ctx->ecdsa_key = ec_key;\n>\n>         return 0;\n> diff --git a/lib/ecdsa/ecdsa-verify.c b/lib/ecdsa/ecdsa-verify.c\n> index 629b662cf6c..64b56bcffba 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>                 return 256;\n>         else if (!strcmp(curve_name, \"secp384r1\"))\n>                 return 384;\n> +       else if (!strcmp(curve_name, \"secp521r1\"))\n> +               return 521;\n>\n>         return 0;\n>  }\n>\n>  static int fdt_get_key(struct ecdsa_public_key *key, const void *fdt, int node)\n>  {\n> -       int x_len, y_len;\n> +       int expected_len, x_len, y_len;\n> +       const char *x;\n> +       const char *y;\n> +\n> +       memset(key, 0, sizeof(*key));\n>\n>         key->curve_name = fdt_getprop(fdt, node, \"ecdsa,curve\", NULL);\n>         if (!key->curve_name) {\n> @@ -50,15 +57,37 @@ static int fdt_get_key(struct ecdsa_public_key *key, const void *fdt, int node)\n>         if (!key->x || !key->y)\n>                 return -EINVAL;\n>\n> -       if (x_len != (key->size_bits / 8) || y_len != (key->size_bits / 8)) {\n> +       /*\n> +        * The public key is stored as an array of u32, so if the key size is\n> +        * not a multiple of 32 (for example 521), we may have extra bytes.\n> +        * To avoid any issue later, we shift the x and y pointer to the first\n> +        * useful byte.\n> +        */\n> +       expected_len = DIV_ROUND_UP(key->size_bits, 8);\n> +\n> +       if (x_len < expected_len || y_len < expected_len) {\n>                 printf(\"%s: node=%d, curve@%p x@%p+%i y@%p+%i\\n\", __func__,\n>                        node, key->curve_name, key->x, x_len, key->y, y_len);\n>                 return -EINVAL;\n>         }\n>\n> +       x = memdup((char *)key->x + (x_len - expected_len), expected_len);\n> +       key->x = (const uint8_t *)x;\n> +\n\nDitto.\n\n> +       y = memdup((char *)key->y + (y_len - expected_len), expected_len);\n> +       key->y = (const uint8_t *)y;\n\nDitto.\n\n> +\n>         return 0;\n>  }\n>\n> +static void fdt_free_key(struct ecdsa_public_key *key)\n> +{\n> +       if (!key)\n> +               return;\n> +       free((char *)key->x);\n> +       free((char *)key->y);\n> +}\n> +\n>  static int ecdsa_verify_hash(struct udevice *dev,\n>                              const struct image_sign_info *info,\n>                              const void *hash, const void *sig, uint sig_len)\n> @@ -73,11 +102,16 @@ static int ecdsa_verify_hash(struct udevice *dev,\n>\n>         if (info->required_keynode > 0) {\n>                 ret = fdt_get_key(&key, info->fdt_blob, info->required_keynode);\n> -               if (ret < 0)\n> +               if (ret < 0) {\n> +                       fdt_free_key(&key);\n>                         return ret;\n> +               }\n>\n> -               return ops->verify(dev, &key, hash, algo->checksum_len,\n> -                                  sig, sig_len);\n> +               ret = ops->verify(dev, &key, hash, algo->checksum_len,\n> +                                 sig, sig_len);\n> +               fdt_free_key(&key);\n> +\n> +               return ret;\n>         }\n>\n>         sig_node = fdt_subnode_offset(info->fdt_blob, 0, FIT_SIG_NODENAME);\n> @@ -87,15 +121,19 @@ static int ecdsa_verify_hash(struct udevice *dev,\n>         /* Try all possible keys under the \"/signature\" node */\n>         fdt_for_each_subnode(key_node, info->fdt_blob, sig_node) {\n>                 ret = fdt_get_key(&key, info->fdt_blob, key_node);\n> -               if (ret < 0)\n> +               if (ret < 0) {\n> +                       fdt_free_key(&key);\n>                         continue;\n> +               }\n>\n>                 ret = ops->verify(dev, &key, hash, algo->checksum_len,\n>                                   sig, sig_len);\n>\n>                 /* On success, don't worry about remaining keys */\n> -               if (!ret)\n> +               if (!ret) {\n> +                       fdt_free_key(&key);\n>                         return 0;\n> +               }\n\nfdt_free_key(&key) is called only on successful verification. Failed\nverification leaks the copied x and y buffers.\n\nRegards,\nRaymond\n\n>         }\n>\n>         return -EPERM;\n> @@ -135,6 +173,18 @@ U_BOOT_CRYPTO_ALGO(ecdsa384) = {\n>         .verify = ecdsa_verify,\n>  };\n>\n> +U_BOOT_CRYPTO_ALGO(ecdsa521) = {\n> +       .name = \"ecdsa521\",\n> +       .key_len = ECDSA521_BYTES,\n> +       .verify = ecdsa_verify,\n> +};\n> +\n> +U_BOOT_CRYPTO_ALGO(secp521r1) = {\n> +       .name = \"secp521r1\",\n> +       .key_len = ECDSA521_BYTES,\n> +       .verify = ecdsa_verify,\n> +};\n> +\n>  /*\n>   * uclass definition for ECDSA API\n>   *\n> diff --git a/lib/fdt-libcrypto.c b/lib/fdt-libcrypto.c\n> index 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>                    BIGNUM *num, int num_bits)\n>  {\n> -       int nwords = num_bits / 32;\n> +       int nwords = (num_bits + 31) / 32;\n>         int size;\n>         uint32_t *buf, *ptr;\n>         BIGNUM *tmp, *big2, *big32, *big2_32;\n> diff --git a/tools/image-sig-host.c b/tools/image-sig-host.c\n> index 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>                 .add_verify_data = ecdsa_add_verify_data,\n>                 .verify = ecdsa_verify,\n>         },\n> +       {\n> +               .name = \"ecdsa521\",\n> +               .key_len = ECDSA521_BYTES,\n> +               .sign = ecdsa_sign,\n> +               .add_verify_data = ecdsa_add_verify_data,\n> +               .verify = ecdsa_verify,\n> +       },\n>         {\n>                 .name = \"secp521r1\",\n>                 .key_len = ECDSA521_BYTES,\n> --\n> 2.43.0\n>","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=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20251104 header.b=mjDIB4kj;\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=pass (p=none dis=none) header.from=gmail.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=gmail.com header.i=@gmail.com header.b=\"mjDIB4kj\";\n\tdkim-atps=neutral","phobos.denx.de;\n dmarc=pass (p=none dis=none) header.from=gmail.com","phobos.denx.de;\n spf=pass smtp.mailfrom=raymondmaoca@gmail.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 4fzsST2j8Mz1yD4\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 21 Apr 2026 03:10:33 +1000 (AEST)","from h2850616.stratoserver.net (localhost [IPv6:::1])\n\tby phobos.denx.de (Postfix) with ESMTP id 6ADA98431E;\n\tMon, 20 Apr 2026 19:10:30 +0200 (CEST)","by phobos.denx.de (Postfix, from userid 109)\n id 2CD0484326; Mon, 20 Apr 2026 19:10:29 +0200 (CEST)","from mail-vs1-xe33.google.com (mail-vs1-xe33.google.com\n [IPv6:2607:f8b0:4864:20::e33])\n (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits))\n (No client certificate requested)\n by phobos.denx.de (Postfix) with ESMTPS id B611083BC8\n for <u-boot@lists.denx.de>; Mon, 20 Apr 2026 19:10:26 +0200 (CEST)","by mail-vs1-xe33.google.com with SMTP id\n ada2fe7eead31-61179fc2242so711488137.0\n for <u-boot@lists.denx.de>; Mon, 20 Apr 2026 10:10:26 -0700 (PDT)"],"X-Spam-Checker-Version":"SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de","X-Spam-Level":"","X-Spam-Status":"No, score=-1.1 required=5.0 tests=BAYES_00,DKIM_SIGNED,\n DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FORGED_GMAIL_RCVD,FREEMAIL_FROM,\n NO_DNS_FOR_FROM,RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,T_SPF_TEMPERROR\n autolearn=no autolearn_force=no version=3.4.2","ARC-Seal":"i=1; a=rsa-sha256; t=1776705025; cv=none;\n d=google.com; s=arc-20240605;\n b=do8WV+Sngrxz0GBir4BQEu/DYar4vawJEcV9oqGNBgFKVzd/bRgUlG7PgzNui80Z0n\n Wy/lqbBK9ugDguIjZThyup7PoVaxNLNm6QN7eMa1qQfTSsWeBPisBdIb5JdeLDE7rIC+\n rUQCf0FPTTquzZLp56b5qhdXbmyZ8hrgXx48Aekxc2l+RwkW3vAXP0wLfYoTgSDf70OI\n 88EeexsMw7WeKesy7VdDxJBxEVgNSv3h62SZrfLDDKBTRZ4Y89nO8Feg5yUh53zR7bQ2\n ajEoyEyP9SPQ2K+vjm+mSpuUfEddvbIvcR3KrdQ0SSrx2la0crqkEFXbbABjGuwiycWL\n WHXQ==","ARC-Message-Signature":"i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com;\n s=arc-20240605;\n h=content-transfer-encoding:cc:to:subject:message-id:date:from\n :in-reply-to:references:mime-version:dkim-signature;\n bh=D3IVH3avWw9gabcnh4szvWSUo2uyGfzQXNGNCYYVy4o=;\n fh=jm5nZMBfBi/L2y9wN9avK1A0b8IJsMp9UO8qc5wuVv4=;\n b=N4YAC89j6vVV3NqcHfaohseHpUcAZ6JDS3y39+6RFf7jHO70xRKa/gHYRpgbzf0iHC\n HotycEAFs1YzuC0XXH/rK0nJRnI1vjqCLP8U6Oxzckjp1vaO+bYCeOlefiGfFqSFFFzf\n bXhkDBB9UYF1StgBJHw/7vJJ3s8OZHfxz8rUzLxQ6duUgQvk+yBmskMbxhwzEyK8eKWV\n CY1leujdHxdpTkhKSY0hlZLvNTlXdwff55zBooNdzGIzzCn58vCc9cD6hwZ7j5XGVg+d\n Wzg6tX1hSQI2d65H9a80Oh94lTLDjsJSjEF522M9KZ+WhPzEyvarrml7EJrC/mCgfeUV\n oW4w==; darn=lists.denx.de","ARC-Authentication-Results":"i=1; mx.google.com; arc=none","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=gmail.com; s=20251104; t=1776705025; x=1777309825; darn=lists.denx.de;\n h=content-transfer-encoding:cc:to:subject:message-id:date:from\n :in-reply-to:references:mime-version:from:to:cc:subject:date\n :message-id:reply-to;\n bh=D3IVH3avWw9gabcnh4szvWSUo2uyGfzQXNGNCYYVy4o=;\n b=mjDIB4kjwwnGQONNFGkSBSbVClpWm4++Yrzw8+eF2fIIc/c1GpwXCaMH92TbknlZxv\n /OQBFRugcEbXg+GMiSOGuu031Ioqb9sOZP01d1gO2ZsxsHK1PzGdtOkbUkJ3OdbdnU7t\n SyX3iR1VPJmJkHPTtf8DqCRJJ3r5CY+XnbwK77eB17tVehaoF94V2HUP+BJ388cCXlBR\n QHKk0mftCleIqucRXoWCQbv98GearLIFlstUNd4AjV7G1Faav4w1S92QiypKtO4aO3sS\n kkKmbQlsbhzA2iDznoDZqEQwAj1P2w1JwDVlt5tXJFWu3sGHRrkrZb9MFabeZZUrJ0p+\n bfMw==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1776705025; x=1777309825;\n h=content-transfer-encoding:cc:to:subject:message-id:date:from\n :in-reply-to:references:mime-version:x-gm-gg:x-gm-message-state:from\n :to:cc:subject:date:message-id:reply-to;\n bh=D3IVH3avWw9gabcnh4szvWSUo2uyGfzQXNGNCYYVy4o=;\n b=qU80qUZs+n6SYfHrXljr6Jvwct+gfPgO3tXUBSmbpcHF6DidhWT1C/7Bo+UWjvBSPH\n sHtTSKodpZKvyLFTFdM+ozTvzD+Cgk1XbJtwO5G3+ELUV/lc+daYak5wuD55YycgCyTD\n T9N1ndArXoE8HlJBwztEfBaWFZvgxlME3xFCcx9T/yJgAJCGtrEWAHF3+Nv94H6No+jT\n suMg4lKQHoQ+6w5AkuzaTXCDtaloHMExOKu2A+V0oz8PVIw1LxaiR8EqgzzFxcHLc3KC\n 11QQNjMUCwmscW1i/fEXvADpSOnEi0s+BLCt3Yi/9z1lIx/ZIfUyVuMWmFTM2V/mUHYI\n BTKw==","X-Forwarded-Encrypted":"i=1;\n AFNElJ9xJPxKCFOweh9hx2DH6JMHPeQBb3eD1mWj4uXPFbX/fSvvXSEWVUzR1VZlilHxG8lsTlfThOI=@lists.denx.de","X-Gm-Message-State":"AOJu0YycYYnBUWeIJReSxQ2wYVsYVOmNainzelEwzO/9v4+jhlYsNmF8\n K0FcNrQj52T+2/FK79gwcExZIWw4q2aH/GpGZdEJ5kusinXkr3moiGmR0phfWs0+4JIqZjFxTiN\n C+THg7+VeQEr+BoOY0HeT2Ny+o3/zZIU=","X-Gm-Gg":"AeBDietyQ9p5QjQqLNWPGsRPbAvZKqoNy6Aue2iurIs6jJlBbX+UFR5M0tZFtdjWv9U\n ZTAEIHm3+ehD5ZLgKq1pF07h+TsbTDrnzJglmyD2yxqnl2eJMh/cPpjxV9QmlKjzkcE9mZ2BDH8\n jK4XeOTP1zpre9p3hzKqn7K5MaeX8zwzJPLFoMwtia3PoCB3yaZtQDOnXPuDnq92aaUfN/IbNe7\n yaeWMS77lBM/Dum9j4j15WHNisSbADVwW1269UkdRcoLxxS2s2j0yCQ76BPpUCIstKlbf7sNKgC\n MmVHm4d3PslyUvaQSWE=","X-Received":"by 2002:a05:6102:5124:b0:608:f466:687f with SMTP id\n ada2fe7eead31-616f88affaamr5783606137.23.1776705025264; Mon, 20 Apr 2026\n 10:10:25 -0700 (PDT)","MIME-Version":"1.0","References":"<20260417130204.49896-1-philippe.reynes@softathome.com>\n <20260417130204.49896-6-philippe.reynes@softathome.com>","In-Reply-To":"<20260417130204.49896-6-philippe.reynes@softathome.com>","From":"Raymond Mao <raymondmaoca@gmail.com>","Date":"Mon, 20 Apr 2026 13:10:14 -0400","X-Gm-Features":"AQROBzCU_g-vdbp6Tfa7iDgGNS6hksRX-ovZGaFMI5HaACIp8NI9hnfUFdWx_vg","Message-ID":"\n <CAMDkj5y8_bKy3tt7eHiweVyh=GoXn5JWd+TGw6WnKYTeJ0qrJg@mail.gmail.com>","Subject":"Re: [PATCH v4 05/14] ecdsa: fix support of secp521r1","To":"Philippe Reynes <philippe.reynes@softathome.com>","Cc":"marko.makela@iki.fi, jonny.green@keytechinc.com, trini@konsulko.com,\n simon.glass@canonical.com, u-boot@lists.denx.de","Content-Type":"text/plain; charset=\"UTF-8\"","Content-Transfer-Encoding":"quoted-printable","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"}}]