From 31b623186f3a2d3de7ab5c7bfb54396a435c8f29 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 16 Nov 2023 07:28:56 +0100 Subject: [PATCH] libnvme: Add base64 functions Copied over from nvme-cli. Signed-off-by: Hannes Reinecke --- src/meson.build | 1 + src/nvme/base64.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++ src/nvme/base64.h | 8 ++++ 3 files changed, 103 insertions(+) create mode 100644 src/nvme/base64.c create mode 100644 src/nvme/base64.h diff --git a/src/meson.build b/src/meson.build index e8b667c2..92e39d44 100644 --- a/src/meson.build +++ b/src/meson.build @@ -15,6 +15,7 @@ sources = [ 'nvme/log.c', 'nvme/tree.c', 'nvme/util.c', + 'nvme/base64.c' ] mi_sources = [ diff --git a/src/nvme/base64.c b/src/nvme/base64.c new file mode 100644 index 00000000..5fae8290 --- /dev/null +++ b/src/nvme/base64.c @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * base64.c - RFC4648-compliant base64 encoding + * + * Copyright (c) 2020 SUSE LLC + * + * Author: Hannes Reinecke + */ + +#include +#include +#include +#include + +static const char base64_table[65] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +/** + * base64_encode() - base64-encode some bytes + * @src: the bytes to encode + * @srclen: 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 unsigned char *src, int srclen, char *dst) +{ + int i, bits = 0; + u_int32_t ac = 0; + char *cp = dst; + + for (i = 0; i < srclen; i++) { + ac = (ac << 8) | src[i]; + bits += 8; + do { + bits -= 6; + *cp++ = base64_table[(ac >> bits) & 0x3f]; + } while (bits >= 6); + } + if (bits) { + *cp++ = base64_table[(ac << (6 - bits)) & 0x3f]; + bits -= 6; + } + while (bits < 0) { + *cp++ = '='; + bits += 2; + } + + return cp - dst; +} + +/** + * 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 srclen, unsigned char *dst) +{ + u_int32_t ac = 0; + int i, bits = 0; + unsigned char *bp = dst; + + 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 (!p || !src[i]) + return -EINVAL; + ac = (ac << 6) | (p - base64_table); + bits += 6; + if (bits >= 8) { + bits -= 8; + *bp++ = (unsigned char)(ac >> bits); + } + } + if (ac && ((1 << bits) - 1)) + return -EAGAIN; + + return bp - dst; +} diff --git a/src/nvme/base64.h b/src/nvme/base64.h new file mode 100644 index 00000000..c0f62e2b --- /dev/null +++ b/src/nvme/base64.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef _BASE64_H +#define _BASE64_H + +int base64_encode(const unsigned char *src, int len, char *dst); +int base64_decode(const char *src, int len, unsigned char *dst); + +#endif /* _BASE64_H */ -- 2.50.1