cisco / libsrtp

Library for SRTP (Secure Realtime Transport Protocol)
Other
1.23k stars 476 forks source link

libsrtp-1.5.3 + openssl + cryptodev engine #147

Closed grbesd1 closed 7 years ago

grbesd1 commented 8 years ago

how to use cryptodev engine(hardware encryption) in libsrtp-1.5.3 with openssl?

we want to stream fullHD(1920 * 1080 @ 15fps) with hardware encryption using symmetric key encryption.

jfigus commented 8 years ago

You would use the --enable-openssl option. Optionally, you can use the --with-openssl-dir option to link to a specific OpenSSL build. But usually it works fine if you simply have the openssl-devel package installed on the Linux system. It requires OpenSSL 1.0.1 or newer.

If you're looking for optimal performance at the SRTP layer, consider using the newer AES-GCM crypto suite. This eliminates the SHA1 calculation, which improves performance. AES-GCM uses GHash for integrity checking instead of SHA1. When coupled with AES-NI support on the chipset, this is the best option for performance.

grbesd1 commented 8 years ago

Hi @jfigus, OpenSSL 1.0.1 is part of my yocto build directory. one big question how can i configure aes-128-cbc/ctr mode. In libsrtp how i'm i suppose to link cryptodev engine and what are the step it will follow to encrypt large chunk of streaming data. If you could step by step tell me what i have to do it will be very nice i already wasted two weeks on reading documents.

Note: i have a deadline to catch plus i'm a greenhorn to this whole project.

grbesd1 commented 8 years ago

i have done in this by using for different host: ./configure --host=arm-poky-linux-gnueabi --enable-openssl this is OK but i have use cryptodev engine(hardware encryption) how to do that with aes-128-cbc?

jfigus commented 8 years ago

When using --enable-openssl, you'll be using openssl for the encryption. Getting openssl to use a hardware encryption module (e.g. HSM) is another challenge. You may want to reach out to the OpenSSL community with this question.

grbesd1 commented 8 years ago

openssl is already using ctr engine but i have to enable crptodev engine in libsrtp-1.5.3/crypto/cipher/aes_icm_ossl.c

grbesd1 commented 8 years ago

below is the link from source forge https://sourceforge.net/p/srtp/mailman/srtp-development/thread/52EBE2AE.3090105@cisco.com/ which i believe you have mention that

To utilize your OpenSSL engine, very few changes should be required to libsrtp. The third parameter to EVP_EncryptInit_ex() in aes_icm.c is currently NULL. You'll just need to change parameter to reference your OpenSSL engine. You'll need to make a similar change to the SHA1 initializer if your engine supports SHA1 >

jfigus commented 8 years ago

Yes, you could pass the ENGINE* reference to the 3rd argument of EVP_EncryptInit_ex(). But if you're engine is a built-in engine, it may be used by default if your application code invokes ENGINE_load_builtin_engines(). You'll probably want to start reading here to learn more about how engines are handled in OpenSSL: http://www.openssl.org/docs/crypto/engine.html

grbesd1 commented 8 years ago

I have added engine in this function aes_icm_openssl_set_iv() in aes_icm_ossl.c file:

ENGINE *crypto_eng; ENGINE_load_builtin_engines(); if (!(crypto_eng = ENGINE_by_id("cryptodev"))) fprintf(stderr, "Error finding specified ENGINE\n"); else if (!ENGINE_set_default(crypto_eng, ENGINE_METHOD_ALL)) fprintf(stderr, "Error using ENGINE\n"); else fprintf(stderr, "Engine successfully enabled\n"); if (!EVP_EncryptInit_ex(&c->ctx, evp, crypto_eng, c->key.v8, c->counter.v8)) { return err_status_fail; } else { return err_status_ok; }

but after compiling when i'm running my application it is printing "engine successfully enabled" and some processing in eng_crprodev.c and evp_enc.c finally it is calling put_dev_crypto and then i'm getting segmentation fault.

