jedisct1 / libsodium

A modern, portable, easy to use crypto library.
https://libsodium.org
Other
12.15k stars 1.73k forks source link

libsodium in AWS Nitro Enclave #1036

Closed ppmag closed 3 years ago

ppmag commented 3 years ago

Hi, when building simplest C++ hello world, it just hangs at sodium_init(); inmain(), when launched in Nitro Enclave.

I was trying:

  1. Dynamic vs static sodium linking
  2. Fully static executable
  3. AMD vs Intel hardware (m5a.xlarge, m5.xlarge EC2 instance types)
  4. Linux distros: latest amazonlinux vs alpine

What was static in my tests:

  1. libsodium release 1.0.18 built from sources without extra configure flags
  2. g++
    Target: x86_64-redhat-linux
    #68 0.542 Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,objc,obj-c++,fortran,ada,go,lto --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --with-linker-hash-style=gnu --enable-plugin --enable-initfini-array --with-isl --enable-libmpx --enable-libsanitizer --enable-gnu-indirect-function --enable-libcilkrts --enable-libatomic --enable-libquadmath --enable-libitm --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
    #68 0.542 Thread model: posix
    #68 0.542 gcc version 7.3.1 20180712 (Red Hat 7.3.1-12) (GCC)

Question: is it possible to turn ALL optimization in configure to see the differens? Any other ideas to check?

TYA

jedisct1 commented 3 years ago

Maybe this?

ppmag commented 3 years ago

Maybe this?

Thank you. Exactly!

cat /proc/sys/kernel/random/entropy_avail
0

However, while looking for best solution from AWS Nitro team (I suppose, best is to use hardware RNG via their NSM API), (https://github.com/aws/aws-nitro-enclaves-sdk-c/issues/41)

I was trying quick workaround building as ./configure --disable-blocking-random. No success. But why?

jedisct1 commented 3 years ago

The library still needs a way to generate random numbers, if only for memory canaries.

But yes, apparently, the only way to get random numbers in Nitro enclaves seems to be via NSM.

Here, they seem to have an "entropy seeder" that only needs to run once at enclave boot. It seems just call the aws_nitro_enclaves_library_seed_entropy() function.

So, maybe this is the general solution to get entropy for all applications running in such a container?

ppmag commented 3 years ago

@jedisct1 You're absolutely right!

Adding next snippet before sodium_init() resolved this issue:

aws_nitro_enclaves_library_init(NULL);
if (aws_nitro_enclaves_library_seed_entropy(1024) != AWS_OP_SUCCESS)
{
  fputs("aws_nitro_enclaves_library_seed_entropy() failed!\n\n", stderr);
}

.....  and before process exit 

aws_nitro_enclaves_library_clean_up();

I looked into the sources of aws_nitro_enclaves_library_seed_entropy() and was surprised all it's doing is just reading number of bytes specified from entropy ioctl of /dev/nsm and feeding it to the /dev/random.

So, maybe this is the general solution to get entropy for all applications running in such a container?

Definitely! I didn't changed my app at all, just placed it after small binary just doing above things and all's working seamless.

BTW, I still hope AWS Nitro team will add this initialization step for any nitro container at boot stage.

Thank you very much for your support and fantastic de-facto standard lib! Stay healthy!

jedisct1 commented 3 years ago

Glad to hear that it's working!

As I have zero experience with AWS Nitro, would it be possible for you to add a few lines about this to the documentation? That would be awesome, and super helpful to other users who may stumble upon the same issue.

The documentation repository is https://github.com/jedisct1/libsodium-doc

ppmag commented 3 years ago

PR: https://github.com/jedisct1/libsodium-doc/pull/129