diff options
author | 2019-11-14 21:11:34 +0000 | |
---|---|---|
committer | 2019-11-14 21:11:34 +0000 | |
commit | da0d961c2c28322a016c9e47e9898b8a67695a06 (patch) | |
tree | 98cc58b7052570a785fb26702de946f8f6519f3a /lib/libcbor/src/cbor/internal/encoders.c | |
parent | Add missing cross-reference to NOTES section. (diff) | |
download | wireguard-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.c | 112 |
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); +} |