Skip to content

Commit b9514e7

Browse files
Merge pull request #10148 from julek-wolfssl/openvpn-master-bn2binpad
Add BN_bn2binpad API and enable OpenVPN master CI testing
2 parents 06abf84 + 3e74f84 commit b9514e7

5 files changed

Lines changed: 93 additions & 6 deletions

File tree

.github/workflows/codespell.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
check_filenames: true
2424
check_hidden: true
2525
# Add comma separated list of words that occur multiple times that should be ignored (sorted alphabetically, case sensitive)
26-
ignore_words_list: adin,aNULL,brunch,carryIn,chainG,ciph,cLen,cliKs,dout,haveA,inCreated,inOut,inout,larg,LEAPYEAR,Merget,optionA,parm,parms,repid,rIn,userA,ser,siz,te,Te,HSI,failT,
26+
ignore_words_list: adin,aNULL,brunch,carryIn,chainG,ciph,cLen,cliKs,dout,haveA,inCreated,inOut,inout,larg,LEAPYEAR,Merget,optionA,parm,parms,repid,rIn,userA,ser,siz,te,Te,HSI,failT,toLen,
2727
# The exclude_file contains lines of code that should be ignored. This is useful for individual lines which have non-words that can safely be ignored.
2828
exclude_file: '.codespellexcludelines'
2929
# To skip files entirely from being processed, add it to the following list:

.github/workflows/openvpn.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,7 @@ jobs:
4242
strategy:
4343
fail-fast: false
4444
matrix:
45-
# Pinned refs: avoid OpenVPN master until wolfSSL adds any new OpenSSL
46-
# APIs it adopts (e.g. BN_bn2binpad). release/2.6 + latest stable tag.
47-
ref: [ release/2.6, v2.6.19 ]
45+
ref: [ master, release/2.6, v2.6.19 ]
4846
name: ${{ matrix.ref }}
4947
if: github.repository_owner == 'wolfssl'
5048
runs-on: ubuntu-24.04

src/ssl_bn.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,56 @@ int wolfSSL_BN_bn2bin(const WOLFSSL_BIGNUM* bn, unsigned char* r)
468468
}
469469

470470

