intel / linux-sgx

Intel SGX for Linux*
https://www.intel.com/content/www/us/en/developer/tools/software-guard-extensions/linux-overview.html
Other
1.33k stars 544 forks source link

can't verify ECDSA signature signed by ecc_handle #532

Open brenzi opened 4 years ago

brenzi commented 4 years ago

In my enclave, I create a keypair and sign a message:

    let ecc_handle = SgxEccHandle::new();
    let _result = ecc_handle.open();
    let (prv_k, pub_k) = ecc_handle.create_key_pair()?;
    info!("    [Enclave] Generate ephemeral ECDSA keypair successful");
    debug!("     pubkey X is {:02x}", pub_k.gx.iter().format(""));
    debug!("     pubkey Y is {:02x}", pub_k.gy.iter().format(""));
...
    info!("    [Enclave] sign ed25519 pubkey with ephemeral ECDSA key");
    debug!("     payload {:02x}", chain_signer.public().0.iter().format(""));
    let gxgy = ecc_handle
        .ecdsa_sign_slice(&chain_signer.public().0, &prv_k)
        .sgx_error()?;
    let chain_signer_attestation = [gxgy.x, gxgy.y].concat();
    let mut chain_signer_attestation_out = [0u32; 16];
    chain_signer_attestation_out.copy_from_slice(&chain_signer_attestation[..]);
    debug!("     signature: {:02x}", chain_signer_attestation_out.iter().format(""));

giving me

[2020-04-26T08:19:15Z INFO  substratee_worker_enclave::attestation]     [Enclave] Generate keypair
[2020-04-26T08:19:15Z INFO  substratee_worker_enclave::attestation]     [Enclave] Generate ephemeral ECDSA keypair successful
[2020-04-26T08:19:15Z DEBUG substratee_worker_enclave::attestation]      pubkey X is bf6df80bec01cc4d89a56de8146cf5040c4da8e9ff4081edced05b40d1b1a7d9
[2020-04-26T08:19:15Z DEBUG substratee_worker_enclave::attestation]      pubkey Y is c2478c87710ac25aaed30d125c63edb3beba25b5564a5f222fdc09298bad2a67
...
2020-04-26T08:19:17Z DEBUG substratee_worker_enclave::attestation]      payload 93cbb905e945dd817dfa86ff52e1261e7ff6956cf8b76e05e936090aa295138c
[2020-04-26T08:19:17Z DEBUG substratee_worker_enclave::attestation]      signature: 3fadd5de3212cd7b1bdeaf4d8cec4852c38ac5876abcca66737477fa74d22025a2656e6e4873f2afeeb61d79e15cf749f98bbc6eada7a8c5c29d968ed42d6aa3

Now I'm trying to verify the signature with ring. But the pubkey seems not to be on the curve (I also tried reversing the bytes in case it was little-endian). Also boringSLL thinks it's not on the curve.

From these lines https://github.com/intel/linux-sgx/blob/4589daddd58bec7367a6a9de3fe301e6de17671a/sdk/tlibcrypto/sgxssl/sgx_ecc256.cpp#L57

I would conclude that ecc_handle is using the prime256v1 curve, equivalent to the NIST P-256 / secp256r1 that ring refers to with ECDSA_P256_SHA256_FIXED

So I'd concatenate X and Y and prefix it with 0x04 to pass it to ring:

04 bf6df80bec01cc4d89a56de8146cf5040c4da8e9ff4081edced05b40d1b1a7d9 c2478c87710ac25aaed30d125c63edb3beba25b5564a5f222fdc09298bad2a67

So why is the pubkey not on the curve?

lzha101 commented 4 years ago

Verifying failure may be related to endian switch. The output keys from SGX SDK are little endian.

And SGX also provides a function for checking whether a pub key is on the curve or not, named sgx_ecc256_check_point(). You can try this function as well.

brenzi commented 4 years ago

I tried little and big endian. both fail. verifying with intel sdk tools works, so there is no point in trying the check-point fn. It seems more like an incompatibility with openssl