]> granicus.if.org Git - esp-idf/commitdiff
mbedtls: Fix Z->s in mbedtls_mpi_exp_mod()
authorKonstantin Kondrashov <konstantin@espressif.com>
Wed, 12 Jun 2019 11:00:44 +0000 (19:00 +0800)
committerKonstantinKondrashov <konstantin@espressif.com>
Wed, 26 Jun 2019 06:19:40 +0000 (14:19 +0800)
Z->s should never be zero, only 1 or -1.
Added additional checks for X, Y and M args to correctly set Z->s.

Closes: https://github.com/espressif/esp-idf/issues/1681
Closes: https://github.com/espressif/esp-idf/issues/3603
Closes: IDFGH-1313
components/mbedtls/port/esp_bignum.c

index ebcd208cc2605054cdd009e0f9fcb1726c299b98..275adad6dcfeb9e70aa1ed9d3fe2421b2c069c2c 100644 (file)
@@ -362,6 +362,18 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi* Z, const mbedtls_mpi* X, const mbedtls_mpi
     mbedtls_mpi *Rinv;    /* points to _Rinv (if not NULL) othwerwise &RR_new */
     mbedtls_mpi_uint Mprime;
 
+    if (mbedtls_mpi_cmp_int(M, 0) <= 0 || (M->p[0] & 1) == 0) {
+        return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+    }
+
+    if (mbedtls_mpi_cmp_int(Y, 0) < 0) {
+        return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+    }
+
+    if (mbedtls_mpi_cmp_int(Y, 0) == 0) {
+        return mbedtls_mpi_lset(Z, 1);
+    }
+
     if (hw_words * 32 > 4096) {
         return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
     }
@@ -395,13 +407,24 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi* Z, const mbedtls_mpi* X, const mbedtls_mpi
     start_op(RSA_START_MODEXP_REG);
 
     /* X ^ Y may actually be shorter than M, but unlikely when used for crypto */
-    MBEDTLS_MPI_CHK( mbedtls_mpi_grow(Z, m_words) );
+    if ((ret = mbedtls_mpi_grow(Z, m_words)) != 0) {
+        esp_mpi_release_hardware();
+        goto cleanup;
+    }
 
     wait_op_complete(RSA_START_MODEXP_REG);
 
     mem_block_to_mpi(Z, RSA_MEM_Z_BLOCK_BASE, m_words);
     esp_mpi_release_hardware();
 
+    // Compensate for negative X
+    if (X->s == -1 && (Y->p[0] & 1) != 0) {
+        Z->s = -1;
+        MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(Z, M, Z));
+    } else {
+        Z->s = 1;
+    }
+
  cleanup:
     if (_Rinv == NULL) {
         mbedtls_mpi_free(&Rinv_new);