summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2022-06-10 20:20:26 -0700
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-06-13 21:49:39 +0000
commitb8544e962b698979bb81ef06f4a8e3dcdf654a35 (patch)
tree4cd83753209875ad3c2dab8d352da335ab5d61c0
parent606ff61be661ec90e16110360790dd1abb13e205 (diff)
downloadchrome-ec-b8544e962b698979bb81ef06f4a8e3dcdf654a35.tar.gz
base64: add implementation for encoding binary into base64
In the Cr50 tree there is no really output devices other than console where base64 encoding output could be sent, and there is no use for decoding function yet. Add the encoding function implementation, make it possible to send output to console by default and optionally to a passed in function. Add test to verify proper encoding. BUG=b:234745585 TEST='make run-base64' succeeds. Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Change-Id: Ibc10681632bc649320d602e319e4f634b4b3a1d1 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3701141 Reviewed-by: Mary Ruthven <mruthven@chromium.org> Reviewed-by: Vadim Sukhomlinov <sukhomlinov@chromium.org>
-rw-r--r--common/base64.c104
-rw-r--r--common/build.mk1
-rw-r--r--include/base64.h24
-rw-r--r--include/config.h3
-rw-r--r--test/base64.c57
-rw-r--r--test/base64.tasklist9
-rw-r--r--test/build.mk2
-rw-r--r--test/test_config.h4
8 files changed, 204 insertions, 0 deletions
diff --git a/common/base64.c b/common/base64.c
new file mode 100644
index 0000000000..e3f979cce2
--- /dev/null
+++ b/common/base64.c
@@ -0,0 +1,104 @@
+/* Copyright 2022 The Chromium OS Authors.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Yet another from scratch implementation of base64 encoding. */
+
+#include "base64.h"
+#include "common.h"
+#include "console.h"
+
+/*
+ * Translation Table as described in RFC1113
+ */
+static const char cb64[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+/* Number of bytes converted into the output block of characters. */
+#define BASE64_BYTE_SIZE 3
+
+/* Number of characters in a single encoded block. */
+#define BASE64_CHAR_SIZE 4
+
+/*
+ * encodeblock
+ *
+ * encode up to 3 bytes 6-bit characters, pad output with '=' if input is
+ * shorter than 3 bytes.
+ *
+ * @param in: pointer to the input bytes
+ * @param out: pointer to the output, guaranteed to be 4 bytes long.
+ * @param len: number of input bytes to process, guaranteed to be in 1..3
+ * range.
+ */
+static void encodeblock(const uint8_t *in, uint8_t *out, size_t len)
+{
+ uint32_t input;
+ int i;
+ int limit;
+
+ /* Place input bytes into a 32 bit value in big endian format. */
+ input = 0;
+ for (i = 0; i < len; i++)
+ ((uint8_t *)&input)[3 - i] = in[i];
+
+ /*
+ * Map each 6 bit quantity of the input into an output character, make
+ * sure partial bit quantities are mapped too in case input is shorter
+ * than 3 bytes.
+ */
+ limit = ((len * 8) + 7) / 6;
+ for (i = 0; i < limit; i++) {
+ int index = (input >> (26 - i * 6)) & 0x3f;
+
+ out[i] = cb64[index];
+ }
+
+ while (i < BASE64_CHAR_SIZE)
+ out[i++] = '=';
+}
+
+/* Pass one output character to the caller. */
+static void printit(char c, void (*f)(char c))
+{
+ if (f)
+ f(c);
+ else
+ ccprintf("%c", c);
+}
+
+#define LINE_SIZE 64
+void base64_encode_to_console(const uint8_t *data, size_t size,
+ void (*func)(char c))
+{
+ uint8_t out[4];
+ int blocksout;
+
+ blocksout = 0;
+ while (size) {
+ int i;
+ int in_length;
+
+ if (size > BASE64_BYTE_SIZE)
+ in_length = BASE64_BYTE_SIZE;
+ else
+ in_length = size;
+
+ encodeblock(data, out, in_length);
+ for (i = 0; i < sizeof(out); i++)
+ printit(out[i], func);
+
+ blocksout++;
+ data += in_length;
+ size -= in_length;
+ if (blocksout >= (LINE_SIZE / BASE64_CHAR_SIZE)) {
+ printit('\n', func);
+ blocksout = 0;
+ if (!func)
+ cflush();
+ }
+ }
+ if (blocksout)
+ printit('\n', func);
+}
diff --git a/common/build.mk b/common/build.mk
index 9d484bcb1b..771b75da1a 100644
--- a/common/build.mk
+++ b/common/build.mk
@@ -35,6 +35,7 @@ common-$(CONFIG_AUDIO_CODEC_I2S_RX)+=audio_codec_i2s_rx.o
common-$(CONFIG_AUDIO_CODEC_WOV)+=audio_codec_wov.o
common-$(CONFIG_BACKLIGHT_LID)+=backlight_lid.o
common-$(CONFIG_BASE32)+=base32.o
+common-$(CONFIG_BASE64)+=base64.o
common-$(CONFIG_DETACHABLE_BASE)+=base_state.o
common-$(CONFIG_CAPSENSE)+=capsense.o
common-$(CONFIG_CASE_CLOSED_DEBUG_V1)+=ccd_config.o
diff --git a/include/base64.h b/include/base64.h
new file mode 100644
index 0000000000..f64c78ebee
--- /dev/null
+++ b/include/base64.h
@@ -0,0 +1,24 @@
+#ifndef __CR50_INCLUDE_B64_H
+#define __CR50_INCLUDE_B64_H
+/* Copyright 2022 The Chromium OS Authors.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ */
+
+#include "util.h"
+
+/*
+ * A function to print base64 encoding of a binary blob on the console.
+ *
+ * For testing purposed an alternative output function could be supplied.
+ *
+ * @param data - pointer to data to encode.
+ * @param size - size of the data area
+ * @param func - optional, function to pass to the characters to print. If
+ * NULL the output is printed on the console.
+ */
+void base64_encode_to_console(const uint8_t *data, size_t size,
+ void (*func)(char c));
+
+#endif /* ! __CR50_INCLUDE_B64_H */
diff --git a/include/config.h b/include/config.h
index f48a640d68..19a4552f2a 100644
--- a/include/config.h
+++ b/include/config.h
@@ -323,6 +323,9 @@
/* Support base32 text encoding */
#undef CONFIG_BASE32
+/* Support base64 text encoding */
+#undef CONFIG_BASE64
+
/*****************************************************************************/
/* Battery config */
diff --git a/test/base64.c b/test/base64.c
new file mode 100644
index 0000000000..9ded346c5d
--- /dev/null
+++ b/test/base64.c
@@ -0,0 +1,57 @@
+/* Copyright 2022 The Chromium OS Authors.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Test Base-64 encoding.
+ */
+
+#include <stdio.h>
+#include "base64.h"
+#include "common.h"
+#include "test_util.h"
+#include "util.h"
+
+static char results[100];
+static size_t index;
+
+static void printer(char c)
+{
+ if (index < sizeof(results))
+ results[index++] = c;
+}
+
+static int test_encode(void)
+{
+ const char *data = "\x00\x01\x02\x80\xf0\ffabcdefghij "
+ "random text to wrap at 64 characters at most";
+ const struct {
+ size_t len; /* Length of input. */
+ const char *encoding; /* Expected encoding. */
+ } cases[] = {
+ { 1, "AA==\n" },
+ { 2, "AAE=\n" },
+ { 3, "AAEC\n" },
+ { 4, "AAECgA==\n" },
+ { 60, "AAECgPAMZmFiY2RlZmdoaWogcmFuZG9tIHRleHQg"
+ "dG8gd3JhcCBhdCA2NCBjaGFy\nYWN0ZXJzIGF0IG1v\n" },
+ };
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(cases); i++) {
+ index = 0;
+ base64_encode_to_console(data, cases[i].len, printer);
+ TEST_ASSERT(index == strlen(cases[i].encoding));
+ TEST_ASSERT(memcmp(cases[i].encoding, results, index) == 0);
+ }
+
+ return EC_SUCCESS;
+}
+
+void run_test(void)
+{
+ test_reset();
+
+ RUN_TEST(test_encode);
+
+ test_print_result();
+}
diff --git a/test/base64.tasklist b/test/base64.tasklist
new file mode 100644
index 0000000000..243a3b683f
--- /dev/null
+++ b/test/base64.tasklist
@@ -0,0 +1,9 @@
+/* Copyright 2022 The Chromium OS Authors.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**
+ * See CONFIG_TASK_LIST in config.h for details.
+ */
+#define CONFIG_TEST_TASK_LIST /* No test task */
diff --git a/test/build.mk b/test/build.mk
index 4072459707..16638acaae 100644
--- a/test/build.mk
+++ b/test/build.mk
@@ -13,6 +13,7 @@ test-list-host=$(TEST_LIST_HOST)
else
test-list-host = aes
test-list-host += base32
+test-list-host += base64
test-list-host += button
test-list-host += cec
test-list-host += console_edit
@@ -58,6 +59,7 @@ endif
aes-y=aes.o
base32-y=base32.o
+base64-y=base64.o
button-y=button.o
cec-y=cec.o
console_edit-y=console_edit.o
diff --git a/test/test_config.h b/test/test_config.h
index f7b222302f..493d255626 100644
--- a/test/test_config.h
+++ b/test/test_config.h
@@ -27,6 +27,10 @@
#define CONFIG_BASE32
#endif
+#ifdef TEST_BASE64
+#define CONFIG_BASE64
+#endif
+
#ifdef TEST_FLASH_LOG
#define CONFIG_CRC8
#define CONFIG_FLASH_ERASED_VALUE32 (-1U)