Topic: [OpenSSL interface] Question about EC_POINT_MUL

Hello all,

Happy new year and best wishes to all the community.

I have a question about the OpenSSL interface API and the function ECC_POINT_mul.

It seems that the behavior of this function is not conform with the OpenSSL requirements.
Following the manpage

https://www.openssl.org/docs/manmaster/ … T_mul.html

"EC_POINT_mul is a convenient interface to EC_POINTs_mul: it calculates the value generator * n + q * m and stores the result in r. The value n may be NULL in which case the result is just q * m (variable point multiplication). Alternatively, both q and m may be NULL, and n non-NULL, in which case the result is just generator * n (fixed point multiplication).[...]"


But in the code of WolfSSL the wolfSSL_EC_POINT_mul (here from v4.1.0) not follows this requirement and stop the processing.

    if (group == NULL || r == NULL || r->internal == NULL ||
        q == NULL || q->internal == NULL || m == NULL) {
        WOLFSSL_MSG("wolfSSL_EC_POINT_mul NULL error");
        return WOLFSSL_FAILURE;
    }

In my case I try to do a Q = d * G point multiplication to generate a public key.
So only the group [group], the result variable [r] and the private scalar [d] are necessary.

You could see this type of usage with the JOSE librairy from CISCO which use OpenSSL interface to perform cryptographic computing like:
        if (1 != EC_POINT_mul(params, Q, bnD, NULL, NULL, NULL))
        {
            CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
            goto create_EC_failed;
        }


Into the OpenSSL implementation, this function follows the requirement of the manpage without filtering (here from openSSL master repository)

int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
                 const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx)
{
    /* just a convenient interface to EC_POINTs_mul() */

    const EC_POINT *points[1];
    const BIGNUM *scalars[1];

    points[0] = point;
    scalars[0] = p_scalar;

    return EC_POINTs_mul(group, r, g_scalar,
                         (point != NULL
                          && p_scalar != NULL), points, scalars, ctx);
}




Can you confirm this difference and explains the reason ?
Have you ever meet this problem by using the JOSE implementation from CISCO and WolfSSL ?


Thanks to all for your help.

Share

Re: [OpenSSL interface] Question about EC_POINT_MUL

Hi @sebdub79,

Thank you for reaching out to wolfSSL support. Can you tell us a bit of background on this project, what the product is and does?

Can you share what is driving this work?

We have not run into this issue in our own testing but we have not been testing with CISCO either. Can you provide a simple test application that could be compiled with both of the below commands to reproduce the issue for review and testing?


gcc test.c -o run-test -lssl -lcrypto

and


gcc test.c -o run-test -lwolfssl

Warm Regards,

KH

Re: [OpenSSL interface] Question about EC_POINT_MUL

Hello @Kaleb,

Thnaks for your reply and your interest about my question.

My goal is to load a JWK file that contains an ECC private key (and of course the public part too because as with asn.1 key format when a private key is present, the public one too).

I think that it's not necessary to know how the JOSE implementation from CISOC works.
The main fact is that the JOSE library call the EC_POINT_mul with following parameters set to NULL

  • const WOLFSSL_EC_POINT *q,

  • const WOLFSSL_BIGNUM *m,

  • WOLFSSL_BN_CTX *ctx

The manpage of OpenSSL indicates, in this case, that the API should only do a "generator * n" [aka G, the base point, * n].

EC_POINT_mul(params, Q, bnD, NULL, NULL, NULL)) => this should perform bnD * G (with G extracted from params which indique the domain parameters of the curve) and result into Q

In my case the goal is to perform the standard Q = d * G multiplication to get Q which is the public key. But due to the checks on parameters "point", "p_scalar"

Whatever the caller is (JOSE from CISCO or any other caller that will use this API with the same calliong context) the result is that the behavior seems to be not the expected one.

So my point is: why wolfSSL do not respect the manpage from OpenSSL and reject if q and m parameters are null ?
This is not the behavior describe by this API.

I seen that in the tests/api.c/static void test_wolfSSL_EC(void) only one test is done and this test perform a variable point multiplication not a fixed point multiplication with G
    /* perform point multiplication */
    AssertIntEQ(EC_POINT_mul(group, new_point, NULL, Gxy, k, ctx), WOLFSSL_SUCCESS);

This is equivalent to Q = G * n + q * m with n = 0 => Q = q * m = Gxy * k
But notest with the case q = 0 and m = 0 to do the simple Q = G * n computation


An by the way, why the API EC_POINT_set_affine_coordinate is not implemented and only the EC_POINT_get_affine_coordinate is implemented ?
I read (https://www.wolfssl.com/wolfssls-openssl-compatibility/) that wolfSSL not implements all the openSSL interfaces, and that interfaces are added following the needs. Maybe it could be interesting to add the EC_POINT_set_affine_coordinate. In my case it could be interesting to load the public part Q(x,y) that is in affine coordinates into an EC_POINT type that use the projective coordinates form (X,Y,Z) and then using this point with the ECC_key structure.


Have a nice day.

Regards
Seb

Share