Skip to content

Commit a965a25

Browse files
committed
Add a few little-endian functions to CBS/CBB.
Change-Id: Idf962d587f031c1feed541a43be55dc9a65ca444 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/39607 Reviewed-by: David Benjamin <[email protected]>
1 parent 8973007 commit a965a25

File tree

5 files changed

+87
-2
lines changed

5 files changed

+87
-2
lines changed

crypto/bytestring/bytestring_test.cc

+14-1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,14 @@ TEST(CBSTest, GetUint) {
6767
EXPECT_EQ(0x13u, u8);
6868
EXPECT_FALSE(CBS_get_u8(&data, &u8));
6969
EXPECT_FALSE(CBS_get_last_u8(&data, &u8));
70+
71+
CBS_init(&data, kData, sizeof(kData));
72+
ASSERT_TRUE(CBS_get_u16le(&data, &u16));
73+
EXPECT_EQ(0x0201u, u16);
74+
ASSERT_TRUE(CBS_get_u32le(&data, &u32));
75+
EXPECT_EQ(0x06050403u, u32);
76+
ASSERT_TRUE(CBS_get_u64le(&data, &u64));
77+
EXPECT_EQ(0x0e0d0c0b0a090807u, u64);
7078
}
7179

7280
TEST(CBSTest, GetPrefixed) {
@@ -316,7 +324,9 @@ TEST(CBBTest, InitUninitialized) {
316324
TEST(CBBTest, Basic) {
317325
static const uint8_t kExpected[] = {1, 2, 3, 4, 5, 6, 7,
318326
8, 9, 0xa, 0xb, 0xc, 0xd, 0xe,
319-
0xf, 0x10, 0x11, 0x12, 0x13, 0x14};
327+
0xf, 0x10, 0x11, 0x12, 0x13, 0x14, 3, 2,
328+
10, 9, 8, 7, 0x12, 0x11, 0x10,
329+
0xf, 0xe, 0xd, 0xc, 0xb};
320330
uint8_t *buf;
321331
size_t buf_len;
322332

@@ -331,6 +341,9 @@ TEST(CBBTest, Basic) {
331341
ASSERT_TRUE(CBB_add_u32(cbb.get(), 0x708090a));
332342
ASSERT_TRUE(CBB_add_u64(cbb.get(), 0xb0c0d0e0f101112));
333343
ASSERT_TRUE(CBB_add_bytes(cbb.get(), (const uint8_t *)"\x13\x14", 2));
344+
ASSERT_TRUE(CBB_add_u16le(cbb.get(), 0x203));
345+
ASSERT_TRUE(CBB_add_u32le(cbb.get(), 0x708090a));
346+
ASSERT_TRUE(CBB_add_u64le(cbb.get(), 0xb0c0d0e0f101112));
334347
ASSERT_TRUE(CBB_finish(cbb.get(), &buf, &buf_len));
335348

336349
bssl::UniquePtr<uint8_t> scoper(buf);

crypto/bytestring/cbb.c

+12
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,10 @@ int CBB_add_u16(CBB *cbb, uint16_t value) {
447447
return cbb_buffer_add_u(cbb->base, value, 2);
448448
}
449449

450+
int CBB_add_u16le(CBB *cbb, uint16_t value) {
451+
return CBB_add_u16(cbb, CRYPTO_bswap2(value));
452+
}
453+
450454
int CBB_add_u24(CBB *cbb, uint32_t value) {
451455
if (!CBB_flush(cbb)) {
452456
return 0;
@@ -463,13 +467,21 @@ int CBB_add_u32(CBB *cbb, uint32_t value) {
463467
return cbb_buffer_add_u(cbb->base, value, 4);
464468
}
465469

470+
int CBB_add_u32le(CBB *cbb, uint32_t value) {
471+
return CBB_add_u32(cbb, CRYPTO_bswap4(value));
472+
}
473+
466474
int CBB_add_u64(CBB *cbb, uint64_t value) {
467475
if (!CBB_flush(cbb)) {
468476
return 0;
469477
}
470478
return cbb_buffer_add_u(cbb->base, value, 8);
471479
}
472480

481+
int CBB_add_u64le(CBB *cbb, uint64_t value) {
482+
return CBB_add_u64(cbb, CRYPTO_bswap8(value));
483+
}
484+
473485
void CBB_discard_child(CBB *cbb) {
474486
if (cbb->child == NULL) {
475487
return;

crypto/bytestring/cbs.c

+24
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,14 @@ int CBS_get_u16(CBS *cbs, uint16_t *out) {
120120
return 1;
121121
}
122122

123+
int CBS_get_u16le(CBS *cbs, uint16_t *out) {
124+
if (!CBS_get_u16(cbs, out)) {
125+
return 0;
126+
}
127+
*out = CRYPTO_bswap2(*out);
128+
return 1;
129+
}
130+
123131
int CBS_get_u24(CBS *cbs, uint32_t *out) {
124132
uint64_t v;
125133
if (!cbs_get_u(cbs, &v, 3)) {
@@ -138,10 +146,26 @@ int CBS_get_u32(CBS *cbs, uint32_t *out) {
138146
return 1;
139147
}
140148

149+
int CBS_get_u32le(CBS *cbs, uint32_t *out) {
150+
if (!CBS_get_u32(cbs, out)) {
151+
return 0;
152+
}
153+
*out = CRYPTO_bswap4(*out);
154+
return 1;
155+
}
156+
141157
int CBS_get_u64(CBS *cbs, uint64_t *out) {
142158
return cbs_get_u(cbs, out, 8);
143159
}
144160

161+
int CBS_get_u64le(CBS *cbs, uint64_t *out) {
162+
if (!cbs_get_u(cbs, out, 8)) {
163+
return 0;
164+
}
165+
*out = CRYPTO_bswap8(*out);
166+
return 1;
167+
}
168+
145169
int CBS_get_last_u8(CBS *cbs, uint8_t *out) {
146170
if (cbs->len == 0) {
147171
return 0;

crypto/internal.h

+13-1
Original file line numberDiff line numberDiff line change
@@ -689,6 +689,10 @@ OPENSSL_EXPORT void CRYPTO_free_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class,
689689
// Endianness conversions.
690690

691691
#if defined(__GNUC__) && __GNUC__ >= 2
692+
static inline uint16_t CRYPTO_bswap2(uint16_t x) {
693+
return __builtin_bswap16(x);
694+
}
695+
692696
static inline uint32_t CRYPTO_bswap4(uint32_t x) {
693697
return __builtin_bswap32(x);
694698
}
@@ -700,7 +704,11 @@ static inline uint64_t CRYPTO_bswap8(uint64_t x) {
700704
OPENSSL_MSVC_PRAGMA(warning(push, 3))
701705
#include <stdlib.h>
702706
OPENSSL_MSVC_PRAGMA(warning(pop))
703-
#pragma intrinsic(_byteswap_uint64, _byteswap_ulong)
707+
#pragma intrinsic(_byteswap_uint64, _byteswap_ulong, _byteswap_ushort)
708+
static inline uint16_t CRYPTO_bswap2(uint16_t x) {
709+
return _byteswap_ushort(x);
710+
}
711+
704712
static inline uint32_t CRYPTO_bswap4(uint32_t x) {
705713
return _byteswap_ulong(x);
706714
}
@@ -709,6 +717,10 @@ static inline uint64_t CRYPTO_bswap8(uint64_t x) {
709717
return _byteswap_uint64(x);
710718
}
711719
#else
720+
static inline uint16_t CRYPTO_bswap2(uint16_t x) {
721+
return (x >> 8) | (x << 8);
722+
}
723+
712724
static inline uint32_t CRYPTO_bswap4(uint32_t x) {
713725
x = (x >> 16) | (x << 16);
714726
x = ((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8);

include/openssl/bytestring.h

+24
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ OPENSSL_EXPORT int CBS_get_u8(CBS *cbs, uint8_t *out);
102102
// advances |cbs|. It returns one on success and zero on error.
103103
OPENSSL_EXPORT int CBS_get_u16(CBS *cbs, uint16_t *out);
104104

105+
// CBS_get_u16le sets |*out| to the next, little-endian uint16_t from |cbs| and
106+
// advances |cbs|. It returns one on success and zero on error.
107+
OPENSSL_EXPORT int CBS_get_u16le(CBS *cbs, uint16_t *out);
108+
105109
// CBS_get_u24 sets |*out| to the next, big-endian 24-bit value from |cbs| and
106110
// advances |cbs|. It returns one on success and zero on error.
107111
OPENSSL_EXPORT int CBS_get_u24(CBS *cbs, uint32_t *out);
@@ -110,10 +114,18 @@ OPENSSL_EXPORT int CBS_get_u24(CBS *cbs, uint32_t *out);
110114
// and advances |cbs|. It returns one on success and zero on error.
111115
OPENSSL_EXPORT int CBS_get_u32(CBS *cbs, uint32_t *out);
112116

117+
// CBS_get_u32le sets |*out| to the next, little-endian uint32_t value from
118+
// |cbs| and advances |cbs|. It returns one on success and zero on error.
119+
OPENSSL_EXPORT int CBS_get_u32le(CBS *cbs, uint32_t *out);
120+
113121
// CBS_get_u64 sets |*out| to the next, big-endian uint64_t value from |cbs|
114122
// and advances |cbs|. It returns one on success and zero on error.
115123
OPENSSL_EXPORT int CBS_get_u64(CBS *cbs, uint64_t *out);
116124

125+
// CBS_get_u64le sets |*out| to the next, little-endian uint64_t value from
126+
// |cbs| and advances |cbs|. It returns one on success and zero on error.
127+
OPENSSL_EXPORT int CBS_get_u64le(CBS *cbs, uint64_t *out);
128+
117129
// CBS_get_last_u8 sets |*out| to the last uint8_t from |cbs| and shortens
118130
// |cbs|. It returns one on success and zero on error.
119131
OPENSSL_EXPORT int CBS_get_last_u8(CBS *cbs, uint8_t *out);
@@ -460,6 +472,10 @@ OPENSSL_EXPORT int CBB_add_u8(CBB *cbb, uint8_t value);
460472
// returns one on success and zero otherwise.
461473
OPENSSL_EXPORT int CBB_add_u16(CBB *cbb, uint16_t value);
462474

475+
// CBB_add_u16le appends a 16-bit, little-endian number from |value| to |cbb|.
476+
// It returns one on success and zero otherwise.
477+
OPENSSL_EXPORT int CBB_add_u16le(CBB *cbb, uint16_t value);
478+
463479
// CBB_add_u24 appends a 24-bit, big-endian number from |value| to |cbb|. It
464480
// returns one on success and zero otherwise.
465481
OPENSSL_EXPORT int CBB_add_u24(CBB *cbb, uint32_t value);
@@ -468,10 +484,18 @@ OPENSSL_EXPORT int CBB_add_u24(CBB *cbb, uint32_t value);
468484
// returns one on success and zero otherwise.
469485
OPENSSL_EXPORT int CBB_add_u32(CBB *cbb, uint32_t value);
470486

487+
// CBB_add_u32le appends a 32-bit, little-endian number from |value| to |cbb|.
488+
// It returns one on success and zero otherwise.
489+
OPENSSL_EXPORT int CBB_add_u32le(CBB *cbb, uint32_t value);
490+
471491
// CBB_add_u64 appends a 64-bit, big-endian number from |value| to |cbb|. It
472492
// returns one on success and zero otherwise.
473493
OPENSSL_EXPORT int CBB_add_u64(CBB *cbb, uint64_t value);
474494

495+
// CBB_add_u64le appends a 64-bit, little-endian number from |value| to |cbb|.
496+
// It returns one on success and zero otherwise.
497+
OPENSSL_EXPORT int CBB_add_u64le(CBB *cbb, uint64_t value);
498+
475499
// CBB_discard_child discards the current unflushed child of |cbb|. Neither the
476500
// child's contents nor the length prefix will be included in the output.
477501
OPENSSL_EXPORT void CBB_discard_child(CBB *cbb);

0 commit comments

Comments
 (0)