aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/aes/src/hex.c
diff options
context:
space:
mode:
authorEgor Tensin <egor@tensin.name>2026-07-22 23:48:16 +0200
committerEgor Tensin <egor@tensin.name>2026-07-23 10:54:24 +0200
commitd6ba2397803c5f2d6a39a8684239c53f84e73b80 (patch)
treec33b3fe76890e05ddea32071f461f892f9d17e6a /aes/src/hex.c
parentaesxx/utils: add tests for invalid inputs (diff)
downloadaes-tools-d6ba2397803c5f2d6a39a8684239c53f84e73b80.tar.gz
aes-tools-d6ba2397803c5f2d6a39a8684239c53f84e73b80.zip
aes: always require full inputs
I.e. no 31 digit for 128-bit blocks, reuse code, etc. Also, generalize hex string parsing.
Diffstat (limited to 'aes/src/hex.c')
-rw-r--r--aes/src/hex.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/aes/src/hex.c b/aes/src/hex.c
new file mode 100644
index 0000000..62b6e5a
--- /dev/null
+++ b/aes/src/hex.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2026 Egor Tensin <Egor.Tensin@gmail.com>
+ * This file is part of the "AES tools" project.
+ * For details, see https://github.com/egor-tensin/aes-tools.
+ * Distributed under the MIT License.
+ */
+
+#include <aes/all.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+AES_StatusCode aes_parse_hex_string(
+ unsigned char* dest,
+ const char* src,
+ size_t numof_bytes,
+ AES_ErrorDetails* err_details
+) {
+ if (dest == NULL)
+ return aes_error_null_argument(err_details, "dest");
+ if (src == NULL)
+ return aes_error_null_argument(err_details, "src");
+
+ char what[30];
+ snprintf(what, sizeof(what), "a %zu-byte hex string", numof_bytes);
+
+ const char* cursor = src;
+
+ for (size_t i = 0; i < numof_bytes; ++i) {
+ int n;
+ unsigned int byte;
+ if (sscanf(cursor, "%2x%n", &byte, &n) != 1 || n != 2)
+ return aes_error_parse(err_details, src, what);
+ dest[i] = (unsigned char)byte;
+ cursor += n;
+ }
+
+ if (*cursor != '\0')
+ return aes_error_parse(err_details, src, what);
+
+ return AES_SUCCESS;
+}