After further testing and investigation, I've discovered that the encryption and decryption works just fine. I'm actually trying to port parts of this code from adb to wolfssl:
https://cs.android.com/android/platform … 28_gcm.cpp

I've zeroed down the problem to my copy pasta of SPAKE2 from boringssl, needed for pairing authentication in adb. The encryption/decryption must be failing because the key received from SPAKE2_process_msg is wrong.

Try this.

Create a callback for the peer verification to bypass the failure. Returning 1 allows the client to accept any certificate, hence bypassing the certificate verification failure.

int wolfssl_verify_cb(int, WOLFSSL_X509_STORE_CTX*)
{
    return 1;
}

void your_function()
{
    // ...
    SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, wolfssl_verify_cb);
    // ...
}

NOTE: From my experience, wolfSSL uses the callback provided through `SSL_CTX_set_verify`, not `SSL_CTX_set_cert_verify_callback`. I haven't dug through the code completely, but those functions set 2 different variables. I believe the CB variable in `SSL_CTX_set_verify` is the one that gets called when the verification fails.

Hi there,

I'm trying to replicate the functions

 EVP_AEAD_CTX_seal 

and

 EVP_AEAD_CTX_open 

in order to send (and receive) data to a server using BoringSSL. However, the server fails to decrypt the data. It seems like wolfSSL doesn't have any directly compatible functions. Here's my approach:

[UPDATE]: I posted decryption code earlier instead of encryption code, my bad.

// Original code using BoringSSL
size_t Encrypt(bssl::ScopedEVP_AEAD_CTX context, const uint8_t* in, size_t in_len, uint8_t* out, size_t out_len)
{
    size_t written_sz;
    std::vector<uint8_t> nonce(EVP_AEAD_nonce_length(EVP_AEAD_CTX_aead(context.get())), 0);

    if (!EVP_AEAD_CTX_seal(context.get(), out, &written_sz, out_len, nonce.data(),
                                        nonce.size(), in, in_len, nullptr, 0)) {
        std::cerr  << "Failed to encrypt" << std::endl;
        return 0;
    }
    
    return written_sz;
}

and

// Code ported to use wolfSSL
// key_g = { preset key }
size_t Decrypt(wolfssl::UniquePtr<WOLFSSL_EVP_CIPHER_CTX> encryptContext,
                                   const uint8_t* in, size_t in_len, uint8_t* out, size_t out_len)
{
    int written_sz, ret, taglen = 16;
    std::vector<uint8_t> nonce(EVP_CIPHER_iv_length(EVP_aes_128_gcm()), 0);

    ret = EVP_EncryptInit(encryptContext.get(), EVP_aes_128_gcm(), key_g, nonce.data());

    assert(ret == SSL_SUCCESS))

    ret = EVP_EncryptUpdate(encryptContext.get(), out, &written_sz, in, (int)in_len);

    if (ret != WOLFSSL_SUCCESS){
        std::cerr  << "Failed to encrypt" << std::endl;
        return 0;
    }

    ret = EVP_EncryptFinal(encryptContext.get(), out, &written_sz);

    if (ret != WOLFSSL_SUCCESS || written_sz != in_len){
        std::cerr  << "Failed to encrypt" << std::endl;
        return 0;
    }

    unsigned char tag[taglen]
    // the last 16 bytes are the tag. Copy the tag into those last 16 bytes as boringssl does
    assert((in_len + taglen) == out_len);
    assert(EVP_CIPHER_CTX_ctrl(encryptContext.get(), EVP_CTRL_GCM_GET_TAG, taglen, (void*)tag) == SSL_SUCCESS);
    memcpy((void*)(out + in_len), tag, taglen);

    return written_sz + taglen; // bssl returns sizeof(encryptedData) + taglen
}

I tried analyzing the encrypted data for bssl and figured out that authTag, which is 16 bytes (depending on cipher I suppose), is appended to the end of the encryption data. I tried following a similar scheme since wolfSSL didn't have the functions out of the box.

However, the server fails to decrypt the data. Can anybody help out?

Thanks in advance