diff --git a/src/0-exec/struct-delta.c.h b/src/0-exec/struct-delta.c.h index e8d452b..9639431 100644 --- a/src/0-exec/struct-delta.c.h +++ b/src/0-exec/struct-delta.c.h @@ -7,6 +7,7 @@ static inline void *DeltaAdd(void *base, ptrdiff_t offset) { + if( !base ) return NULL; return (uint8_t *)base + offset; } diff --git a/src/2-asn1/der-codec.c b/src/2-asn1/der-codec.c index 40c8cf9..2bde178 100644 --- a/src/2-asn1/der-codec.c +++ b/src/2-asn1/der-codec.c @@ -182,6 +182,95 @@ size_t ber_push_tag(uint8_t **stack, uint32_t val, int pc) else return 0; } +size_t ber_put_tag(uint8_t *buf, uint32_t val, int pc) +{ + uint8_t tagflags = ((6 & (val >> 28)) | (pc & 1)) << 5; + val &= BER_TLV_TAG_MAX; + + if( val < (uint32_t)1 << 5 ) + { + if( buf ) *buf++ = tagflags | val; + return 1; + } + + else if( val < (uint32_t)1 << (7 * 1) ) + { + if( buf ) + { + *buf++ = tagflags | 31; + *buf++ = val; + } + return 2; + } + + else if( val < (uint32_t)1 << (7 * 2) ) + { + if( buf ) + { + *buf++ = tagflags | 31; + *buf++ = (0x7f & (val >> 7)) | 0x80; + *buf++ = 0x7f & val; + } + return 3; + } + + else if( val < (uint32_t)1 << (7 * 3) ) + { + if( buf ) + { + *buf++ = tagflags | 31; + *buf++ = (0x7f & (val >> 14)) | 0x80; + *buf++ = (0x7f & (val >> 7)) | 0x80; + *buf++ = 0x7f & val; + } + return 4; + } + + else if( val < (uint32_t)1 << (7 * 4) ) + { + if( buf ) + { + *buf++ = tagflags | 31; + *buf++ = (0x7f & (val >> 21)) | 0x80; + *buf++ = (0x7f & (val >> 14)) | 0x80; + *buf++ = (0x7f & (val >> 7)) | 0x80; + *buf++ = 0x7f & val; + } + return 5; + } + + else return 0; +} + +size_t ber_put_len(uint8_t *buf, size_t val) +{ + if( val < 0x80 ) + { + if( buf ) + { + *buf++ = val; + } + return 1; + } + + else + { + size_t ret = 0, i; + while( (val >> (8*ret)) > 0 ) ret++; + + if( buf ) + { + *buf++ = 0x80 | ret; + for(i=ret; i-->0; ) + { + *buf++ = val >> (8 * i); + } + } + + return ret + 1; + } +} + void *ber_util_splice_insert( void *buf, size_t len1, ptrdiff_t offset, size_t len2) @@ -324,3 +413,45 @@ IntPtr ber_tlv_encode_integer(BER_TLV_ENCODING_FUNC_PARAMS) return ret; } + +IntPtr ber_tlv_put_integer(BER_TLV_ENCODING_FUNC_PARAMS) +{ + size_t ret = 0, hdr; + size_t i; + const vlong_t *w = any; + + // 2023-10-05: + // this function has error return values, + // so the [ber-int-err-chk:2021-02-13] note + // doesn't apply to it. + + // This function handles only unsigned integers. + ret = w->c * sizeof(uint32_t) + 1; + for(i=w->c; --i < w->c; ) + { + if( w->v[i] < UINT32_C(1) << 31 ) ret--; + if( w->v[i] < UINT32_C(1) << 23 ) ret--; + if( w->v[i] < UINT32_C(1) << 15 ) ret--; + if( w->v[i] < UINT32_C(1) << 7 ) ret--; + if( w->v[i] ) break; + } + + hdr = ber_put_tag(NULL, BER_TLV_TAG_UNI(2), 0) + ber_put_len(NULL, ret); + + if( !enc ) return ret + hdr; + if( enclen < ret + hdr ) return -1; + + enc += ber_put_tag(enc, BER_TLV_TAG_UNI(2), 0); + enc += ber_put_len(enc, ret); + + for(i=0; ic ? (w->v[u] >> v) : 0; + } + + return ret + hdr; +} diff --git a/src/2-asn1/der-codec.h b/src/2-asn1/der-codec.h index 49345c2..74fd714 100644 --- a/src/2-asn1/der-codec.h +++ b/src/2-asn1/der-codec.h @@ -43,6 +43,14 @@ void *ber_util_splice_insert( void *buf, size_t len1, ptrdiff_t offset, size_t len2); +// 2023-10-05: +// New (supposedly) more efficient way to encode DER. +// The following 2 functions assume the initial value +// of ``buf'' can hold both of their maximum output. +#define TAGLEN_MAX 16 +size_t ber_put_tag(uint8_t *buf, uint32_t val, int pc); +size_t ber_put_len(uint8_t *buf, size_t val); + // // A ``ber_tlv_{de,en}coding_func'' have 2 passes, // @@ -87,4 +95,6 @@ typedef IntPtr (*ber_tlv_encoding_func)(BER_TLV_ENCODING_FUNC_PARAMS); IntPtr ber_tlv_decode_integer(BER_TLV_DECODING_FUNC_PARAMS); IntPtr ber_tlv_encode_integer(BER_TLV_ENCODING_FUNC_PARAMS); +IntPtr ber_tlv_put_integer(BER_TLV_ENCODING_FUNC_PARAMS); + #endif /* MySuiteA_der_parse_h */ diff --git a/src/2-rsa/rsa-privkey-codec-der-test.c b/src/2-rsa/rsa-privkey-codec-der-test.c index 5939f34..6b5aca8 100644 --- a/src/2-rsa/rsa-privkey-codec-der-test.c +++ b/src/2-rsa/rsa-privkey-codec-der-test.c @@ -20,6 +20,8 @@ void dump_ctx_words(const uint32_t *ctx, size_t size) #define dump_ctx_words(...) ((void)0) #endif /* DUMP_CONTEXT_WORDS */ +#include "../test-utils.c.h" + int main(int argc, char *argv[]) { FILE *fp; @@ -46,7 +48,7 @@ int main(int argc, char *argv[]) // decoding test. - size = ber_tlv_decode_RSAPrivateKey(NULL, buf, len); + size = ber_tlv_decode_RSAPrivateKey(NULL, buf, len); //dumphex(buf,len); printf("1st pass decoding returned: %ld\n", size); ctx = malloc(size); @@ -62,7 +64,7 @@ int main(int argc, char *argv[]) size = ber_tlv_encode_RSAPrivateKey(ctx, NULL, 0); printf("1st pass encoding returned: %ld\n", size); - size = ber_tlv_encode_RSAPrivateKey(ctx, buf2, len); + size = ber_tlv_encode_RSAPrivateKey(ctx, buf2, len); //dumphex(buf2,len); if( memcmp(buf, buf2, len) ) { diff --git a/src/2-rsa/rsa-privkey-codec-der-test.sh b/src/2-rsa/rsa-privkey-codec-der-test.sh index 0b31a18..c661ccf 100644 --- a/src/2-rsa/rsa-privkey-codec-der-test.sh +++ b/src/2-rsa/rsa-privkey-codec-der-test.sh @@ -1,8 +1,9 @@ #!/bin/sh -optimize=true +optimize=debug testfunc() { - $exec ../tests/rsa-1440-3primes.der + #lldb --\ + $exec ../tests/rsa-1440-3primes.der } cd "$(dirname "$0")" diff --git a/src/2-rsa/rsa-privkey-writer-der.c b/src/2-rsa/rsa-privkey-writer-der.c index 1f47065..820d3bb 100644 --- a/src/2-rsa/rsa-privkey-writer-der.c +++ b/src/2-rsa/rsa-privkey-writer-der.c @@ -4,19 +4,15 @@ #include "../0-exec/struct-delta.c.h" static IntPtr ber_tlv_encode_OtherPrimeInfos( - BER_TLV_ENCODING_FUNC_PARAMS, int pass); + BER_TLV_ENCODING_FUNC_PARAMS); IntPtr ber_tlv_encode_RSAPrivateKey(BER_TLV_ENCODING_FUNC_PARAMS) { - int pass = enc ? 2 : 1; IntPtr ret = 0, subret; - uint8_t *stack = NULL; - uint8_t *ptr = enc; - size_t remain = enclen; - //- not used -// uint32_t i; - - size_t taglen; + uint8_t tlbuf[TAGLEN_MAX]; + uint8_t *ptr = tlbuf; + IntPtr t; const RSA_Priv_Base_Ctx_t *bx = any; const RSA_Priv_Ctx_Hdr_t *ctx = any; @@ -36,164 +32,69 @@ IntPtr ber_tlv_encode_RSAPrivateKey(BER_TLV_ENCODING_FUNC_PARAMS) // // version Version, -- Version ::= INTEGER ( two-prime(0), multi(1) ) -- - subret = ber_tlv_encode_integer(&ver, ptr, remain); + subret = ber_tlv_put_integer(&ver, DeltaAdd(enc, ret), enclen-ret); + if( subret < 0 ) return -1; ret += subret; - // [NULL-stack-in-pass-1]: - // stack is initialized as NULL and only set to non-NULL in pass-2 when - // actual tag and length values are to be pushed onto the stack. - // this avoids NULL-resetting in pass 1 and saves one if clause. - if( pass == 2 ) stack = enc + enclen; - taglen = 0; - taglen += ber_push_len(&stack, subret); - taglen += ber_push_tag(&stack, BER_TLV_TAG_UNI(2), 0); - - if( pass == 2 ) - { - ber_util_splice_insert(ptr, subret, (stack - ptr), taglen); - } - ret += taglen; - if( enc ) ptr += subret + taglen; remain -= subret + taglen; - // // modulus INTEGER, -- n - subret = ber_tlv_encode_integer(DeltaTo(bx, offset_n), ptr, remain); + subret = ber_tlv_put_integer( + DeltaTo(bx, offset_n), DeltaAdd(enc, ret), enclen-ret); + if( subret < 0 ) return -1; ret += subret; - if( pass == 2 ) stack = enc + enclen; // [NULL-stack-in-pass-1]. - taglen = 0; - taglen += ber_push_len(&stack, subret); - taglen += ber_push_tag(&stack, BER_TLV_TAG_UNI(2), 0); - - if( pass == 2 ) - { - ber_util_splice_insert(ptr, subret, (stack - ptr), taglen); - } - ret += taglen; - if( enc ) ptr += subret + taglen; remain -= subret + taglen; - // // publicExponent INTEGER, -- e - subret = ber_tlv_encode_integer(DeltaTo(bx, offset_e), ptr, remain); + subret = ber_tlv_put_integer( + DeltaTo(bx, offset_e), DeltaAdd(enc, ret), enclen-ret); + if( subret < 0 ) return -1; ret += subret; - if( pass == 2 ) stack = enc + enclen; // [NULL-stack-in-pass-1]. - taglen = 0; - taglen += ber_push_len(&stack, subret); - taglen += ber_push_tag(&stack, BER_TLV_TAG_UNI(2), 0); - - if( pass == 2 ) - { - ber_util_splice_insert(ptr, subret, (stack - ptr), taglen); - } - ret += taglen; - if( enc ) ptr += subret + taglen; remain -= subret + taglen; - // // privateExponent INTEGER, -- d - subret = ber_tlv_encode_integer(DeltaTo(bx, offset_d), ptr, remain); + subret = ber_tlv_put_integer( + DeltaTo(bx, offset_d), DeltaAdd(enc, ret), enclen-ret); + if( subret < 0 ) return -1; ret += subret; - if( pass == 2 ) stack = enc + enclen; // [NULL-stack-in-pass-1]. - taglen = 0; - taglen += ber_push_len(&stack, subret); - taglen += ber_push_tag(&stack, BER_TLV_TAG_UNI(2), 0); - - if( pass == 2 ) - { - ber_util_splice_insert(ptr, subret, (stack - ptr), taglen); - } - ret += taglen; - if( enc ) ptr += subret + taglen; remain -= subret + taglen; - // // prime1 INTEGER, -- p - subret = ber_tlv_encode_integer(DeltaTo(bx, offset_p), ptr, remain); + subret = ber_tlv_put_integer( + DeltaTo(bx, offset_p), DeltaAdd(enc, ret), enclen-ret); + if( subret < 0 ) return -1; ret += subret; - if( pass == 2 ) stack = enc + enclen; // [NULL-stack-in-pass-1]. - taglen = 0; - taglen += ber_push_len(&stack, subret); - taglen += ber_push_tag(&stack, BER_TLV_TAG_UNI(2), 0); - - if( pass == 2 ) - { - ber_util_splice_insert(ptr, subret, (stack - ptr), taglen); - } - ret += taglen; - if( enc ) ptr += subret + taglen; remain -= subret + taglen; - // // prime2 INTEGER, -- q - subret = ber_tlv_encode_integer(DeltaTo(bx, offset_q), ptr, remain); + subret = ber_tlv_put_integer( + DeltaTo(bx, offset_q), DeltaAdd(enc, ret), enclen-ret); + if( subret < 0 ) return -1; ret += subret; - if( pass == 2 ) stack = enc + enclen; // [NULL-stack-in-pass-1]. - taglen = 0; - taglen += ber_push_len(&stack, subret); - taglen += ber_push_tag(&stack, BER_TLV_TAG_UNI(2), 0); - - if( pass == 2 ) - { - ber_util_splice_insert(ptr, subret, (stack - ptr), taglen); - } - ret += taglen; - if( enc ) ptr += subret + taglen; remain -= subret + taglen; - // // exponent1 INTEGER, -- d mod (p-1) - subret = ber_tlv_encode_integer(DeltaTo(bx, offset_dP), ptr, remain); + subret = ber_tlv_put_integer( + DeltaTo(bx, offset_dP), DeltaAdd(enc, ret), enclen-ret); + if( subret < 0 ) return -1; ret += subret; - if( pass == 2 ) stack = enc + enclen; // [NULL-stack-in-pass-1]. - taglen = 0; - taglen += ber_push_len(&stack, subret); - taglen += ber_push_tag(&stack, BER_TLV_TAG_UNI(2), 0); - - if( pass == 2 ) - { - ber_util_splice_insert(ptr, subret, (stack - ptr), taglen); - } - ret += taglen; - if( enc ) ptr += subret + taglen; remain -= subret + taglen; - // // exponent2 INTEGER, -- d mod (q-1) - subret = ber_tlv_encode_integer(DeltaTo(bx, offset_dQ), ptr, remain); + subret = ber_tlv_put_integer( + DeltaTo(bx, offset_dQ), DeltaAdd(enc, ret), enclen-ret); + if( subret < 0 ) return -1; ret += subret; - if( pass == 2 ) stack = enc + enclen; // [NULL-stack-in-pass-1]. - taglen = 0; - taglen += ber_push_len(&stack, subret); - taglen += ber_push_tag(&stack, BER_TLV_TAG_UNI(2), 0); - - if( pass == 2 ) - { - ber_util_splice_insert(ptr, subret, (stack - ptr), taglen); - } - ret += taglen; - if( enc ) ptr += subret + taglen; remain -= subret + taglen; - // // coefficient INTEGER, -- (inverse of q) mod p - subret = ber_tlv_encode_integer(DeltaTo(bx, offset_qInv), ptr, remain); + subret = ber_tlv_put_integer( + DeltaTo(bx, offset_qInv), DeltaAdd(enc, ret), enclen-ret); + if( subret < 0 ) return -1; ret += subret; - if( pass == 2 ) stack = enc + enclen; // [NULL-stack-in-pass-1]. - taglen = 0; - taglen += ber_push_len(&stack, subret); - taglen += ber_push_tag(&stack, BER_TLV_TAG_UNI(2), 0); - - if( pass == 2 ) - { - ber_util_splice_insert(ptr, subret, (stack - ptr), taglen); - } - ret += taglen; - if( enc ) ptr += subret + taglen; remain -= subret + taglen; - if( version == 0 ) { - // do nothing. + // has nothing to do. } else if( version == 1 ) { @@ -201,38 +102,32 @@ IntPtr ber_tlv_encode_RSAPrivateKey(BER_TLV_ENCODING_FUNC_PARAMS) // otherPrimeInfos OtherPrimeInfos OPTIONAL // -- OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo -- - subret = ber_tlv_encode_OtherPrimeInfos(ctx, ptr, remain, pass); + subret = ber_tlv_encode_OtherPrimeInfos( + ctx, DeltaAdd(enc, ret), enclen-ret); + if( subret < 0 ) return -1; ret += subret; - - if( pass == 2 ) stack = enc + enclen; - taglen = 0; - taglen += ber_push_len(&stack, subret); - taglen += ber_push_tag(&stack, BER_TLV_TAG_UNI(16), 1); - - if( pass == 2 ) - { - ber_util_splice_insert(ptr, subret, (stack - ptr), taglen); - } - ret += taglen; - if( enc ) ptr += subret + taglen; remain -= subret + taglen; - } // // } -- End of "RSAPrivateKey ::= SEQUENCE". - if( pass == 2 ) stack = enc + enclen; - taglen = 0; - taglen += ber_push_len(&stack, ret); - taglen += ber_push_tag(&stack, BER_TLV_TAG_UNI(16), 1); + ptr += ber_put_tag(ptr, BER_TLV_TAG_UNI(16), 1); + ptr += ber_put_len(ptr, ret); + subret = ptr - tlbuf; - if( pass == 2 ) + if( enc ) { - ber_util_splice_insert(enc, ret, (stack - enc), taglen); + if( ret + subret > (IntPtr)enclen ) + return -1; + + for(t=ret+subret; t-->subret; ) + enc[t] = enc[t - subret]; + + for(t=subret; t-->0; ) + enc[t] = tlbuf[t]; } - ret += taglen; - return ret; + return ret + subret; } // [2021-06-06:bug]: @@ -240,103 +135,88 @@ IntPtr ber_tlv_encode_RSAPrivateKey(BER_TLV_ENCODING_FUNC_PARAMS) // more than 3 primes to emit incorrect result during testing of // the RSA keygen function. static IntPtr ber_tlv_encode_OtherPrimeInfos( - BER_TLV_ENCODING_FUNC_PARAMS, int pass) + BER_TLV_ENCODING_FUNC_PARAMS) { IntPtr ret = 0, subret, accum; - - uint8_t *stack = NULL; - uint8_t *ptr = enc; - uint8_t *ptr1; - size_t remain = enclen; uint32_t i; - size_t taglen; + uint8_t tlbuf[TAGLEN_MAX]; + uint8_t *ptr = tlbuf; + IntPtr t; const RSA_Priv_Ctx_Hdr_t *bx = any; i = 0; encode_1more_prime: - if( pass == 1 || pass == 2 ) + ptr = tlbuf; + accum = 0; + if( i >= bx->base.count_primes_other ) { - if( i >= bx->base.count_primes_other ) - return ret; + ptr += ber_put_tag(ptr, BER_TLV_TAG_UNI(16), 1); + ptr += ber_put_len(ptr, ret); + subret = ptr - tlbuf; + + if( enc ) + { + if( ret + subret > (IntPtr)enclen ) + return -1; + + for(t=ret+subret; t-->subret; ) + enc[t] = enc[t - subret]; + + for(t=subret; t-->0; ) + enc[t] = tlbuf[t]; + } + + return ret + subret; } - else return -1; // // OtherPrimeInfo ::= SEQUENCE { - ptr1 = ptr; - accum = 0; // // prime INTEGER, -- r_i - subret = ber_tlv_encode_integer( - DeltaTo(bx, primes_other[i].offset_r), ptr, remain); + subret = ber_tlv_put_integer( + DeltaTo(bx, primes_other[i].offset_r), + DeltaAdd(enc, ret+accum), enclen-ret-accum); + if( subret < 0 ) return -1; accum += subret; - if( pass == 2 ) stack = enc + enclen; // [NULL-stack-in-pass-1]. - taglen = 0; - taglen += ber_push_len(&stack, subret); - taglen += ber_push_tag(&stack, BER_TLV_TAG_UNI(2), 0); - - if( pass == 2 ) - { - ber_util_splice_insert(ptr, subret, (stack - ptr), taglen); - } - accum += taglen; - if( enc ) ptr += subret + taglen; remain -= subret + taglen; - // // exponent INTEGER, -- d_i - subret = ber_tlv_encode_integer( - DeltaTo(bx, primes_other[i].offset_d), ptr, remain); + subret = ber_tlv_put_integer( + DeltaTo(bx, primes_other[i].offset_d), + DeltaAdd(enc, ret+accum), enclen-ret-accum); + if( subret < 0 ) return -1; accum += subret; - if( pass == 2 ) stack = enc + enclen; // [NULL-stack-in-pass-1]. - taglen = 0; - taglen += ber_push_len(&stack, subret); - taglen += ber_push_tag(&stack, BER_TLV_TAG_UNI(2), 0); - - if( pass == 2 ) - { - ber_util_splice_insert(ptr, subret, (stack - ptr), taglen); - } - accum += taglen; - if( enc ) ptr += subret + taglen; remain -= subret + taglen; - // coefficient INTEGER -- t_i - subret = ber_tlv_encode_integer( - DeltaTo(bx, primes_other[i].offset_t), ptr, remain); + subret = ber_tlv_put_integer( + DeltaTo(bx, primes_other[i].offset_t), + DeltaAdd(enc, ret+accum), enclen-ret-accum); + if( subret < 0 ) return -1; accum += subret; - if( pass == 2 ) stack = enc + enclen; // [NULL-stack-in-pass-1]. - taglen = 0; - taglen += ber_push_len(&stack, subret); - taglen += ber_push_tag(&stack, BER_TLV_TAG_UNI(2), 0); - - if( pass == 2 ) - { - ber_util_splice_insert(ptr, subret, (stack - ptr), taglen); - } - accum += taglen; - if( enc ) ptr += subret + taglen; remain -= subret + taglen; - // // } -- End of "OtherPrimeInfo ::= SEQUENCE" - if( pass == 2 ) stack = enc + enclen; - taglen = 0; - taglen += ber_push_len(&stack, accum); - taglen += ber_push_tag(&stack, BER_TLV_TAG_UNI(16), 1); + ptr += ber_put_tag(ptr, BER_TLV_TAG_UNI(16), 1); + ptr += ber_put_len(ptr, accum); + subret = ptr - tlbuf; - if( pass == 2 ) + if( enc ) { - ber_util_splice_insert(ptr1, accum, (stack - ptr1), taglen); - } + if( ret + accum + subret > (IntPtr)enclen ) + return -1; - ret += accum + taglen; - if( enc ) ptr += taglen; remain -= taglen; + for(t=ret+accum+subret; t-->ret+subret; ) + enc[t] = enc[t - subret]; + + for(t=ret+subret; t-->ret; ) + enc[t] = tlbuf[t]; + } + ret += accum + subret; i++; goto encode_1more_prime; } diff --git a/src/2-rsa/rsa-pubkey-codec-der-test.sh b/src/2-rsa/rsa-pubkey-codec-der-test.sh index c3ca889..7886c0a 100644 --- a/src/2-rsa/rsa-pubkey-codec-der-test.sh +++ b/src/2-rsa/rsa-pubkey-codec-der-test.sh @@ -2,6 +2,7 @@ optimize=true testfunc() { + #lldb --\ $exec ../tests/rsa-1440-3primes.der ../tests/rsa-1440-pub.der } diff --git a/src/2-rsa/rsa-pubkey-export-der.c b/src/2-rsa/rsa-pubkey-export-der.c index e2c02e5..937b1e4 100644 --- a/src/2-rsa/rsa-pubkey-export-der.c +++ b/src/2-rsa/rsa-pubkey-export-der.c @@ -5,15 +5,11 @@ IntPtr ber_tlv_export_RSAPublicKey(BER_TLV_ENCODING_FUNC_PARAMS) { - int pass = enc ? 2 : 1; IntPtr ret = 0, subret; - uint8_t *stack = NULL; - uint8_t *ptr = enc; - size_t remain = enclen; - //- not used -// uint32_t i; - - size_t taglen; + uint8_t tlbuf[TAGLEN_MAX]; + uint8_t *ptr = tlbuf; + IntPtr t; const RSA_Priv_Base_Ctx_t *ctx = any; @@ -22,51 +18,36 @@ IntPtr ber_tlv_export_RSAPublicKey(BER_TLV_ENCODING_FUNC_PARAMS) // // modulus INTEGER, -- n - subret = ber_tlv_encode_integer(DeltaTo(ctx, offset_n), ptr, remain); + subret = ber_tlv_put_integer( + DeltaTo(ctx, offset_n), DeltaAdd(enc, ret), enclen-ret); + if( subret < 0 ) return -1; ret += subret; - if( pass == 2 ) stack = enc + enclen; // [NULL-stack-in-pass-1]. - taglen = 0; - taglen += ber_push_len(&stack, subret); - taglen += ber_push_tag(&stack, BER_TLV_TAG_UNI(2), 0); - - if( pass == 2 ) - { - ber_util_splice_insert(ptr, subret, (stack - ptr), taglen); - } - ret += taglen; - if( enc ) ptr += subret + taglen; remain -= subret + taglen; - // // publicExponent INTEGER, -- e - subret = ber_tlv_encode_integer(DeltaTo(ctx, offset_e), ptr, remain); + subret = ber_tlv_put_integer( + DeltaTo(ctx, offset_e), DeltaAdd(enc, ret), enclen-ret); + if( subret < 0 ) return -1; ret += subret; - if( pass == 2 ) stack = enc + enclen; // [NULL-stack-in-pass-1]. - taglen = 0; - taglen += ber_push_len(&stack, subret); - taglen += ber_push_tag(&stack, BER_TLV_TAG_UNI(2), 0); - - if( pass == 2 ) - { - ber_util_splice_insert(ptr, subret, (stack - ptr), taglen); - } - ret += taglen; - if( enc ) ptr += subret + taglen; remain -= subret + taglen; - // // } -- End of "RSAPublicKey ::= SEQUENCE". - if( pass == 2 ) stack = enc + enclen; - taglen = 0; - taglen += ber_push_len(&stack, ret); - taglen += ber_push_tag(&stack, BER_TLV_TAG_UNI(16), 1); + ptr += ber_put_tag(ptr, BER_TLV_TAG_UNI(16), 1); + ptr += ber_put_len(ptr, ret); + subret = ptr - tlbuf; - if( pass == 2 ) + if( enc ) { - ber_util_splice_insert(enc, ret, (stack - enc), taglen); + if( ret + subret > (IntPtr)enclen ) + return -1; + + for(t=ret+subret; t-->subret; ) + enc[t] = enc[t - subret]; + + for(t=subret; t-->0; ) + enc[t] = tlbuf[t]; } - ret += taglen; - return ret; + return ret + subret; } diff --git a/src/2-rsa/rsa-pubkey-writer-der.c b/src/2-rsa/rsa-pubkey-writer-der.c index c62efc6..b6e23dd 100644 --- a/src/2-rsa/rsa-pubkey-writer-der.c +++ b/src/2-rsa/rsa-pubkey-writer-der.c @@ -5,15 +5,11 @@ IntPtr ber_tlv_encode_RSAPublicKey(BER_TLV_ENCODING_FUNC_PARAMS) { - int pass = enc ? 2 : 1; IntPtr ret = 0, subret; - uint8_t *stack = NULL; - uint8_t *ptr = enc; - size_t remain = enclen; - //- not used -// uint32_t i; - - size_t taglen; + uint8_t tlbuf[TAGLEN_MAX]; + uint8_t *ptr = tlbuf; + IntPtr t; const RSA_Pub_Ctx_Hdr_t *ctx = any; @@ -22,51 +18,36 @@ IntPtr ber_tlv_encode_RSAPublicKey(BER_TLV_ENCODING_FUNC_PARAMS) // // modulus INTEGER, -- n - subret = ber_tlv_encode_integer(DeltaTo(ctx, offset_n), ptr, remain); + subret = ber_tlv_put_integer( + DeltaTo(ctx, offset_n), DeltaAdd(enc, ret), enclen-ret); + if( subret < 0 ) return -1; ret += subret; - if( pass == 2 ) stack = enc + enclen; // [NULL-stack-in-pass-1]. - taglen = 0; - taglen += ber_push_len(&stack, subret); - taglen += ber_push_tag(&stack, BER_TLV_TAG_UNI(2), 0); - - if( pass == 2 ) - { - ber_util_splice_insert(ptr, subret, (stack - ptr), taglen); - } - ret += taglen; - if( enc ) ptr += subret + taglen; remain -= subret + taglen; - // // publicExponent INTEGER, -- e - subret = ber_tlv_encode_integer(DeltaTo(ctx, offset_e), ptr, remain); + subret = ber_tlv_put_integer( + DeltaTo(ctx, offset_e), DeltaAdd(enc, ret), enclen-ret); + if( subret < 0 ) return -1; ret += subret; - if( pass == 2 ) stack = enc + enclen; // [NULL-stack-in-pass-1]. - taglen = 0; - taglen += ber_push_len(&stack, subret); - taglen += ber_push_tag(&stack, BER_TLV_TAG_UNI(2), 0); - - if( pass == 2 ) - { - ber_util_splice_insert(ptr, subret, (stack - ptr), taglen); - } - ret += taglen; - if( enc ) ptr += subret + taglen; remain -= subret + taglen; - // // } -- End of "RSAPublicKey ::= SEQUENCE". - if( pass == 2 ) stack = enc + enclen; - taglen = 0; - taglen += ber_push_len(&stack, ret); - taglen += ber_push_tag(&stack, BER_TLV_TAG_UNI(16), 1); + ptr += ber_put_tag(ptr, BER_TLV_TAG_UNI(16), 1); + ptr += ber_put_len(ptr, ret); + subret = ptr - tlbuf; - if( pass == 2 ) + if( enc ) { - ber_util_splice_insert(enc, ret, (stack - enc), taglen); + if( ret + subret > (IntPtr)enclen ) + return -1; + + for(t=ret+subret; t-->subret; ) + enc[t] = enc[t - subret]; + + for(t=subret; t-->0; ) + enc[t] = tlbuf[t]; } - ret += taglen; - return ret; + return ret + subret; } diff --git a/src/3-ecc-common/ecc-common.c b/src/3-ecc-common/ecc-common.c index 6a1ea23..e467876 100644 --- a/src/3-ecc-common/ecc-common.c +++ b/src/3-ecc-common/ecc-common.c @@ -227,15 +227,11 @@ IntPtr ECC_Encode_PublicKey( IntPtr ber_tlv_ecc_encode_dss_signature(BER_TLV_ENCODING_FUNC_PARAMS) { - int pass = enc ? 2 : 1; IntPtr ret = 0, subret; - uint8_t *stack = NULL; - uint8_t *ptr = enc; - size_t remain = enclen; - //- not used -// uint32_t i; - - size_t taglen; + uint8_t tlbuf[TAGLEN_MAX]; + uint8_t *ptr = tlbuf; + IntPtr t; const ECC_Hash_Ctx_Hdr_t *ctx = any; const ecp_opctx_t *opctx = DeltaTo(ctx, offset_opctx); @@ -245,53 +241,38 @@ IntPtr ber_tlv_ecc_encode_dss_signature(BER_TLV_ENCODING_FUNC_PARAMS) // // r INTEGER, - subret = ber_tlv_encode_integer(DeltaTo(opctx, offset_r), ptr, remain); + subret = ber_tlv_put_integer( + DeltaTo(opctx, offset_r), DeltaAdd(enc, ret), enclen-ret); + if( subret < 0 ) return -1; ret += subret; - if( pass == 2 ) stack = enc + enclen; // [NULL-stack-in-pass-1]. - taglen = 0; - taglen += ber_push_len(&stack, subret); - taglen += ber_push_tag(&stack, BER_TLV_TAG_UNI(2), 0); - - if( pass == 2 ) - { - ber_util_splice_insert(ptr, subret, (stack - ptr), taglen); - } - ret += taglen; - if( enc ) ptr += subret + taglen; remain -= subret + taglen; - // // s INTEGER, - subret = ber_tlv_encode_integer(DeltaTo(opctx, offset_s), ptr, remain); + subret = ber_tlv_put_integer( + DeltaTo(opctx, offset_s), DeltaAdd(enc, ret), enclen-ret); + if( subret < 0 ) return -1; ret += subret; - if( pass == 2 ) stack = enc + enclen; // [NULL-stack-in-pass-1]. - taglen = 0; - taglen += ber_push_len(&stack, subret); - taglen += ber_push_tag(&stack, BER_TLV_TAG_UNI(2), 0); - - if( pass == 2 ) - { - ber_util_splice_insert(ptr, subret, (stack - ptr), taglen); - } - ret += taglen; - if( enc ) ptr += subret + taglen; remain -= subret + taglen; - // // } -- End of "Ecdsa-Sig-Value ::= SEQUENCE". - if( pass == 2 ) stack = enc + enclen; - taglen = 0; - taglen += ber_push_len(&stack, ret); - taglen += ber_push_tag(&stack, BER_TLV_TAG_UNI(16), 1); + ptr += ber_put_tag(ptr, BER_TLV_TAG_UNI(16), 1); + ptr += ber_put_len(ptr, ret); + subret = ptr - tlbuf; - if( pass == 2 ) + if( enc ) { - ber_util_splice_insert(enc, ret, (stack - enc), taglen); + if( ret + subret > (IntPtr)enclen ) + return -1; + + for(t=ret+subret; t-->subret; ) + enc[t] = enc[t - subret]; + + for(t=subret; t-->0; ) + enc[t] = tlbuf[t]; } - ret += taglen; - return ret; + return ret + subret; } #endif /* ! PKC_OMIT_PRIV_OPS */