i have changed the output buffer size

unsigned char out_buf[1024*1024*2]; unsigned char plaintext_temp_buff[1024] = {0};

is it because of that or i'm not properly invoking engine.

Vijayendar commented 8 years ago

Hi, Unfortunately, our CAAM (Cryptographic Acceleration and Assurance Module) driver does not support AES-GCM. We are using an iMX6 SOC and it has a hardware accelerator called CAAM to do encryption/decryption. So, we are stuck with AES-CTR mode to do hardware encryption with libsrtp. We are using a Gstreamer bad plugin (srtpenc) which relies on libsrtp to do real time encryption of live RTP video packets.

Vijayendar commented 8 years ago
  1. Coming back to the issue at hand, I modified the encrypt function in aes_icm_openssl.c to give a different buffer for input and output.
  2. In the original code, the encryption was done in place. This change was done because of a segmentation fault thrown from the EVP_EncryptUpdate() call.
  3. I debugged this and couldn't find anything strange in the cryptodev as well as openssl code (buffer overflows, memory leaks or out of bound array access) except for the in place computation.
  4. So, I declared a global buffer for 1 KB (out_buf) and gave this as the output argument to EVP_EncryptUpdate() and now, the encryption and decryption succeeded, except that the input had to be padded to a multiple of 16 so that the decryption could succeed, later. This was a workaround/hack I did to get basic hardware encryption with AES-CTR, working.
  5. The 1 KB size was arbitrary and chosen to make the srtp driver tests work. To encrypt video, I had to increase the buffer size and so, I chose a maximum size of 2 MB (I didn't want to allocate dynamic memory to keep things simple) to hold the video packets.
  6. Now, it seems that the code is throwing a segmentation fault (during encryption) with a 2 MB buffer size. Things work well with a 1 KB buffer size, but video decryption is failing (a blank screen is seen), since buffer size is limited to 1KB (not enough to hold video packets).
  7. Please note that encryption/decryption works fine without crypto engine support. i.e. if we pass NULL as the 3rd argument to EVP_EncryptInit_ex(), there's no need for a separate input/output buffer, and encryption and decryption work fine with large buffers too (video can be encrypted/decrypted).
  8. But we want the hardware engine support to speed up video encryption/decryption and hence this exercise.
Vijayendar commented 8 years ago

Please note that we have enough free memory (DDR RAM) on the board to declare a 2 MByte static buffer.

We have spent considerable time doing research on this (Googling, basically) to see if others have faced such an issue/implemented hardware support for AES-CTR on iMX6 from libsrtp. Unfortunately, we have not found anything that could help us, except this forum.

It would be very nice if the experts here could review the changes in aes_icm_ossl.c and provide any suggestion/pointers to look into.

Thanks.

jfigus commented 8 years ago

If you're looking for support for the OpenSSL engine interface, this is the wrong forum. You'll want to reach out to the OpenSSL community. A good place to start would be openssl-users@openssl.org.

lmtan91 commented 8 years ago

@grbesd1 @jfigus @Vijayendar Dear all,

Any updates on the hardware engine support to speed up video encryption/decryption for libsrtp?

Thanks, Tan

pabuhler commented 7 years ago

@grbesd1 Hi did you get this working? I saw this post https://mta.openssl.org/pipermail/openssl-users/2016-February/003023.html but did not see any replies. I wondered if the problem is related to padding? Did you try with EVP_CIPHER_CTX_set_padding?

When quickly grepping in the openssl source code for EVP_EncryptUpdate I see a couple of places where the input and output buffers are the same so I assume it is safe to do so. Although assumptions are dangerous.

pabuhler commented 7 years ago

Will close this as am not sure what is required from the libsrtp team. If you have a specific openssl engine that should be used then either modify libsrtp to use that engine or else config openssl to use that engine by default. If these approaches do not work then we can try to make an example as supporting different engines is definitely a desired feature of libsrtp.