diff options
| -rw-r--r-- | meta/recipes-support/libgcrypt/files/0005-ecc-Add-input-validation-for-X25519.patch | 158 | ||||
| -rw-r--r-- | meta/recipes-support/libgcrypt/libgcrypt_1.8.0.bb | 1 |
2 files changed, 159 insertions, 0 deletions
diff --git a/meta/recipes-support/libgcrypt/files/0005-ecc-Add-input-validation-for-X25519.patch b/meta/recipes-support/libgcrypt/files/0005-ecc-Add-input-validation-for-X25519.patch new file mode 100644 index 0000000000..66fdd740b5 --- /dev/null +++ b/meta/recipes-support/libgcrypt/files/0005-ecc-Add-input-validation-for-X25519.patch | |||
| @@ -0,0 +1,158 @@ | |||
| 1 | From ef570e3d2773c12126e7d3fcdc4db9ef80a5e214 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: NIIBE Yutaka <gniibe@fsij.org> | ||
| 3 | Date: Fri, 25 Aug 2017 18:13:28 +0900 | ||
| 4 | Subject: [PATCH] ecc: Add input validation for X25519. | ||
| 5 | |||
| 6 | * cipher/ecc.c (ecc_decrypt_raw): Add input validation. | ||
| 7 | * mpi/ec.c (ec_p_init): Use scratch buffer for bad points. | ||
| 8 | (_gcry_mpi_ec_bad_point): New. | ||
| 9 | |||
| 10 | -- | ||
| 11 | |||
| 12 | Following is the paper describing the attack: | ||
| 13 | |||
| 14 | May the Fourth Be With You: A Microarchitectural Side Channel Attack | ||
| 15 | on Real-World Applications of Curve25519 | ||
| 16 | by Daniel Genkin, Luke Valenta, and Yuval Yarom | ||
| 17 | |||
| 18 | In the current implementation, we do output checking and it results an | ||
| 19 | error for those bad points. However, when attacked, the computation | ||
| 20 | will done with leak of private key, even it will results errors. To | ||
| 21 | mitigate leak, we added input validation. | ||
| 22 | |||
| 23 | Note that we only list bad points with MSB=0. By X25519, MSB is | ||
| 24 | always cleared. | ||
| 25 | |||
| 26 | In future, we should implement constant-time field computation. Then, | ||
| 27 | this input validation could be removed, if performance is important | ||
| 28 | and we are sure for no leak. | ||
| 29 | |||
| 30 | CVE-id: CVE-2017-0379 | ||
| 31 | Signed-off-by: NIIBE Yutaka <gniibe@fsij.org> | ||
| 32 | |||
| 33 | Upstream-Status: Backport | ||
| 34 | CVE: CVE-2017-0379 | ||
| 35 | Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com> | ||
| 36 | --- | ||
| 37 | cipher/ecc.c | 17 +++++++++++++++-- | ||
| 38 | mpi/ec.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++--- | ||
| 39 | src/mpi.h | 1 + | ||
| 40 | 3 files changed, 64 insertions(+), 5 deletions(-) | ||
| 41 | |||
| 42 | diff --git a/cipher/ecc.c b/cipher/ecc.c | ||
| 43 | index e25bf09..4e3e5b1 100644 | ||
| 44 | --- a/cipher/ecc.c | ||
| 45 | +++ b/cipher/ecc.c | ||
| 46 | @@ -1628,9 +1628,22 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) | ||
| 47 | if (DBG_CIPHER) | ||
| 48 | log_printpnt ("ecc_decrypt kG", &kG, NULL); | ||
| 49 | |||
| 50 | - if (!(flags & PUBKEY_FLAG_DJB_TWEAK) | ||
| 51 | + if ((flags & PUBKEY_FLAG_DJB_TWEAK)) | ||
| 52 | + { | ||
| 53 | /* For X25519, by its definition, validation should not be done. */ | ||
| 54 | - && !_gcry_mpi_ec_curve_point (&kG, ec)) | ||
| 55 | + /* (Instead, we do output check.) | ||
| 56 | + * | ||
| 57 | + * However, to mitigate secret key leak from our implementation, | ||
| 58 | + * we also do input validation here. For constant-time | ||
| 59 | + * implementation, we can remove this input validation. | ||
| 60 | + */ | ||
| 61 | + if (_gcry_mpi_ec_bad_point (&kG, ec)) | ||
| 62 | + { | ||
| 63 | + rc = GPG_ERR_INV_DATA; | ||
| 64 | + goto leave; | ||
| 65 | + } | ||
| 66 | + } | ||
| 67 | + else if (!_gcry_mpi_ec_curve_point (&kG, ec)) | ||
| 68 | { | ||
| 69 | rc = GPG_ERR_INV_DATA; | ||
| 70 | goto leave; | ||
| 71 | diff --git a/mpi/ec.c b/mpi/ec.c | ||
| 72 | index a0f7357..4c16603 100644 | ||
| 73 | --- a/mpi/ec.c | ||
| 74 | +++ b/mpi/ec.c | ||
| 75 | @@ -396,6 +396,29 @@ ec_get_two_inv_p (mpi_ec_t ec) | ||
| 76 | } | ||
| 77 | |||
| 78 | |||
| 79 | +static const char *curve25519_bad_points[] = { | ||
| 80 | + "0x0000000000000000000000000000000000000000000000000000000000000000", | ||
| 81 | + "0x0000000000000000000000000000000000000000000000000000000000000001", | ||
| 82 | + "0x00b8495f16056286fdb1329ceb8d09da6ac49ff1fae35616aeb8413b7c7aebe0", | ||
| 83 | + "0x57119fd0dd4e22d8868e1c58c45c44045bef839c55b1d0b1248c50a3bc959c5f", | ||
| 84 | + "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec", | ||
| 85 | + "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed", | ||
| 86 | + "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee", | ||
| 87 | + NULL | ||
| 88 | +}; | ||
| 89 | + | ||
| 90 | +static gcry_mpi_t | ||
| 91 | +scanval (const char *string) | ||
| 92 | +{ | ||
| 93 | + gpg_err_code_t rc; | ||
| 94 | + gcry_mpi_t val; | ||
| 95 | + | ||
| 96 | + rc = _gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL); | ||
| 97 | + if (rc) | ||
| 98 | + log_fatal ("scanning ECC parameter failed: %s\n", gpg_strerror (rc)); | ||
| 99 | + return val; | ||
| 100 | +} | ||
| 101 | + | ||
| 102 | |||
| 103 | /* This function initialized a context for elliptic curve based on the | ||
| 104 | field GF(p). P is the prime specifying this field, A is the first | ||
| 105 | @@ -434,9 +457,17 @@ ec_p_init (mpi_ec_t ctx, enum gcry_mpi_ec_models model, | ||
| 106 | |||
| 107 | _gcry_mpi_ec_get_reset (ctx); | ||
| 108 | |||
| 109 | - /* Allocate scratch variables. */ | ||
| 110 | - for (i=0; i< DIM(ctx->t.scratch); i++) | ||
| 111 | - ctx->t.scratch[i] = mpi_alloc_like (ctx->p); | ||
| 112 | + if (model == MPI_EC_MONTGOMERY) | ||
| 113 | + { | ||
| 114 | + for (i=0; i< DIM(ctx->t.scratch) && curve25519_bad_points[i]; i++) | ||
| 115 | + ctx->t.scratch[i] = scanval (curve25519_bad_points[i]); | ||
| 116 | + } | ||
| 117 | + else | ||
| 118 | + { | ||
| 119 | + /* Allocate scratch variables. */ | ||
| 120 | + for (i=0; i< DIM(ctx->t.scratch); i++) | ||
| 121 | + ctx->t.scratch[i] = mpi_alloc_like (ctx->p); | ||
| 122 | + } | ||
| 123 | |||
| 124 | /* Prepare for fast reduction. */ | ||
| 125 | /* FIXME: need a test for NIST values. However it does not gain us | ||
| 126 | @@ -1572,3 +1603,17 @@ _gcry_mpi_ec_curve_point (gcry_mpi_point_t point, mpi_ec_t ctx) | ||
| 127 | |||
| 128 | return res; | ||
| 129 | } | ||
| 130 | + | ||
| 131 | + | ||
| 132 | +int | ||
| 133 | +_gcry_mpi_ec_bad_point (gcry_mpi_point_t point, mpi_ec_t ctx) | ||
| 134 | +{ | ||
| 135 | + int i; | ||
| 136 | + gcry_mpi_t x_bad; | ||
| 137 | + | ||
| 138 | + for (i = 0; (x_bad = ctx->t.scratch[i]); i++) | ||
| 139 | + if (!mpi_cmp (point->x, x_bad)) | ||
| 140 | + return 1; | ||
| 141 | + | ||
| 142 | + return 0; | ||
| 143 | +} | ||
| 144 | diff --git a/src/mpi.h b/src/mpi.h | ||
| 145 | index b5385b5..aeba7f8 100644 | ||
| 146 | --- a/src/mpi.h | ||
| 147 | +++ b/src/mpi.h | ||
| 148 | @@ -296,6 +296,7 @@ void _gcry_mpi_ec_mul_point (mpi_point_t result, | ||
| 149 | gcry_mpi_t scalar, mpi_point_t point, | ||
| 150 | mpi_ec_t ctx); | ||
| 151 | int _gcry_mpi_ec_curve_point (gcry_mpi_point_t point, mpi_ec_t ctx); | ||
| 152 | +int _gcry_mpi_ec_bad_point (gcry_mpi_point_t point, mpi_ec_t ctx); | ||
| 153 | |||
| 154 | gcry_mpi_t _gcry_mpi_ec_ec2os (gcry_mpi_point_t point, mpi_ec_t ectx); | ||
| 155 | |||
| 156 | -- | ||
| 157 | 1.8.3.1 | ||
| 158 | |||
diff --git a/meta/recipes-support/libgcrypt/libgcrypt_1.8.0.bb b/meta/recipes-support/libgcrypt/libgcrypt_1.8.0.bb index 1797d9584d..fb004d9ceb 100644 --- a/meta/recipes-support/libgcrypt/libgcrypt_1.8.0.bb +++ b/meta/recipes-support/libgcrypt/libgcrypt_1.8.0.bb | |||
| @@ -20,6 +20,7 @@ SRC_URI = "${GNUPG_MIRROR}/libgcrypt/libgcrypt-${PV}.tar.gz \ | |||
| 20 | file://0003-tests-bench-slope.c-workaround-ICE-failure-on-mips-w.patch \ | 20 | file://0003-tests-bench-slope.c-workaround-ICE-failure-on-mips-w.patch \ |
| 21 | file://0002-libgcrypt-fix-building-error-with-O2-in-sysroot-path.patch \ | 21 | file://0002-libgcrypt-fix-building-error-with-O2-in-sysroot-path.patch \ |
| 22 | file://0004-tests-Makefile.am-fix-undefined-reference-to-pthread.patch \ | 22 | file://0004-tests-Makefile.am-fix-undefined-reference-to-pthread.patch \ |
| 23 | file://0005-ecc-Add-input-validation-for-X25519.patch \ | ||
| 23 | " | 24 | " |
| 24 | SRC_URI[md5sum] = "110ce4352f9ea6f560bdc6c5644ae93c" | 25 | SRC_URI[md5sum] = "110ce4352f9ea6f560bdc6c5644ae93c" |
| 25 | SRC_URI[sha256sum] = "f6e470b7f2d3a703e8747f05a8c19d9e10e26ebf2d5f3d71ff75a40f504e12ee" | 26 | SRC_URI[sha256sum] = "f6e470b7f2d3a703e8747f05a8c19d9e10e26ebf2d5f3d71ff75a40f504e12ee" |
