From: Hannes Reinecke <hare@suse.de>
To: Christoph Hellwig <hch@lst.de>
Cc: Sagi Grimberg <sagi@grimberg.me>,
Keith Busch <keith.busch@wdc.com>,
Herbert Xu <herbert@gondor.apana.org.au>,
"David S . Miller" <davem@davemloft.net>,
linux-nvme@lists.infradead.org, linux-crypto@vger.kernel.org,
Hannes Reinecke <hare@suse.de>
Subject: [PATCH 04/13] lib/base64: RFC4648-compliant base64 encoding
Date: Tue, 10 Aug 2021 14:42:21 +0200 [thread overview]
Message-ID: <20210810124230.12161-5-hare@suse.de> (raw)
In-Reply-To: <20210810124230.12161-1-hare@suse.de>
Add RFC4648-compliant base64 encoding and decoding routines.
Signed-off-by: Hannes Reinecke <hare@suse.de>
---
include/linux/base64.h | 16 ++++++
lib/Makefile | 2 +-
lib/base64.c | 115 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 132 insertions(+), 1 deletion(-)
create mode 100644 include/linux/base64.h
create mode 100644 lib/base64.c
diff --git a/include/linux/base64.h b/include/linux/base64.h
new file mode 100644
index 000000000000..660d4cb1ef31
--- /dev/null
+++ b/include/linux/base64.h
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * base64 encoding, lifted from fs/crypto/fname.c.
+ */
+
+#ifndef _LINUX_BASE64_H
+#define _LINUX_BASE64_H
+
+#include <linux/types.h>
+
+#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);
+
+#endif /* _LINUX_BASE64_H */
diff --git a/lib/Makefile b/lib/Makefile
index 6d765d5fb8ac..92a428aa0e5f 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -46,7 +46,7 @@ obj-y += bcd.o sort.o parser.o debug_locks.o random32.o \
bust_spinlocks.o kasprintf.o bitmap.o scatterlist.o \
list_sort.o uuid.o iov_iter.o clz_ctz.o \
bsearch.o find_bit.o llist.o memweight.o kfifo.o \
- percpu-refcount.o rhashtable.o \
+ percpu-refcount.o rhashtable.o base64.o \
once.o refcount.o usercopy.o errseq.o bucket_locks.o \
generic-radix-tree.o
obj-$(CONFIG_STRING_SELFTEST) += test_string.o
diff --git a/lib/base64.c b/lib/base64.c
new file mode 100644
index 000000000000..ef120cecceba
--- /dev/null
+++ b/lib/base64.c
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * base64.c - RFC4648-compliant base64 encoding
+ *
+ * Copyright (c) 2020 Hannes Reinecke, SUSE
+ *
+ * Based on the (slightly non-standard) base64 routines
+ * from fs/crypto/fname.c, but using the RFC-mandated
+ * coding table.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/export.h>
+#include <linux/string.h>
+#include <linux/base64.h>
+
+static const char lookup_table[65] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+/**
+ * base64_encode() - base64-encode some bytes
+ * @src: the bytes to encode
+ * @len: number of bytes to encode
+ * @dst: (output) the base64-encoded string. Not NUL-terminated.
+ *
+ * Encodes the input string using characters from the set [A-Za-z0-9+,].
+ * The encoded string is roughly 4/3 times the size of the input string.
+ *
+ * Return: length of the encoded string
+ */
+int base64_encode(const u8 *src, int len, char *dst)
+{
+ int i, bits = 0;
+ u32 ac = 0;
+ char *cp = dst;
+
+ for (i = 0; i < len; i++) {
+ ac = (ac << 8) | src[i];
+ bits += 8;
+ if (bits < 24)
+ continue;
+ do {
+ bits -= 6;
+ *cp++ = lookup_table[(ac >> bits) & 0x3f];
+ } while (bits);
+ ac = 0;
+ }
+ if (bits) {
+ int more = 0;
+
+ if (bits < 16)
+ more = 2;
+ ac = (ac << (2 + more));
+ bits += (2 + more);
+ do {
+ bits -= 6;
+ *cp++ = lookup_table[(ac >> bits) & 0x3f];
+ } while (bits);
+ *cp++ = '=';
+ if (more)
+ *cp++ = '=';
+ }
+
+ return cp - dst;
+}
+EXPORT_SYMBOL_GPL(base64_encode);
+
+/**
+ * base64_decode() - base64-decode some bytes
+ * @src: the base64-encoded string to decode
+ * @len: number of bytes to decode
+ * @dst: (output) the decoded bytes.
+ *
+ * Decodes the base64-encoded bytes @src according to RFC 4648.
+ *
+ * Return: number of decoded bytes
+ */
+int base64_decode(const char *src, int len, u8 *dst)
+{
+ int i, bits = 0, pad = 0;
+ u32 ac = 0;
+ size_t dst_len = 0;
+
+ for (i = 0; i < len; i++) {
+ int c, p = -1;
+
+ if (src[i] == '=') {
+ pad++;
+ if (i + 1 < len && src[i + 1] == '=')
+ pad++;
+ break;
+ }
+ for (c = 0; c < strlen(lookup_table); c++) {
+ if (src[i] == lookup_table[c]) {
+ p = c;
+ break;
+ }
+ }
+ if (p < 0)
+ break;
+ ac = (ac << 6) | p;
+ bits += 6;
+ if (bits < 24)
+ continue;
+ while (bits) {
+ bits -= 8;
+ dst[dst_len++] = (ac >> bits) & 0xff;
+ }
+ ac = 0;
+ }
+ dst_len -= pad;
+ return dst_len;
+}
+EXPORT_SYMBOL_GPL(base64_decode);
--
2.29.2
_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme
next prev parent reply other threads:[~2021-08-10 12:44 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-08-10 12:42 [PATCHv2 00/13] nvme: In-band authentication support Hannes Reinecke
2021-08-10 12:42 ` [PATCH 01/13] crypto: add crypto_has_shash() Hannes Reinecke
2021-08-10 12:42 ` [PATCH 02/13] crypto: add crypto_has_kpp() Hannes Reinecke
2021-08-10 12:42 ` [PATCH 03/13] crypto/ffdhe: Finite Field DH Ephemeral Parameters Hannes Reinecke
2021-08-10 12:42 ` Hannes Reinecke [this message]
2021-08-10 19:13 ` [PATCH 04/13] lib/base64: RFC4648-compliant base64 encoding Eric Biggers
2021-08-11 5:57 ` Hannes Reinecke
2021-08-10 12:42 ` [PATCH 05/13] nvme: add definitions for NVMe In-Band authentication Hannes Reinecke
2021-08-10 12:42 ` [PATCH 06/13] nvme-fabrics: decode 'authentication required' connect error Hannes Reinecke
2021-08-10 12:42 ` [PATCH 07/13] nvme: Implement In-Band authentication Hannes Reinecke
2021-08-10 12:42 ` [PATCH 08/13] nvme-auth: Diffie-Hellman key exchange support Hannes Reinecke
2021-08-10 12:42 ` [PATCH 09/13] nvmet: Parse fabrics commands on all queues Hannes Reinecke
2021-08-10 12:42 ` [PATCH 10/13] nvmet: Implement basic In-Band Authentication Hannes Reinecke
2021-08-10 12:42 ` [PATCH 11/13] nvmet-auth: Diffie-Hellman key exchange support Hannes Reinecke
2021-08-10 12:42 ` [PATCH 12/13] nvmet-auth: expire authentication sessions Hannes Reinecke
2021-08-10 12:42 ` [PATCH 13/13] nvme: add non-standard ECDH and curve25517 algorithms Hannes Reinecke
2021-08-12 12:25 ` Christoph Hellwig
2021-08-12 12:51 ` Hannes Reinecke
2021-08-17 21:21 ` [PATCHv2 00/13] nvme: In-band authentication support Sagi Grimberg
2021-08-18 5:44 ` Hannes Reinecke
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=20210810124230.12161-5-hare@suse.de \
--to=hare@suse.de \
--cc=davem@davemloft.net \
--cc=hch@lst.de \
--cc=herbert@gondor.apana.org.au \
--cc=keith.busch@wdc.com \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-nvme@lists.infradead.org \
--cc=sagi@grimberg.me \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox