-
Notifications
You must be signed in to change notification settings - Fork 36
Validate EC_PUB_X/EC_PUB_Y on import by routine them through the X9.63 point import #467
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -584,35 +584,126 @@ static int wp_ecc_set_params_enc_pub_key(wp_Ecc *ecc, const OSSL_PARAM params[], | |
| } | ||
|
|
||
| /** | ||
| * Set the public key values into ECC key object. | ||
| * Set the public key ordinates into the ECC key object. | ||
| * | ||
| * X and Y are imported together as an X9.63 point, and the resulting point is | ||
| * checked against the curve, instead of being stored unvalidated. | ||
| * | ||
| * @param [in, out] ecc ECC key object. | ||
| * @param [in] params Array of parameters and values. | ||
| * @return 1 on success. | ||
| * @return 0 on failure. | ||
| */ | ||
| static int wp_ecc_set_params_pub(wp_Ecc *ecc, const OSSL_PARAM params[]) | ||
| static int wp_ecc_set_params_pub_xy(wp_Ecc* ecc, const OSSL_PARAM params[]) | ||
| { | ||
| int ok = 1; | ||
| int set = 0; | ||
| int setX = 0; | ||
| int setY = 0; | ||
| int init = 0; | ||
| int size = 0; | ||
| unsigned char* point = NULL; | ||
| mp_int x; | ||
| mp_int y; | ||
|
|
||
| WOLFPROV_ENTER(WP_LOG_COMP_ECC, "wp_ecc_set_params_pub"); | ||
| WOLFPROV_ENTER(WP_LOG_COMP_ECC, "wp_ecc_set_params_pub_xy"); | ||
|
|
||
| if (!wp_params_get_mp(params, OSSL_PKEY_PARAM_EC_PUB_X, | ||
| ecc->key.pubkey.x, &set)) { | ||
| if (mp_init_multi(&x, &y, NULL, NULL, NULL, NULL) != MP_OKAY) { | ||
| ok = 0; | ||
| } | ||
| else { | ||
| init = 1; | ||
| } | ||
| if (ok && (!wp_params_get_mp(params, OSSL_PKEY_PARAM_EC_PUB_X, &x, | ||
| &setX))) { | ||
| ok = 0; | ||
| } | ||
| if (ok && (!wp_params_get_mp(params, OSSL_PKEY_PARAM_EC_PUB_Y, &y, | ||
| &setY))) { | ||
| ok = 0; | ||
| } | ||
| if (ok && (set == 1)) { | ||
| if (mp_iszero(ecc->key.pubkey.x)) { | ||
| /* One ordinate on its own is not a public key. */ | ||
| if (ok && (setX != setY)) { | ||
| ok = 0; | ||
| } | ||
| if (ok && setX) { | ||
| size = wc_ecc_get_curve_size_from_id(ecc->curveId); | ||
| if (size <= 0) { | ||
| ok = 0; | ||
| } | ||
| } | ||
| if (ok && setX) { | ||
| point = OPENSSL_malloc(1 + (2 * (size_t)size)); | ||
| if (point == NULL) { | ||
| ok = 0; | ||
| } | ||
| } | ||
| if (ok && setX) { | ||
| /* Uncompressed X9.63 point: 0x04 || X || Y. */ | ||
| point[0] = 0x04; | ||
| if (mp_to_unsigned_bin_len(&x, point + 1, size) != MP_OKAY) { | ||
| ok = 0; | ||
| } | ||
| } | ||
| if (ok && setX) { | ||
| if (mp_to_unsigned_bin_len(&y, point + 1 + size, size) != MP_OKAY) { | ||
| ok = 0; | ||
| } | ||
| } | ||
| if (ok && setX) { | ||
| int rc; | ||
| int origType; | ||
|
|
||
| rc = wc_ecc_import_x963_ex(point, 1 + (2 * (word32)size), &ecc->key, | ||
| ecc->curveId); | ||
| if (rc != 0) { | ||
| WOLFPROV_MSG_DEBUG_RETCODE(WP_LOG_LEVEL_DEBUG, | ||
| "wc_ecc_import_x963_ex", rc); | ||
| ok = 0; | ||
| } | ||
| if (ok) { | ||
| /* wc_ecc_import_x963_ex only checks the point against the curve | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. According to the logic in this comment, we should also apply the check below in iiuc, |
||
| * when wolfSSL is built with WOLFSSL_VALIDATE_ECC_IMPORT, so check | ||
| * it here instead of relying on the build options. */ | ||
| origType = ecc->key.type; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. AI says |
||
| ecc->key.type = ECC_PUBLICKEY; | ||
| ecc->hasPub = 1; | ||
| rc = wc_ecc_check_key(&ecc->key); | ||
| ecc->key.type = origType; | ||
| if (rc != 0) { | ||
| WOLFPROV_MSG_DEBUG_RETCODE(WP_LOG_LEVEL_DEBUG, | ||
| "wc_ecc_check_key", rc); | ||
| ok = 0; | ||
| } | ||
| else { | ||
| ecc->hasPub = 1; | ||
| } | ||
| } | ||
| } | ||
| if (!wp_params_get_mp(params, OSSL_PKEY_PARAM_EC_PUB_Y, | ||
| ecc->key.pubkey.y, NULL)) { | ||
|
|
||
| OPENSSL_free(point); | ||
| if (init) { | ||
| mp_clear(&x); | ||
| mp_clear(&y); | ||
| } | ||
|
|
||
| WOLFPROV_LEAVE(WP_LOG_COMP_ECC, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok); | ||
| return ok; | ||
| } | ||
|
|
||
| /** | ||
| * Set the public key values into ECC key object. | ||
| * | ||
| * @param [in, out] ecc ECC key object. | ||
| * @param [in] params Array of parameters and values. | ||
| * @return 1 on success. | ||
| * @return 0 on failure. | ||
| */ | ||
| static int wp_ecc_set_params_pub(wp_Ecc *ecc, const OSSL_PARAM params[]) | ||
| { | ||
| int ok = 1; | ||
|
|
||
| WOLFPROV_ENTER(WP_LOG_COMP_ECC, "wp_ecc_set_params_pub"); | ||
|
|
||
| if (!wp_ecc_set_params_pub_xy(ecc, params)) { | ||
| ok = 0; | ||
| } | ||
| if (wp_ecc_set_params_enc_pub_key(ecc, params, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AI tells me this call can overwrite/zero existing fields within the ecc key, which is fine for import, but potentially dangerous when called from
wp_ecc_set_params. Can you investigate?