Add functions to write simple CBOR values
The unit value, null, and the boolean values, true and false, have their
own CBOR encoding. Expose functions to write these values.
Change-Id: I8528f89eb949ffe985cea17ed9110be3672b3d6e
Reviewed-on: https://pigweed-review.googlesource.com/c/open-dice/+/39340
Commit-Queue: Andrew Scull <ascull@google.com>
Pigweed-Auto-Submit: Andrew Scull <ascull@google.com>
Reviewed-by: Darren Krahn <dkrahn@google.com>
diff --git a/include/dice/cbor_writer.h b/include/dice/cbor_writer.h
index 8652eaf..9835c6e 100644
--- a/include/dice/cbor_writer.h
+++ b/include/dice/cbor_writer.h
@@ -47,6 +47,9 @@
size_t CborWriteTstr(const char* str, struct CborOut* out);
size_t CborWriteArray(size_t num_elements, struct CborOut* out);
size_t CborWriteMap(size_t num_pairs, struct CborOut* out);
+size_t CborWriteFalse(struct CborOut* out);
+size_t CborWriteTrue(struct CborOut* out);
+size_t CborWriteNull(struct CborOut* out);
#ifdef __cplusplus
} // extern "C"
diff --git a/src/cbor_writer.c b/src/cbor_writer.c
index 7ec1c67..b5517d9 100644
--- a/src/cbor_writer.c
+++ b/src/cbor_writer.c
@@ -26,6 +26,8 @@
CBOR_TYPE_TSTR = 3,
CBOR_TYPE_ARRAY = 4,
CBOR_TYPE_MAP = 5,
+ // Type 6, tags, are not supported.
+ CBOR_TYPE_SIMPLE = 7,
};
static size_t CborWriteType(enum CborType type, uint64_t val,
@@ -132,3 +134,15 @@
size_t CborWriteMap(size_t num_pairs, struct CborOut* out) {
return CborWriteType(CBOR_TYPE_MAP, num_pairs, out);
}
+
+size_t CborWriteFalse(struct CborOut* out) {
+ return CborWriteType(CBOR_TYPE_SIMPLE, /*val=*/20, out);
+}
+
+size_t CborWriteTrue(struct CborOut* out) {
+ return CborWriteType(CBOR_TYPE_SIMPLE, /*val=*/21, out);
+}
+
+size_t CborWriteNull(struct CborOut* out) {
+ return CborWriteType(CBOR_TYPE_SIMPLE, /*val=*/22, out);
+}
diff --git a/src/cbor_writer_fuzzer.cc b/src/cbor_writer_fuzzer.cc
index 42db6dd..fc1b739 100644
--- a/src/cbor_writer_fuzzer.cc
+++ b/src/cbor_writer_fuzzer.cc
@@ -23,13 +23,16 @@
WriteTstr,
WriteArray,
WriteMap,
- kMaxValue = WriteMap,
+ WriteFalse,
+ WriteTrue,
+ WriteNull,
+ kMaxValue = WriteNull,
};
// Use data sizes that exceed the 16-bit range without being excessive.
constexpr size_t kMaxDataSize = 0xffff + 0x5000;
constexpr size_t kMaxBufferSize = kMaxDataSize * 3;
-constexpr size_t kIterations = 10;
+constexpr size_t kIterations = 16;
} // namespace
@@ -73,6 +76,15 @@
CborWriteMap(num_pairs, &out);
break;
}
+ case WriteFalse:
+ CborWriteNull(&out);
+ break;
+ case WriteTrue:
+ CborWriteNull(&out);
+ break;
+ case WriteNull:
+ CborWriteNull(&out);
+ break;
}
}
diff --git a/src/cbor_writer_test.cc b/src/cbor_writer_test.cc
index 4cb9711..ed0cdc8 100644
--- a/src/cbor_writer_test.cc
+++ b/src/cbor_writer_test.cc
@@ -159,6 +159,39 @@
EXPECT_EQ(0, memcmp(buffer, kExpectedEncoding, sizeof(kExpectedEncoding)));
}
+TEST(CborWriterTest, FalseEncoding) {
+ const uint8_t kExpectedEncoding[] = {0xf4};
+ uint8_t buffer[64];
+ CborOut out = {
+ .buffer = buffer,
+ .size = sizeof(buffer),
+ };
+ EXPECT_EQ(sizeof(kExpectedEncoding), CborWriteFalse(&out));
+ EXPECT_EQ(0, memcmp(buffer, kExpectedEncoding, sizeof(kExpectedEncoding)));
+}
+
+TEST(CborWriterTest, TrueEncoding) {
+ const uint8_t kExpectedEncoding[] = {0xf5};
+ uint8_t buffer[64];
+ CborOut out = {
+ .buffer = buffer,
+ .size = sizeof(buffer),
+ };
+ EXPECT_EQ(sizeof(kExpectedEncoding), CborWriteTrue(&out));
+ EXPECT_EQ(0, memcmp(buffer, kExpectedEncoding, sizeof(kExpectedEncoding)));
+}
+
+TEST(CborWriterTest, NullEncoding) {
+ const uint8_t kExpectedEncoding[] = {0xf6};
+ uint8_t buffer[64];
+ CborOut out = {
+ .buffer = buffer,
+ .size = sizeof(buffer),
+ };
+ EXPECT_EQ(sizeof(kExpectedEncoding), CborWriteNull(&out));
+ EXPECT_EQ(0, memcmp(buffer, kExpectedEncoding, sizeof(kExpectedEncoding)));
+}
+
TEST(CborWriterTest, CborOutInvariants) {
const uint8_t kData[] = {0xb2, 0x34, 0x75, 0x92, 0x52};
uint8_t buffer[64];
@@ -171,8 +204,11 @@
EXPECT_EQ(9u, CborWriteTstr("A string", &out));
EXPECT_EQ(1u, CborWriteArray(/*num_elements=*/16, &out));
EXPECT_EQ(2u, CborWriteMap(/*num_pairs=*/35, &out));
+ EXPECT_EQ(1u, CborWriteFalse(&out));
+ EXPECT_EQ(1u, CborWriteTrue(&out));
+ EXPECT_EQ(1u, CborWriteNull(&out));
// Offset is the cumulative size.
- EXPECT_EQ(3 + 6 + 9 + 1 + 2u, out.offset);
+ EXPECT_EQ(3 + 6 + 9 + 1 + 2 + 1 + 1 + 1u, out.offset);
// Buffer and size are unchanged.
EXPECT_EQ(buffer, out.buffer);
EXPECT_EQ(sizeof(buffer), out.size);
@@ -184,13 +220,16 @@
.buffer = nullptr,
.size = 2, // Ignored.
};
+ EXPECT_EQ(1u, CborWriteNull(&out));
+ EXPECT_EQ(1u, CborWriteTrue(&out));
+ EXPECT_EQ(1u, CborWriteFalse(&out));
EXPECT_EQ(3u, CborWriteMap(/*num_pairs=*/623, &out));
EXPECT_EQ(5u, CborWriteArray(/*num_elements=*/70000, &out));
EXPECT_EQ(7u, CborWriteTstr("length", &out));
EXPECT_EQ(8u, CborWriteBstr(sizeof(kData), kData, &out));
EXPECT_EQ(5u, CborWriteInt(-10002000, &out));
// Offset is the cumulative size.
- EXPECT_EQ(3 + 5 + 7 + 8 + 5u, out.offset);
+ EXPECT_EQ(1 + 1 + 1 + 3 + 5 + 7 + 8 + 5u, out.offset);
// Buffer and size are unchanged.
EXPECT_EQ(nullptr, out.buffer);
EXPECT_EQ(2u, out.size);
@@ -214,6 +253,13 @@
EXPECT_EQ(0u, CborWriteArray(/*num_elements=*/563, &out));
out.offset = 0;
EXPECT_EQ(0u, CborWriteMap(/*num_pairs=*/29, &out));
+ out.size = 0;
+ out.offset = 0;
+ EXPECT_EQ(0u, CborWriteFalse(&out));
+ out.offset = 0;
+ EXPECT_EQ(0u, CborWriteTrue(&out));
+ out.offset = 0;
+ EXPECT_EQ(0u, CborWriteNull(&out));
}
TEST(CborWriterTest, NotEnoughRemainingSpace) {
@@ -234,6 +280,12 @@
EXPECT_EQ(0u, CborWriteArray(/*num_elements=*/352, &out));
out.offset = sizeof(buffer) - 1;
EXPECT_EQ(0u, CborWriteMap(/*num_pairs=*/73, &out));
+ out.offset = sizeof(buffer);
+ EXPECT_EQ(0u, CborWriteFalse(&out));
+ out.offset = sizeof(buffer);
+ EXPECT_EQ(0u, CborWriteTrue(&out));
+ out.offset = sizeof(buffer);
+ EXPECT_EQ(0u, CborWriteNull(&out));
}
TEST(CborWriterTest, OffsetOverflow) {
@@ -254,6 +306,12 @@
EXPECT_EQ(0u, CborWriteArray(/*num_elements=*/41, &out));
out.offset = SIZE_MAX - 1;
EXPECT_EQ(0u, CborWriteMap(/*num_pairs=*/998844, &out));
+ out.offset = SIZE_MAX;
+ EXPECT_EQ(0u, CborWriteFalse(&out));
+ out.offset = SIZE_MAX;
+ EXPECT_EQ(0u, CborWriteTrue(&out));
+ out.offset = SIZE_MAX;
+ EXPECT_EQ(0u, CborWriteNull(&out));
}
TEST(CborWriterTest, MeasurementOffsetOverflow) {
@@ -272,6 +330,12 @@
EXPECT_EQ(0u, CborWriteArray(/*num_elements=*/8368257314, &out));
out.offset = SIZE_MAX - 1;
EXPECT_EQ(0u, CborWriteMap(/*num_pairs=*/92, &out));
+ out.offset = SIZE_MAX;
+ EXPECT_EQ(0u, CborWriteFalse(&out));
+ out.offset = SIZE_MAX;
+ EXPECT_EQ(0u, CborWriteTrue(&out));
+ out.offset = SIZE_MAX;
+ EXPECT_EQ(0u, CborWriteNull(&out));
}
}