+static int ossltest_aes128_init_key(EVP_CIPHER_CTX *ctx,
+ const unsigned char *key,
+ const unsigned char *iv, int enc);
+static int ossltest_aes128_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl);
+static int ossltest_aes128_gcm_init_key(EVP_CIPHER_CTX *ctx,
+ const unsigned char *key,
+ const unsigned char *iv, int enc);
+static int ossltest_aes128_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl);
+static int ossltest_aes128_gcm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
+ void *ptr);
+static int ossltest_aes128_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx,
+ const unsigned char *key,
+ const unsigned char *iv,
+ int enc);
+static int ossltest_aes128_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx,
+ unsigned char *out,
+ const unsigned char *in,
+ size_t inl);
+static int ossltest_aes128_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type,
+ int arg, void *ptr);
+
+typedef struct {
+ size_t payload_length; /* AAD length in decrypt case */
+ unsigned int tls_ver;
+} EVP_AES_HMAC_SHA1;
+
+static EVP_CIPHER *_hidden_aes_128_cbc = NULL;
+static const EVP_CIPHER *ossltest_aes_128_cbc(void)
+{
+ if (_hidden_aes_128_cbc == NULL
+ && ((_hidden_aes_128_cbc = EVP_CIPHER_meth_new(NID_aes_128_cbc,
+ 16 /* block size */,
+ 16 /* key len */)) == NULL
+ || !EVP_CIPHER_meth_set_iv_length(_hidden_aes_128_cbc,16)
+ || !EVP_CIPHER_meth_set_flags(_hidden_aes_128_cbc,
+ EVP_CIPH_FLAG_DEFAULT_ASN1
+ | EVP_CIPH_CBC_MODE)
+ || !EVP_CIPHER_meth_set_init(_hidden_aes_128_cbc,
+ ossltest_aes128_init_key)
+ || !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_128_cbc,
+ ossltest_aes128_cbc_cipher)
+ || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_128_cbc,
+ EVP_CIPHER_impl_ctx_size(EVP_aes_128_cbc())))) {
+ EVP_CIPHER_meth_free(_hidden_aes_128_cbc);
+ _hidden_aes_128_cbc = NULL;
+ }
+ return _hidden_aes_128_cbc;
+}
+
+static EVP_CIPHER *_hidden_aes_128_gcm = NULL;
+
+#define AES_GCM_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 \
+ | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
+ | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \
+ | EVP_CIPH_CUSTOM_COPY |EVP_CIPH_FLAG_AEAD_CIPHER \
+ | EVP_CIPH_GCM_MODE)
+
+static const EVP_CIPHER *ossltest_aes_128_gcm(void)
+{
+ if (_hidden_aes_128_gcm == NULL
+ && ((_hidden_aes_128_gcm = EVP_CIPHER_meth_new(NID_aes_128_gcm,
+ 1 /* block size */,
+ 16 /* key len */)) == NULL
+ || !EVP_CIPHER_meth_set_iv_length(_hidden_aes_128_gcm,12)
+ || !EVP_CIPHER_meth_set_flags(_hidden_aes_128_gcm, AES_GCM_FLAGS)
+ || !EVP_CIPHER_meth_set_init(_hidden_aes_128_gcm,
+ ossltest_aes128_gcm_init_key)
+ || !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_128_gcm,
+ ossltest_aes128_gcm_cipher)
+ || !EVP_CIPHER_meth_set_ctrl(_hidden_aes_128_gcm,
+ ossltest_aes128_gcm_ctrl)
+ || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_128_gcm,
+ EVP_CIPHER_impl_ctx_size(EVP_aes_128_gcm())))) {
+ EVP_CIPHER_meth_free(_hidden_aes_128_gcm);
+ _hidden_aes_128_gcm = NULL;
+ }
+ return _hidden_aes_128_gcm;
+}
+
+static EVP_CIPHER *_hidden_aes_128_cbc_hmac_sha1 = NULL;
+
+static const EVP_CIPHER *ossltest_aes_128_cbc_hmac_sha1(void)
+{
+ if (_hidden_aes_128_cbc_hmac_sha1 == NULL
+ && ((_hidden_aes_128_cbc_hmac_sha1
+ = EVP_CIPHER_meth_new(NID_aes_128_cbc_hmac_sha1,
+ 16 /* block size */,
+ 16 /* key len */)) == NULL
+ || !EVP_CIPHER_meth_set_iv_length(_hidden_aes_128_cbc_hmac_sha1,16)
+ || !EVP_CIPHER_meth_set_flags(_hidden_aes_128_cbc_hmac_sha1,
+ EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 |
+ EVP_CIPH_FLAG_AEAD_CIPHER)
+ || !EVP_CIPHER_meth_set_init(_hidden_aes_128_cbc_hmac_sha1,
+ ossltest_aes128_cbc_hmac_sha1_init_key)
+ || !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_128_cbc_hmac_sha1,
+ ossltest_aes128_cbc_hmac_sha1_cipher)
+ || !EVP_CIPHER_meth_set_ctrl(_hidden_aes_128_cbc_hmac_sha1,
+ ossltest_aes128_cbc_hmac_sha1_ctrl)
+ || !EVP_CIPHER_meth_set_set_asn1_params(_hidden_aes_128_cbc_hmac_sha1,
+ EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv)
+ || !EVP_CIPHER_meth_set_get_asn1_params(_hidden_aes_128_cbc_hmac_sha1,
+ EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv)
+ || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_128_cbc_hmac_sha1,
+ sizeof(EVP_AES_HMAC_SHA1)))) {
+ EVP_CIPHER_meth_free(_hidden_aes_128_cbc_hmac_sha1);
+ _hidden_aes_128_cbc_hmac_sha1 = NULL;
+ }
+ return _hidden_aes_128_cbc_hmac_sha1;
+}
+
+static void destroy_ciphers(void)
+{
+ EVP_CIPHER_meth_free(_hidden_aes_128_cbc);
+ EVP_CIPHER_meth_free(_hidden_aes_128_gcm);
+ EVP_CIPHER_meth_free(_hidden_aes_128_cbc_hmac_sha1);
+ _hidden_aes_128_cbc = NULL;
+ _hidden_aes_128_gcm = NULL;
+ _hidden_aes_128_cbc_hmac_sha1 = NULL;
+}
+
+/* Key loading */
+static EVP_PKEY *load_key(ENGINE *eng, const char *key_id, int pub,
+ UI_METHOD *ui_method, void *ui_data)
+{
+ BIO *in;
+ EVP_PKEY *key;
+
+ if (!CHECK_AND_SKIP_CASE_PREFIX(key_id, "ot:"))
+ return NULL;
+
+ fprintf(stderr, "[ossltest]Loading %s key %s\n",
+ pub ? "Public" : "Private", key_id);
+ in = BIO_new_file(key_id, "r");
+ if (!in)
+ return NULL;
+ if (pub)
+ key = PEM_read_bio_PUBKEY(in, NULL, 0, NULL);
+ else
+ key = PEM_read_bio_PrivateKey(in, NULL, 0, NULL);
+ BIO_free(in);
+ return key;
+}
+
+static EVP_PKEY *ossltest_load_privkey(ENGINE *eng, const char *key_id,
+ UI_METHOD *ui_method, void *ui_data)
+{
+ return load_key(eng, key_id, 0, ui_method, ui_data);
+}
+
+static EVP_PKEY *ossltest_load_pubkey(ENGINE *eng, const char *key_id,
+ UI_METHOD *ui_method, void *ui_data)
+{
+ return load_key(eng, key_id, 1, ui_method, ui_data);
+}