}
# endif /* OPENSSL_NO_KTLS_RX */
+
+/* Function to check supported ciphers in Linux */
+static ossl_inline int ktls_check_supported_cipher(const EVP_CIPHER *c,
+ const EVP_CIPHER_CTX *dd)
+{
+ /* check that cipher is AES_GCM_128, AES_GCM_256, AES_CCM_128 */
+ switch (EVP_CIPHER_nid(c))
+ {
+# ifdef OPENSSL_KTLS_AES_CCM_128
+ case NID_aes_128_ccm:
+ if (EVP_CIPHER_CTX_tag_length(dd) != EVP_CCM_TLS_TAG_LEN)
+ return 0;
+# endif
+# ifdef OPENSSL_KTLS_AES_GCM_128
+ case NID_aes_128_gcm:
+# endif
+# ifdef OPENSSL_KTLS_AES_GCM_256
+ case NID_aes_256_gcm:
+# endif
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+/* Function to configure kernel TLS structure */
+static ossl_inline int ktls_configure_crypto(const EVP_CIPHER *c, int tls_version,
+ EVP_CIPHER_CTX *dd, void *rl_sequence,
+ struct tls_crypto_info_all *crypto_info,
+ unsigned char **rec_seq, unsigned char *iv,
+ unsigned char *key)
+{
+ unsigned char geniv[12];
+ unsigned char *iiv = iv;
+
+ if (tls_version == TLS1_2_VERSION &&
+ EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) {
+ EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_GET_IV,
+ EVP_GCM_TLS_FIXED_IV_LEN + EVP_GCM_TLS_EXPLICIT_IV_LEN,
+ geniv);
+ iiv = geniv;
+ }
+
+ memset(crypto_info, 0, sizeof(*crypto_info));
+ switch (EVP_CIPHER_nid(c))
+ {
+# ifdef OPENSSL_KTLS_AES_GCM_128
+ case NID_aes_128_gcm:
+ crypto_info->gcm128.info.cipher_type = TLS_CIPHER_AES_GCM_128;
+ crypto_info->gcm128.info.version = tls_version;
+ crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm128);
+ memcpy(crypto_info->gcm128.iv, iiv + EVP_GCM_TLS_FIXED_IV_LEN,
+ TLS_CIPHER_AES_GCM_128_IV_SIZE);
+ memcpy(crypto_info->gcm128.salt, iiv, TLS_CIPHER_AES_GCM_128_SALT_SIZE);
+ memcpy(crypto_info->gcm128.key, key, EVP_CIPHER_key_length(c));
+ memcpy(crypto_info->gcm128.rec_seq, rl_sequence,
+ TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
+ if (rec_seq != NULL)
+ *rec_seq = crypto_info->gcm128.rec_seq;
+ return 1;
+# endif
+# ifdef OPENSSL_KTLS_AES_GCM_256
+ case NID_aes_256_gcm:
+ crypto_info->gcm256.info.cipher_type = TLS_CIPHER_AES_GCM_256;
+ crypto_info->gcm256.info.version = tls_version;
+ crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm256);
+ memcpy(crypto_info->gcm256.iv, iiv + EVP_GCM_TLS_FIXED_IV_LEN,
+ TLS_CIPHER_AES_GCM_256_IV_SIZE);
+ memcpy(crypto_info->gcm256.salt, iiv, TLS_CIPHER_AES_GCM_256_SALT_SIZE);
+ memcpy(crypto_info->gcm256.key, key, EVP_CIPHER_key_length(c));
+ memcpy(crypto_info->gcm256.rec_seq, rl_sequence,
+ TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
+ if (rec_seq != NULL)
+ *rec_seq = crypto_info->gcm256.rec_seq;
+ return 1;
+# endif
+# ifdef OPENSSL_KTLS_AES_CCM_128
+ case NID_aes_128_ccm:
+ crypto_info->ccm128.info.cipher_type = TLS_CIPHER_AES_CCM_128;
+ crypto_info->ccm128.info.version = tls_version;
+ crypto_info->tls_crypto_info_len = sizeof(crypto_info->ccm128);
+ memcpy(crypto_info->ccm128.iv, iiv + EVP_CCM_TLS_FIXED_IV_LEN,
+ TLS_CIPHER_AES_CCM_128_IV_SIZE);
+ memcpy(crypto_info->ccm128.salt, iiv, TLS_CIPHER_AES_CCM_128_SALT_SIZE);
+ memcpy(crypto_info->ccm128.key, key, EVP_CIPHER_key_length(c));
+ memcpy(crypto_info->ccm128.rec_seq, rl_sequence,
+ TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
+ if (rec_seq != NULL)
+ *rec_seq = crypto_info->ccm128.rec_seq;
+ return 1;
+# endif
+ default:
+ return 0;
+ }
+
+}
+
# endif /* OPENSSL_SYS_LINUX */
# endif /* HEADER_INTERNAL_KTLS */
#else /* defined(OPENSSL_NO_KTLS) */