/* Padding is ignored. We use OAEP by default. Parameter is to support more paddings in the future */ soter_status_t soter_asym_cipher_init(soter_asym_cipher_t* asym_cipher, const void* key, const size_t key_length, soter_asym_cipher_padding_t pad) { EVP_PKEY *pkey; if ((!asym_cipher) || (SOTER_ASYM_CIPHER_OAEP != pad)) { return SOTER_INVALID_PARAMETER; } pkey = EVP_PKEY_new(); if (!pkey) { return SOTER_NO_MEMORY; } /* Only RSA supports asymmetric encryption */ if (!EVP_PKEY_set_type(pkey, EVP_PKEY_RSA)) { EVP_PKEY_free(pkey); return SOTER_FAIL; } asym_cipher->pkey_ctx = EVP_PKEY_CTX_new(pkey, NULL); if (!(asym_cipher->pkey_ctx)) { EVP_PKEY_free(pkey); return SOTER_FAIL; } SOTER_IF_FAIL(soter_asym_cipher_import_key(asym_cipher, key, key_length)==SOTER_SUCCESS, (EVP_PKEY_free(pkey), EVP_PKEY_CTX_free(asym_cipher->pkey_ctx))); return SOTER_SUCCESS; }
soter_status_t soter_sym_aead_decrypt_final(soter_sym_ctx_t *ctx, const void* auth_tag, const size_t auth_tag_length) { SOTER_CHECK_PARAM(auth_tag!=NULL); SOTER_CHECK_PARAM(auth_tag_length>=SOTER_AES_GCM_AUTH_TAG_LENGTH); SOTER_CHECK(ctx!=NULL); SOTER_IF_FAIL(EVP_CIPHER_CTX_ctrl(&(ctx->evp_sym_ctx), EVP_CTRL_GCM_SET_TAG, SOTER_AES_GCM_AUTH_TAG_LENGTH, (void*)auth_tag), soter_sym_aead_decrypt_destroy(ctx)); return soter_sym_aead_ctx_final(ctx, false); }
soter_status_t soter_rsa_key_pair_gen_init(soter_rsa_key_pair_gen_t* ctx, const unsigned key_length){ EVP_PKEY *pkey; pkey = EVP_PKEY_new(); SOTER_CHECK(pkey); /* Only RSA supports asymmetric encryption */ SOTER_IF_FAIL(EVP_PKEY_set_type(pkey, EVP_PKEY_RSA), EVP_PKEY_free(pkey)); ctx->pkey_ctx = EVP_PKEY_CTX_new(pkey, NULL); SOTER_IF_FAIL(ctx->pkey_ctx,EVP_PKEY_free(pkey)); BIGNUM *pub_exp; SOTER_IF_FAIL(EVP_PKEY_keygen_init(ctx->pkey_ctx), EVP_PKEY_CTX_free(ctx->pkey_ctx)); /* Although it seems that OpenSSL/LibreSSL use 0x10001 as default public exponent, we will set it explicitly just in case */ pub_exp = BN_new(); SOTER_CHECK(pub_exp); SOTER_IF_FAIL(BN_set_word(pub_exp, RSA_F4), (BN_free(pub_exp), EVP_PKEY_CTX_free(ctx->pkey_ctx))); SOTER_IF_FAIL(1 <= EVP_PKEY_CTX_ctrl(ctx->pkey_ctx, -1, -1, EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pub_exp), (BN_free(pub_exp), EVP_PKEY_CTX_free(ctx->pkey_ctx))); /* Override default key size for RSA key. Currently OpenSSL has default key size of 1024. LibreSSL has 2048. We will put 2048 explicitly */ SOTER_IF_FAIL((1 <= EVP_PKEY_CTX_ctrl(ctx->pkey_ctx, -1, -1, EVP_PKEY_CTRL_RSA_KEYGEN_BITS, rsa_key_length(key_length), NULL)), (BN_free(pub_exp), EVP_PKEY_CTX_free(ctx->pkey_ctx))); SOTER_IF_FAIL(EVP_PKEY_keygen(ctx->pkey_ctx, &pkey), (BN_free(pub_exp), EVP_PKEY_CTX_free(ctx->pkey_ctx))); return SOTER_SUCCESS; }