summaryrefslogtreecommitdiffstats
path: root/lib/libcbor/src/cbor/internal/encoders.c
diff options
context:
space:
mode:
authordjm <djm@openbsd.org>2019-11-14 21:11:34 +0000
committerdjm <djm@openbsd.org>2019-11-14 21:11:34 +0000
commitda0d961c2c28322a016c9e47e9898b8a67695a06 (patch)
tree98cc58b7052570a785fb26702de946f8f6519f3a /lib/libcbor/src/cbor/internal/encoders.c
parentAdd missing cross-reference to NOTES section. (diff)
downloadwireguard-openbsd-da0d961c2c28322a016c9e47e9898b8a67695a06.tar.xz
wireguard-openbsd-da0d961c2c28322a016c9e47e9898b8a67695a06.zip
Add libcbor; an implementation of the Concise Binary Object
Representation (CBOR) encoding format defined in RFC7049. This is a dependency of libfido2, that we'll use for U2F/FIDO support in OpenSSH. feedback and "Looks good enough to me" deraadt@
Diffstat (limited to 'lib/libcbor/src/cbor/internal/encoders.c')
-rw-r--r--lib/libcbor/src/cbor/internal/encoders.c112
1 files changed, 112 insertions, 0 deletions
diff --git a/lib/libcbor/src/cbor/internal/encoders.c b/lib/libcbor/src/cbor/internal/encoders.c
new file mode 100644
index 00000000000..478b3885cb1
--- /dev/null
+++ b/lib/libcbor/src/cbor/internal/encoders.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com>
+ *
+ * libcbor is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See LICENSE for details.
+ */
+
+#include "encoders.h"
+
+#if HAVE_ENDIAN_H
+#include <endian.h>
+#endif
+
+size_t _cbor_encode_uint8(uint8_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset)
+{
+ if (value <= 23) {
+ if (buffer_size >= 1) {
+ buffer[0] = value + offset;
+ return 1;
+ }
+ } else {
+ if (buffer_size >= 2) {
+ buffer[0] = 0x18 + offset;
+ buffer[1] = value;
+ return 2;
+ }
+ }
+ return 0;
+}
+
+size_t _cbor_encode_uint16(uint16_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset)
+{
+ if (buffer_size >= 3) {
+ buffer[0] = 0x19 + offset;
+
+#ifdef HAVE_ENDIAN_H
+ *(uint16_t *) &buffer[1] = htobe16(value);
+#else
+ #ifdef IS_BIG_ENDIAN
+ *(uint16_t *) &buffer[1] = value;
+ #else
+ buffer[1] = value >> 8;
+ buffer[2] = value;
+ #endif
+#endif
+
+ return 3;
+ } else
+ return 0;
+}
+
+size_t _cbor_encode_uint32(uint32_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset)
+{
+ if (buffer_size >= 5) {
+ buffer[0] = 0x1A + offset;
+
+#ifdef HAVE_ENDIAN_H
+ *(uint32_t *) &buffer[1] = htobe32(value);
+#else
+ #ifdef IS_BIG_ENDIAN
+ *(uint32_t *) &buffer[1] = value;
+ #else
+ buffer[1] = value >> 24;
+ buffer[2] = value >> 16;
+ buffer[3] = value >> 8;
+ buffer[4] = value;
+ #endif
+#endif
+
+ return 5;
+ } else
+ return 0;
+}
+
+size_t _cbor_encode_uint64(uint64_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset)
+{
+ if (buffer_size >= 9) {
+ buffer[0] = 0x1B + offset;
+
+#ifdef HAVE_ENDIAN_H
+ *(uint64_t *) &buffer[1] = htobe64(value);
+#else
+ #ifdef IS_BIG_ENDIAN
+ *(uint64_t *) &buffer[1] = value;
+ #else
+ buffer[1] = value >> 56;
+ buffer[2] = value >> 48;
+ buffer[3] = value >> 40;
+ buffer[4] = value >> 32;
+ buffer[5] = value >> 24;
+ buffer[6] = value >> 16;
+ buffer[7] = value >> 8;
+ buffer[8] = value;
+ #endif
+#endif
+
+ return 9;
+ } else
+ return 0;
+}
+
+size_t _cbor_encode_uint(uint64_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset)
+{
+ if (value <= UINT16_MAX) if (value <= UINT8_MAX)
+ return _cbor_encode_uint8((uint8_t) value, buffer, buffer_size, offset);
+ else
+ return _cbor_encode_uint16((uint16_t) value, buffer, buffer_size, offset);
+ else if (value <= UINT32_MAX)
+ return _cbor_encode_uint32((uint32_t) value, buffer, buffer_size, offset);
+ else
+ return _cbor_encode_uint64((uint64_t) value, buffer, buffer_size, offset);
+}