aboutsummaryrefslogtreecommitdiffhomepage
path: root/pyecsca/codegen/asn1
diff options
context:
space:
mode:
authorJ08nY2019-11-27 20:34:58 +0100
committerJ08nY2019-11-27 20:34:58 +0100
commit32a4874abfbaff8cb4ee2d31fe71bcc3499e52dc (patch)
tree1203a322d7488ef51b4de2d34c6e0c2871ea68a5 /pyecsca/codegen/asn1
parentbb00fee9702155586e674b9d6a3b838bd54baac2 (diff)
downloadpyecsca-codegen-32a4874abfbaff8cb4ee2d31fe71bcc3499e52dc.tar.gz
pyecsca-codegen-32a4874abfbaff8cb4ee2d31fe71bcc3499e52dc.tar.zst
pyecsca-codegen-32a4874abfbaff8cb4ee2d31fe71bcc3499e52dc.zip
Reorganize files, implement proper main.
Diffstat (limited to 'pyecsca/codegen/asn1')
-rw-r--r--pyecsca/codegen/asn1/asn1.c97
-rw-r--r--pyecsca/codegen/asn1/asn1.h13
2 files changed, 110 insertions, 0 deletions
diff --git a/pyecsca/codegen/asn1/asn1.c b/pyecsca/codegen/asn1/asn1.c
new file mode 100644
index 0000000..3fd1f5f
--- /dev/null
+++ b/pyecsca/codegen/asn1/asn1.c
@@ -0,0 +1,97 @@
+#include "asn1.h"
+
+#include <stdlib.h>
+
+uint8_t *asn1_der_encode(const bn_t *r, const bn_t *s, size_t *result_len) {
+ uint8_t r_len = (uint8_t) bn_to_bin_size(r);
+ uint8_t s_len = (uint8_t) bn_to_bin_size(s);
+
+ // Pad with one zero byte in case most-significant bit of top byte is one.
+ uint8_t r_length = r_len + (bn_get_bit(r, r_len * 8) ? 1 : 0);
+ uint8_t s_length = s_len + (bn_get_bit(s, s_len * 8) ? 1 : 0);
+
+ // R and S are < 128 bytes, so 1 byte tag + 1 byte len + len bytes value
+ size_t seq_value_len = 2 + r_length + 2 + s_length;
+ size_t whole_len = seq_value_len;
+
+ // The SEQUENCE length might be >= 128, so more bytes of length
+ size_t seq_len_len = 0;
+ if (seq_value_len >= 128) {
+ size_t s = seq_value_len;
+ do {
+ seq_len_len++;
+ } while ((s = s >> 8));
+ }
+ // seq_len_len bytes for length and one for length of length
+ whole_len += seq_len_len + 1;
+
+ // 1 byte tag for SEQUENCE
+ whole_len += 1;
+
+ uint8_t *data = malloc(whole_len);
+ size_t i = 0;
+ data[i++] = 0x30; // SEQUENCE
+ if (seq_value_len < 128) {
+ data[i++] = (uint8_t) seq_value_len;
+ } else {
+ data[i++] = (uint8_t) (seq_len_len | (1 << 7));
+ for (size_t j = 0; j < seq_len_len; ++j) {
+ data[i++] = (uint8_t) (seq_value_len & (0xff << (8 * (seq_len_len - j - 1))));
+ }
+ }
+ data[i++] = 0x02; //INTEGER
+ data[i++] = r_length;
+ if (bn_get_bit(r, r_len * 8)) {
+ data[i++] = 0;
+ }
+ bn_to_bin(r, data + i);
+ i += r_len;
+ data[i++] = 0x02; //INTEGER
+ data[i++] = s_length;
+ if (bn_get_bit(s, s_len * 8)) {
+ data[i++] = 0;
+ }
+ bn_to_bin(s, data + i);
+ i += s_len;
+
+ return data;
+}
+
+bool asn1_der_decode(const uint8_t *sig, size_t sig_len, bn_t *r, bn_t *s) {
+ size_t i = 0;
+ if (sig[i++] != 0x30) {//SEQUENCE
+ return false;
+ }
+ size_t seq_value_len = 0;
+ if (!(sig[i] & 0x80)) {
+ seq_value_len = sig[i++];
+ } else {
+ size_t seq_len_len = sig[i++] & 0x7f;
+ while (seq_len_len > 0) {
+ seq_value_len |= (sig[i++] << (seq_len_len - 1));
+ seq_len_len--;
+ }
+ }
+
+ if (sig[i++] != 0x02) {//INTEGER
+ return false;
+ }
+ size_t r_length = sig[i++];
+ size_t r_offset = i;
+ i += r_length;
+
+ if (sig[i++] != 0x02) {//INTEGER
+ return false;
+ }
+ size_t s_length = sig[i++];
+ size_t s_offset = i;
+ i += s_length;
+
+ if (i != sig_len) {
+ return false;
+ }
+
+ bn_from_bin(sig + r_offset, r_length, r);
+ bn_from_bin(sig + s_offset, s_length, s);
+ return true;
+} \ No newline at end of file
diff --git a/pyecsca/codegen/asn1/asn1.h b/pyecsca/codegen/asn1/asn1.h
new file mode 100644
index 0000000..691755c
--- /dev/null
+++ b/pyecsca/codegen/asn1/asn1.h
@@ -0,0 +1,13 @@
+#ifndef ASN1_H_
+#define ASN1_H_
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+#include "bn.h"
+
+uint8_t *asn1_der_encode(const bn_t *r, const bn_t *s, size_t *result_len);
+
+bool asn1_der_decode(const uint8_t *sig, size_t sig_len, bn_t *r, bn_t *s);
+
+#endif //ASN1_H_ \ No newline at end of file