1 /*  Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
2 
3     This program is free software: you can redistribute it and/or modify
4     it under the terms of the GNU General Public License as published by
5     the Free Software Foundation, either version 3 of the License, or
6     (at your option) any later version.
7 
8     This program is distributed in the hope that it will be useful,
9     but WITHOUT ANY WARRANTY; without even the implied warranty of
10     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11     GNU General Public License for more details.
12 
13     You should have received a copy of the GNU General Public License
14     along with this program.  If not, see <https://www.gnu.org/licenses/>.
15  */
16 
17 #include <assert.h>
18 #include <string.h>
19 
20 #include "libdnssec/shared/bignum.h"
21 
skip_leading_zeroes(dnssec_binary_t * value)22 static void skip_leading_zeroes(dnssec_binary_t *value)
23 {
24 	while (value->size > 0 && value->data[0] == 0) {
25 		value->data += 1;
26 		value->size -= 1;
27 	}
28 }
29 
bignum_size_u(const dnssec_binary_t * _value)30 size_t bignum_size_u(const dnssec_binary_t *_value)
31 {
32 	dnssec_binary_t value = *_value;
33 	skip_leading_zeroes(&value);
34 
35 	if (value.size == 0) {
36 		return value.size + 1;
37 	} else {
38 		return value.size;
39 	}
40 }
41 
bignum_size_s(const dnssec_binary_t * _value)42 size_t bignum_size_s(const dnssec_binary_t *_value)
43 {
44 	dnssec_binary_t value = *_value;
45 	skip_leading_zeroes(&value);
46 
47 	if (value.size == 0 || value.data[0] & 0x80) {
48 		return value.size + 1;
49 	} else {
50 		return value.size;
51 	}
52 }
53 
bignum_write(wire_ctx_t * ctx,size_t width,const dnssec_binary_t * _value)54 void bignum_write(wire_ctx_t *ctx, size_t width, const dnssec_binary_t *_value)
55 {
56 	dnssec_binary_t value = *_value;
57 	skip_leading_zeroes(&value);
58 
59 	size_t padding_len = width - value.size;
60 	if (padding_len > 0) {
61 		wire_ctx_clear(ctx, padding_len);
62 	}
63 	wire_ctx_write(ctx, value.data, value.size);
64 }
65