diff --git a/wolfcrypt/src/tfm.c b/wolfcrypt/src/tfm.c index a5c409f47..70df13969 100644 --- a/wolfcrypt/src/tfm.c +++ b/wolfcrypt/src/tfm.c @@ -2194,26 +2194,31 @@ int fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) #ifndef POSITIVE_EXP_ONLY /* reduce stack if assume no negatives */ int err; #ifndef WOLFSSL_SMALL_STACK - fp_int tmp[1]; + fp_int tmp[2]; #else fp_int *tmp; #endif #ifdef WOLFSSL_SMALL_STACK - tmp = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT); + tmp = (fp_int*)XMALLOC(sizeof(fp_int) * 2, NULL, DYNAMIC_TYPE_BIGINT); if (tmp == NULL) return FP_MEM; #endif /* yes, copy G and invmod it */ - fp_init_copy(tmp, G); - err = fp_invmod(tmp, P, tmp); + fp_init_copy(&tmp[0], G); + fp_init_copy(&tmp[1], P); + tmp[1].sign = FP_ZPOS; + err = fp_invmod(&tmp[0], &tmp[1], &tmp[0]); if (err == FP_OKAY) { X->sign = FP_ZPOS; - err = _fp_exptmod(tmp, X, X->used, P, Y); + err = _fp_exptmod(&tmp[0], X, X->used, P, Y); if (X != Y) { X->sign = FP_NEG; } + if (P->sign == FP_NEG) { + fp_add(Y, P, Y); + } } #ifdef WOLFSSL_SMALL_STACK XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -2256,26 +2261,31 @@ int fp_exptmod_ex(fp_int * G, fp_int * X, int digits, fp_int * P, fp_int * Y) #ifndef POSITIVE_EXP_ONLY /* reduce stack if assume no negatives */ int err; #ifndef WOLFSSL_SMALL_STACK - fp_int tmp[1]; + fp_int tmp[2]; #else fp_int *tmp; #endif #ifdef WOLFSSL_SMALL_STACK - tmp = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_TMP_BUFFER); + tmp = (fp_int*)XMALLOC(sizeof(fp_int) * 2, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (tmp == NULL) return FP_MEM; #endif /* yes, copy G and invmod it */ - fp_init_copy(tmp, G); - err = fp_invmod(tmp, P, tmp); + fp_init_copy(&tmp[0], G); + fp_init_copy(&tmp[1], P); + tmp[1].sign = FP_ZPOS; + err = fp_invmod(&tmp[0], &tmp[1], &tmp[0]); if (err == FP_OKAY) { X->sign = FP_ZPOS; - err = _fp_exptmod(tmp, X, digits, P, Y); + err = _fp_exptmod(&tmp[0], X, digits, P, Y); if (X != Y) { X->sign = FP_NEG; } + if (P->sign == FP_NEG) { + fp_add(Y, P, Y); + } } #ifdef WOLFSSL_SMALL_STACK XFREE(tmp, NULL, DYNAMIC_TYPE_BIGINT);