From: David Laight <david.laight.linux@gmail.com>
To: Guan-Chun Wu <409411716@gms.tku.edu.tw>
Cc: akpm@linux-foundation.org, andriy.shevchenko@intel.com,
axboe@kernel.dk, ceph-devel@vger.kernel.org, ebiggers@kernel.org,
hch@lst.de, home7438072@gmail.com, idryomov@gmail.com,
jaegeuk@kernel.org, kbusch@kernel.org,
linux-fscrypt@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-nvme@lists.infradead.org, sagi@grimberg.me, tytso@mit.edu,
visitorckw@gmail.com, xiubli@redhat.com
Subject: Re: [PATCH v5 1/6] lib/base64: Add support for multiple variants
Date: Fri, 14 Nov 2025 09:13:48 +0000 [thread overview]
Message-ID: <20251114091348.562c5965@pumpkin> (raw)
In-Reply-To: <20251114060045.88792-1-409411716@gms.tku.edu.tw>
On Fri, 14 Nov 2025 14:00:45 +0800
Guan-Chun Wu <409411716@gms.tku.edu.tw> wrote:
> From: Kuan-Wei Chiu <visitorckw@gmail.com>
>
> Extend the base64 API to support multiple variants (standard, URL-safe,
> and IMAP) as defined in RFC 4648 and RFC 3501. The API now takes a
> variant parameter and an option to control padding. Update NVMe auth
> code to use the new interface with BASE64_STD.
>
> Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
> Co-developed-by: Guan-Chun Wu <409411716@gms.tku.edu.tw>
> Signed-off-by: Guan-Chun Wu <409411716@gms.tku.edu.tw>
Reviewed-by: David Laight <david.laight.linux@gmail.com>
> ---
> drivers/nvme/common/auth.c | 4 +--
> include/linux/base64.h | 10 ++++--
> lib/base64.c | 62 ++++++++++++++++++++++----------------
> 3 files changed, 46 insertions(+), 30 deletions(-)
>
> diff --git a/drivers/nvme/common/auth.c b/drivers/nvme/common/auth.c
> index 1f51fbebd9fa..e07e7d4bf8b6 100644
> --- a/drivers/nvme/common/auth.c
> +++ b/drivers/nvme/common/auth.c
> @@ -178,7 +178,7 @@ struct nvme_dhchap_key *nvme_auth_extract_key(unsigned char *secret,
> if (!key)
> return ERR_PTR(-ENOMEM);
>
> - key_len = base64_decode(secret, allocated_len, key->key);
> + key_len = base64_decode(secret, allocated_len, key->key, true, BASE64_STD);
> if (key_len < 0) {
> pr_debug("base64 key decoding error %d\n",
> key_len);
> @@ -663,7 +663,7 @@ int nvme_auth_generate_digest(u8 hmac_id, u8 *psk, size_t psk_len,
> if (ret)
> goto out_free_digest;
>
> - ret = base64_encode(digest, digest_len, enc);
> + ret = base64_encode(digest, digest_len, enc, true, BASE64_STD);
> if (ret < hmac_len) {
> ret = -ENOKEY;
> goto out_free_digest;
> diff --git a/include/linux/base64.h b/include/linux/base64.h
> index 660d4cb1ef31..a2c6c9222da3 100644
> --- a/include/linux/base64.h
> +++ b/include/linux/base64.h
> @@ -8,9 +8,15 @@
>
> #include <linux/types.h>
>
> +enum base64_variant {
> + BASE64_STD, /* RFC 4648 (standard) */
> + BASE64_URLSAFE, /* RFC 4648 (base64url) */
> + BASE64_IMAP, /* RFC 3501 */
> +};
> +
> #define BASE64_CHARS(nbytes) DIV_ROUND_UP((nbytes) * 4, 3)
>
> -int base64_encode(const u8 *src, int len, char *dst);
> -int base64_decode(const char *src, int len, u8 *dst);
> +int base64_encode(const u8 *src, int len, char *dst, bool padding, enum base64_variant variant);
> +int base64_decode(const char *src, int len, u8 *dst, bool padding, enum base64_variant variant);
>
> #endif /* _LINUX_BASE64_H */
> diff --git a/lib/base64.c b/lib/base64.c
> index b736a7a431c5..a7c20a8e8e98 100644
> --- a/lib/base64.c
> +++ b/lib/base64.c
> @@ -1,12 +1,12 @@
> // SPDX-License-Identifier: GPL-2.0
> /*
> - * base64.c - RFC4648-compliant base64 encoding
> + * base64.c - Base64 with support for multiple variants
> *
> * Copyright (c) 2020 Hannes Reinecke, SUSE
> *
> * Based on the base64url routines from fs/crypto/fname.c
> - * (which are using the URL-safe base64 encoding),
> - * modified to use the standard coding table from RFC4648 section 4.
> + * (which are using the URL-safe Base64 encoding),
> + * modified to support multiple Base64 variants.
> */
>
> #include <linux/kernel.h>
> @@ -15,26 +15,31 @@
> #include <linux/string.h>
> #include <linux/base64.h>
>
> -static const char base64_table[65] =
> - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
> +static const char base64_tables[][65] = {
> + [BASE64_STD] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
> + [BASE64_URLSAFE] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",
> + [BASE64_IMAP] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,",
> +};
>
> /**
> - * base64_encode() - base64-encode some binary data
> + * base64_encode() - Base64-encode some binary data
> * @src: the binary data to encode
> * @srclen: the length of @src in bytes
> - * @dst: (output) the base64-encoded string. Not NUL-terminated.
> + * @dst: (output) the Base64-encoded string. Not NUL-terminated.
> + * @padding: whether to append '=' padding characters
> + * @variant: which base64 variant to use
> *
> - * Encodes data using base64 encoding, i.e. the "Base 64 Encoding" specified
> - * by RFC 4648, including the '='-padding.
> + * Encodes data using the selected Base64 variant.
> *
> - * Return: the length of the resulting base64-encoded string in bytes.
> + * Return: the length of the resulting Base64-encoded string in bytes.
> */
> -int base64_encode(const u8 *src, int srclen, char *dst)
> +int base64_encode(const u8 *src, int srclen, char *dst, bool padding, enum base64_variant variant)
> {
> u32 ac = 0;
> int bits = 0;
> int i;
> char *cp = dst;
> + const char *base64_table = base64_tables[variant];
>
> for (i = 0; i < srclen; i++) {
> ac = (ac << 8) | src[i];
> @@ -48,44 +53,49 @@ int base64_encode(const u8 *src, int srclen, char *dst)
> *cp++ = base64_table[(ac << (6 - bits)) & 0x3f];
> bits -= 6;
> }
> - while (bits < 0) {
> - *cp++ = '=';
> - bits += 2;
> + if (padding) {
> + while (bits < 0) {
> + *cp++ = '=';
> + bits += 2;
> + }
> }
> return cp - dst;
> }
> EXPORT_SYMBOL_GPL(base64_encode);
>
> /**
> - * base64_decode() - base64-decode a string
> + * base64_decode() - Base64-decode a string
> * @src: the string to decode. Doesn't need to be NUL-terminated.
> * @srclen: the length of @src in bytes
> * @dst: (output) the decoded binary data
> + * @padding: whether to append '=' padding characters
> + * @variant: which base64 variant to use
> *
> - * Decodes a string using base64 encoding, i.e. the "Base 64 Encoding"
> - * specified by RFC 4648, including the '='-padding.
> + * Decodes a string using the selected Base64 variant.
> *
> * This implementation hasn't been optimized for performance.
> *
> * Return: the length of the resulting decoded binary data in bytes,
> - * or -1 if the string isn't a valid base64 string.
> + * or -1 if the string isn't a valid Base64 string.
> */
> -int base64_decode(const char *src, int srclen, u8 *dst)
> +int base64_decode(const char *src, int srclen, u8 *dst, bool padding, enum base64_variant variant)
> {
> u32 ac = 0;
> int bits = 0;
> int i;
> u8 *bp = dst;
> + const char *base64_table = base64_tables[variant];
>
> for (i = 0; i < srclen; i++) {
> const char *p = strchr(base64_table, src[i]);
> -
> - if (src[i] == '=') {
> - ac = (ac << 6);
> - bits += 6;
> - if (bits >= 8)
> - bits -= 8;
> - continue;
> + if (padding) {
> + if (src[i] == '=') {
> + ac = (ac << 6);
> + bits += 6;
> + if (bits >= 8)
> + bits -= 8;
> + continue;
> + }
> }
> if (p == NULL || src[i] == 0)
> return -1;
next prev parent reply other threads:[~2025-11-14 9:13 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-14 5:58 [PATCH v5 0/6] lib/base64: add generic encoder/decoder, migrate users Guan-Chun Wu
2025-11-14 6:00 ` [PATCH v5 1/6] lib/base64: Add support for multiple variants Guan-Chun Wu
2025-11-14 9:13 ` David Laight [this message]
2025-11-14 6:01 ` [PATCH v5 2/6] lib/base64: Optimize base64_decode() with reverse lookup tables Guan-Chun Wu
2025-11-14 9:14 ` David Laight
2025-11-14 6:01 ` [PATCH v5 3/6] lib/base64: rework encode/decode for speed and stricter validation Guan-Chun Wu
2025-11-14 9:18 ` David Laight
2025-11-16 10:28 ` Guan-Chun Wu
2025-11-17 17:46 ` Andrew Morton
2025-11-18 10:38 ` Andy Shevchenko
2025-11-18 17:24 ` Andrew Morton
2025-11-14 6:01 ` [PATCH v5 4/6] lib: add KUnit tests for base64 encoding/decoding Guan-Chun Wu
2025-11-14 6:02 ` [PATCH v5 5/6] fscrypt: replace local base64url helpers with lib/base64 Guan-Chun Wu
2025-11-14 6:02 ` [PATCH v5 6/6] ceph: replace local base64 " Guan-Chun Wu
2025-11-14 18:07 ` Viacheslav Dubeyko
2025-11-16 10:36 ` Guan-Chun Wu
2025-11-17 19:42 ` Viacheslav Dubeyko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251114091348.562c5965@pumpkin \
--to=david.laight.linux@gmail.com \
--cc=409411716@gms.tku.edu.tw \
--cc=akpm@linux-foundation.org \
--cc=andriy.shevchenko@intel.com \
--cc=axboe@kernel.dk \
--cc=ceph-devel@vger.kernel.org \
--cc=ebiggers@kernel.org \
--cc=hch@lst.de \
--cc=home7438072@gmail.com \
--cc=idryomov@gmail.com \
--cc=jaegeuk@kernel.org \
--cc=kbusch@kernel.org \
--cc=linux-fscrypt@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-nvme@lists.infradead.org \
--cc=sagi@grimberg.me \
--cc=tytso@mit.edu \
--cc=visitorckw@gmail.com \
--cc=xiubli@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.