471+
/* Encode a big number as a big-endian byte array, zero-padded to toLen bytes.
472+
*
473+
* Returns toLen on success, -1 on error (including when the number is too
474+
* large to fit in toLen bytes).
475+
*
476+
* @param [in] bn Big number to encode.
477+
* @param [out] r Buffer to place encoding into. Must be at least toLen
478+
* bytes.
479+
* @param [in] toLen Desired output length in bytes.
480+
* @return toLen on success.
481+
* @return -1 on error.
482+
*/
483+
int wolfSSL_BN_bn2binpad(const WOLFSSL_BIGNUM* bn, unsigned char* r, int toLen)
484+
{
485+
int numBytes;
486+
487+
WOLFSSL_ENTER("wolfSSL_BN_bn2binpad");
488+
489+
/* Validate parameters. */
490+
if (BN_IS_NULL(bn) || (r == NULL) || (toLen < 0)) {
491+
WOLFSSL_MSG("NULL bn, r, or invalid toLen error");
492+
return WOLFSSL_FATAL_ERROR;
493+
}
494+
495+
/* Get the number of bytes needed to encode the big number. */
496+
numBytes = mp_unsigned_bin_size((mp_int*)bn->internal);
497+
if (numBytes < 0) {
498+
WOLFSSL_MSG("mp_unsigned_bin_size error");
499+
return WOLFSSL_FATAL_ERROR;
500+
}
501+
if (numBytes > toLen) {
502+
WOLFSSL_MSG("BN too large for toLen");
503+
return WOLFSSL_FATAL_ERROR;
504+
}
505+
506+
/* Zero-pad leading bytes. */
507+
XMEMSET(r, 0, (size_t)(toLen - numBytes));
508+
509+
/* Encode the big number into the remaining bytes. */
510+
if (numBytes > 0 &&
511+
mp_to_unsigned_bin((mp_int*)bn->internal, r + toLen - numBytes) !=
512+
MP_OKAY) {
513+
WOLFSSL_MSG("mp_to_unsigned_bin error");
514+
return WOLFSSL_FATAL_ERROR;
515+
}
516+
517+
return toLen;
518+
}
519+
520+
471521
/* Return a big number with value of the decoding of the big-endian byte array.
472522
*
473523
* Returns ret when not NULL.

tests/api/test_ossl_bn.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,42 @@ int test_wolfSSL_BN_enc_dec(void)
323323
ExpectNotNull(BN_bin2bn(binNum, sizeof(binNum), b));
324324
ExpectIntEQ(BN_cmp(a, b), -1);
325325

326+
/* BN_bn2binpad tests */
327+
{
328+
unsigned char padOut[5];
329+
330+
/* Invalid parameters */
331+
ExpectIntEQ(BN_bn2binpad(NULL, padOut, sizeof(padOut)), -1);
332+
ExpectIntEQ(BN_bn2binpad(&emptyBN, padOut, sizeof(padOut)), -1);
333+
ExpectIntEQ(BN_bn2binpad(a, NULL, sizeof(padOut)), -1);
334+
ExpectIntEQ(BN_bn2binpad(a, padOut, -1), -1);
335+
/* toLen too small for the value */
336+
ExpectNotNull(BN_bin2bn(binNum, sizeof(binNum), b));
337+
ExpectIntEQ(BN_bn2binpad(b, padOut, 2), -1);
338+
/* Normal case: a = 2, padded to 5 bytes */
339+
XMEMSET(padOut, 0xFF, sizeof(padOut));
340+
ExpectIntEQ(BN_bn2binpad(a, padOut, 5), 5);
341+
ExpectIntEQ(padOut[0], 0x00);
342+
ExpectIntEQ(padOut[1], 0x00);
343+
ExpectIntEQ(padOut[2], 0x00);
344+
ExpectIntEQ(padOut[3], 0x00);
345+
ExpectIntEQ(padOut[4], 0x02);
346+
/* Exact size (no padding needed) */
347+
ExpectIntEQ(BN_bn2binpad(a, padOut, 1), 1);
348+
ExpectIntEQ(padOut[0], 0x02);
349+
/* Zero value padded to 3 bytes */
350+
ExpectIntEQ(BN_set_word(a, 0), 1);
351+
ExpectIntEQ(BN_bn2binpad(a, padOut, 3), 3);
352+
ExpectIntEQ(padOut[0], 0x00);
353+
ExpectIntEQ(padOut[1], 0x00);
354+
ExpectIntEQ(padOut[2], 0x00);
355+
/* toLen == 0 with zero-valued BN is valid */
356+
ExpectIntEQ(BN_bn2binpad(a, padOut, 0), 0);
357+
/* toLen == 0 with non-zero BN is an error */
358+
ExpectIntEQ(BN_set_word(a, 2), 1);
359+
ExpectIntEQ(BN_bn2binpad(a, padOut, 0), -1);
360+
}
361+
326362
ExpectNotNull(str = BN_bn2hex(a));
327363
ExpectNotNull(BN_hex2bn(&b, str));
328364
ExpectIntEQ(BN_cmp(a, b), 0);

wolfssl/openssl/bn.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ WOLFSSL_API int wolfSSL_BN_cmp(const WOLFSSL_BIGNUM* a, const WOLFSSL_BIGNUM* b)
135135
WOLFSSL_API int wolfSSL_BN_ucmp(const WOLFSSL_BIGNUM* a, const WOLFSSL_BIGNUM* b);
136136

137137
WOLFSSL_API int wolfSSL_BN_bn2bin(const WOLFSSL_BIGNUM* bn, unsigned char* r);
138+
WOLFSSL_API int wolfSSL_BN_bn2binpad(const WOLFSSL_BIGNUM* bn, unsigned char* r,
139+
int toLen);
138140
WOLFSSL_API WOLFSSL_BIGNUM* wolfSSL_BN_bin2bn(const unsigned char* str, int len,
139141
WOLFSSL_BIGNUM* ret);
140142

@@ -246,8 +248,9 @@ typedef WOLFSSL_BN_GENCB BN_GENCB;
246248
#define BN_cmp wolfSSL_BN_cmp
247249
#define BN_ucmp wolfSSL_BN_ucmp
248250

249-
#define BN_bn2bin wolfSSL_BN_bn2bin
250-
#define BN_bin2bn wolfSSL_BN_bin2bn
251+
#define BN_bn2bin wolfSSL_BN_bn2bin
252+
#define BN_bn2binpad wolfSSL_BN_bn2binpad
253+
#define BN_bin2bn wolfSSL_BN_bin2bn
251254

252255
#define BN_mod wolfSSL_BN_mod
253256
#define BN_mod_exp wolfSSL_BN_mod_exp

0 commit comments

Comments
 (0)