Crypto libraries introduction Milan Brož xbroz@fi.muni.cz PV181, FI MUNI, Brno Cryptographic libraries plan for next three PV181 labs lLinux environment lFedora in VirtualBox (image in IS) or laisa.fi.muni.cz (OpenSSL only) or lYour own distro lExamples in C language lHome assignments (10 points each) Lab environment VirtualBox image lUnpack zip archive from IS lOpen VirtualBox (click blue icon – config file) lLogin and password is pv181 (same for sudo and root password) lExamples on gitlab git clone https://gitlab.fi.muni.cz/xbroz/pv181.git make clean; make; ./example Cryptographic libraries Introduction lOpen-source / Proprietary lStatic + embedded / dynamically linked lLow or high level abstractions lMultiplatform lStable API and ABI lSecurity or platform specific features lSafe memory use, side-channel resistance, … lHW acceleration support, “secure” HW support Example libs (C and Linux) abstraction from low to high lNettle llibgcrypt lOpenSSL lLibreSSL (clone), BoringSSL (Google) lNSS lNetwork Security Services (Mozilla) lNaCl ("salt") lmore common as libsodium Crypto libraries lRandom Number Generator (RNG) access lHash, keyed-hash (HMAC, msg authentication) lSymmetric ciphers and modes lAsymmetric ciphers lCertificate support, ASN.1, ... lKey exchange, key derivation lHelpers lsecure memory lsafe comparison lnetwork / sockets l... Today’s exercise lLow-level crypto primitives lRNG lHash, HMAC lPBKDF l lExamples comparison in OpenSSL, gcrypt, libsodium l lLearn to write code in a defensive approach It will fail, be prepared for it. J Why implementation matters lIt works, but … lHow many possible bugs do you see? /* Read a key from Linux RNG */ #include #include #include int main(int argc, char *argv[]) { int fd; char key[32]; fd = open("/dev/random", O_RDONLY); read(fd, key, 32); close(fd); /* Do something with the key[] */ memset(key, 0, 32); return 0; } Example 1: RNG in libraries libgcrypt see 1_rng_gcrypt example (void) gcry_randomize(buf, sizeof(buf), GCRY_STRONG_RANDOM); OpenSSL see 1_rng_openssl example (int) RAND_bytes(buf, sizeof(buf)) libsodium see 1_rng_sodium example (void) randombytes(buf, sizeof(buf)); Simple? Not in real-world. RNG or pseudo RNG, optional parameters, initialization or another call for configuration, can/cannot fail, can/cannot block if not enough entropy, is it own implementation or wrapper to system RNG, can it be used in FIPS mode ... Example 2: Hash functions libgcrypt See 2_hash_hmac_gcrypt example gcry_md_open(context, hash_id, flags) gcry_md_write(context, data, data_len) gcry_md_read(context, hash_id) gcry_md_close(context) OpenSSL (new 1.1.0 syntax) EVP (envelope) interface, see 2_hash_hmac_openssl example EVP_MD_CTX_new(); EVP_DigestInit(context, hash_id) EVP_DigestUpdate(context, data, data_len) EVP_DigestFinal(context, out, &out_len) EVP_MD_CTX_free(context); libsodium See 2_hash_hmac_sodium example crypto_hash_sha256_init(context) crypto_hash_sha256_update(context, data, data_len) crypto_hash_sha256_final(context, out)) Example 2: HMAC Keyed Hash Message Authentication Code libgcrypt See 2_hash_hmac_gcrypt example gcry_md_open(context, hash_id, GCRY_MD_FLAG_HMAC) gcry_md_setkey(context, key, key_len) gcry_md_write(context, data, data_len) gcry_md_read(context, hash_id) gcry_md_close(context) OpenSSL (new 1.1.0 syntax) EVP interface or direct calls, see 2_hash_hmac_openssl example HMAC_CTX_new(); HMAC_Init(context, key, key_len, hash_id) HMAC_Update(context, data, data_len) HMAC_Final(context, out, &out_len) HMAC_CTX_free(context); libsodium NaCl compatible interface, see 2_hash_hmac_sodium example crypto_auth(out, data, data_len, key)) crypto_auth_verify(expected_out, data, data_len, key)) Example 3: PBKDF Password-Based Key Derivation Functions libgcrypt See 3_pbkdf_gcrypt example gcry_kdf_derive(password, password_len, GCRY_KDF_PBKDF2, GCRY_MD_SHA256, salt, salt_len, iterations, key_len, key) OpenSSL See 3_pbkdf_openssl example PKCS5_PBKDF2_HMAC(password, password_len, salt, salt_len, iterations, EVP_sha256, key_len, key) libsodium (no example intentionally, default Argon2i is too recent :-) crypto_pwhash(key, key_len, password, password_len, salt, opslimit, memlimit, algorithm) Note: old API functions based on PBKDF2 (supports only time cost – iterations) For recent algorithms (scrypt, Argon2i) API calls are often abused ... Assignment lGoal is to lWork with standard (RFC) document lUse test vectors (self-test) lUse OpenSSL in a Linux environment lSee Assignment.txt in IS lYou can use the provided example lComment your code lbut do not overuse comments lNO plagiarism (even from previous years) l=> 0 points for both sides (sender & receiver) lCode quality matters!