feat(crypto): extend DER functionality in trezor-crypto
What changed, and why it matters
This is a routine feature addition to Trezor's cryptographic library. It adds helper functions for comparing DER-encoded data items and reading an item with an expected tag, plus a constant for OID tags and minor const-correctness cleanups. There is no indication of a security bug being fixed.
No security action required; treat as normal code-quality/feature commit.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit extends the DER/buffer utilities in trezor-crypto: introduces der_equal() for comparing two DER_ITEMs by tag and content, der_read_item_expected() for reading a DER item and verifying its identifier tag, DER_OID (0x06) constant, and const qualifiers on read-only BUFFER_READER/BUFFER_WRITER accessors. der_reencode_int() is refactored to use the new expected-tag helper. No bounds-checking or parsing logic changes that would alter security properties.
Changed components
crypto/buffer.ccrypto/buffer.hcrypto/der.ccrypto/der.hInspect captured patch +31 / −9
diff --git a/crypto/buffer.c b/crypto/buffer.c
index 1306224a..dbad030c 100644
--- a/crypto/buffer.c
+++ b/crypto/buffer.c
@@ -38,7 +38,7 @@ void buffer_writer_init(BUFFER_WRITER *writer, uint8_t *data, size_t size) {
writer->pos = 0;
}
-size_t buffer_remaining(BUFFER_READER *buf) {
+size_t buffer_remaining(const BUFFER_READER *buf) {
if ((buf->data == NULL) || (buf->pos > buf->size)) {
return 0;
}
@@ -46,7 +46,7 @@ size_t buffer_remaining(BUFFER_READER *buf) {
return buf->size - buf->pos;
}
-bool buffer_ptr(BUFFER_READER *buf, const uint8_t **ptr) {
+bool buffer_ptr(const BUFFER_READER *buf, const uint8_t **ptr) {
if ((buf->data == NULL) || (buf->pos > buf->size)) {
return false;
}
@@ -139,4 +139,4 @@ bool buffer_write_buffer(BUFFER_WRITER *dest, BUFFER_READER *src) {
return true;
}
-size_t buffer_written_size(BUFFER_WRITER *writer) { return writer->pos; }
+size_t buffer_written_size(const BUFFER_WRITER *writer) { return writer->pos; }
diff --git a/crypto/buffer.h b/crypto/buffer.h
index cfc9cd3d..1a75af28 100644
--- a/crypto/buffer.h
+++ b/crypto/buffer.h
@@ -45,8 +45,8 @@ typedef struct {
void buffer_reader_init(BUFFER_READER *buf, const uint8_t *data, size_t size);
void buffer_writer_init(BUFFER_WRITER *buf, uint8_t *data, size_t size);
-size_t __wur buffer_remaining(BUFFER_READER *buf);
-bool __wur buffer_ptr(BUFFER_READER *buf, const uint8_t **ptr);
+size_t __wur buffer_remaining(const BUFFER_READER *buf);
+bool __wur buffer_ptr(const BUFFER_READER *buf, const uint8_t **ptr);
bool __wur buffer_peek(const BUFFER_READER *buf, uint8_t *byte);
bool __wur buffer_get(BUFFER_READER *buf, uint8_t *byte);
bool __wur buffer_seek(BUFFER_READER *buf, size_t pos);
@@ -57,6 +57,6 @@ bool __wur buffer_put(BUFFER_WRITER *writer, uint8_t byte);
bool __wur buffer_write_array(BUFFER_WRITER *writer, const uint8_t *src,
size_t size);
bool __wur buffer_write_buffer(BUFFER_WRITER *dest, BUFFER_READER *src);
-size_t __wur buffer_written_size(BUFFER_WRITER *writer);
+size_t __wur buffer_written_size(const BUFFER_WRITER *writer);
#endif // __BUFFER_H
diff --git a/crypto/der.c b/crypto/der.c
index e863ef85..0940dfa2 100644
--- a/crypto/der.c
+++ b/crypto/der.c
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2023 Trezor Company s.r.o.
+ * Copyright (c) 2023, 2026 Trezor Company s.r.o.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the "Software"),
@@ -21,6 +21,7 @@
*/
#include "der.h"
+#include <string.h>
bool der_read_length(BUFFER_READER *buf, size_t *len) {
// Read the initial octet.
@@ -107,13 +108,30 @@ bool der_read_item(BUFFER_READER *buf, DER_ITEM *item) {
return buffer_seek(&item->buf, header_size);
}
+bool der_read_item_expected(BUFFER_READER *buf, const uint8_t expected_id,
+ DER_ITEM *item) {
+ return der_read_item(buf, item) && item->id == expected_id;
+}
+
+bool der_equal(const DER_ITEM *a, const DER_ITEM *b) {
+ if (a->id != b->id) {
+ return false;
+ }
+
+ if (a->buf.size != b->buf.size) {
+ return false;
+ }
+
+ return memcmp(a->buf.data, b->buf.data, a->buf.size) == 0;
+}
+
// Reencode a positive integer which violates the encoding rules in Rec. ITU-T
// X.690, section 8.3.2 (the bits of the first octet and bit 8 of the second
// octet shall not all be zero).
bool der_reencode_int(BUFFER_READER *reader, BUFFER_WRITER *writer) {
// Read a DER-encoded integer.
DER_ITEM item = {0};
- if (!der_read_item(reader, &item) || item.id != DER_INTEGER) {
+ if (!der_read_item_expected(reader, DER_INTEGER, &item)) {
return false;
}
diff --git a/crypto/der.h b/crypto/der.h
index 2836a3c6..74fbec89 100644
--- a/crypto/der.h
+++ b/crypto/der.h
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2023 Trezor Company s.r.o.
+ * Copyright (c) 2023, 2026 Trezor Company s.r.o.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the "Software"),
@@ -37,6 +37,7 @@
#define DER_INTEGER 0x02
#define DER_BIT_STRING 0x03
#define DER_OCTET_STRING 0x04
+#define DER_OID 0x06
// Struct representing a DER-encoded ASN.1 data value.
typedef struct {
@@ -51,6 +52,9 @@ typedef struct {
bool __wur der_read_length(BUFFER_READER *buf, size_t *len);
bool __wur der_write_length(BUFFER_WRITER *buf, size_t len);
bool __wur der_read_item(BUFFER_READER *buf, DER_ITEM *item);
+bool __wur der_read_item_expected(BUFFER_READER *buf, const uint8_t expected_id,
+ DER_ITEM *item);
+bool __wur der_equal(const DER_ITEM *a, const DER_ITEM *b);
bool __wur der_reencode_int(BUFFER_READER *reader, BUFFER_WRITER *writer);
#endif // __DER_H
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.