+/* This is an internal function that can be used instead of bn_expand2()
+ * when there is a need to copy BIGNUMs instead of only expanding the
+ * data part, while still expanding them.
+ * Especially useful when needing to expand BIGNUMs that are declared
+ * 'const' and should therefore not be changed.
+ * The reason to use this instead of a BN_dup() followed by a bn_expand2()
+ * is memory allocation overhead. A BN_dup() followed by a bn_expand2()
+ * will allocate new memory for the BIGNUM data twice, and free it once,
+ * while bn_dup_expand() makes sure allocation is made only once.
+ */
+
+BIGNUM *bn_dup_expand(const BIGNUM *b, int words)
+ {
+ BIGNUM *r = NULL;
+
+ if (words > b->dmax)
+ {
+ BN_ULONG *a = internal_bn_expand(b, words);
+
+ if (a)
+ {
+ r = BN_new();
+ r->top = b->top;
+ r->dmax = words;
+ r->neg = b->neg;
+ r->d = a;
+ }
+ /* Otherwise, there was an error in allocation in
+ internal_bn_expand(), and NULL should be returned */
+ }
+ else
+ {
+ r = BN_dup(b);
+ }
+
+ return r;
+ }
+
+/* This is an internal function that should not be used in applications.
+ * It ensures that 'b' has enough room for a 'words' word number number.
+ * It is mostly used by the various BIGNUM routines. If there is an error,
+ * NULL is returned. If not, 'b' is returned. */
+
+BIGNUM *bn_expand2(BIGNUM *b, int words)
+ {
+ if (words > b->dmax)
+ {
+ BN_ULONG *a = internal_bn_expand(b, words);
+
+ if (a)
+ {
+ OPENSSL_free(b->d);
+ b->d=a;
+ b->dmax=words;
+ }
+ else
+ b = NULL;