diff options
Diffstat (limited to 'providers/implementations/include/prov/ciphercommon_gcm.h')
-rw-r--r-- | providers/implementations/include/prov/ciphercommon_gcm.h | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/providers/implementations/include/prov/ciphercommon_gcm.h b/providers/implementations/include/prov/ciphercommon_gcm.h new file mode 100644 index 000000000000..7c4a548f9d44 --- /dev/null +++ b/providers/implementations/include/prov/ciphercommon_gcm.h @@ -0,0 +1,129 @@ + +/* + * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <openssl/aes.h> +#include "ciphercommon_aead.h" + +typedef struct prov_gcm_hw_st PROV_GCM_HW; + +#define GCM_IV_DEFAULT_SIZE 12 /* IV's for AES_GCM should normally be 12 bytes */ +#define GCM_IV_MAX_SIZE (1024 / 8) +#define GCM_TAG_MAX_SIZE 16 + +#if defined(OPENSSL_CPUID_OBJ) && defined(__s390__) +/*- + * KMA-GCM-AES parameter block - begin + * (see z/Architecture Principles of Operation >= SA22-7832-11) + */ +typedef struct S390X_kma_params_st { + unsigned char reserved[12]; + union { + unsigned int w; + unsigned char b[4]; + } cv; /* 32 bit counter value */ + union { + unsigned long long g[2]; + unsigned char b[16]; + } t; /* tag */ + unsigned char h[16]; /* hash subkey */ + unsigned long long taadl; /* total AAD length */ + unsigned long long tpcl; /* total plaintxt/ciphertxt len */ + union { + unsigned long long g[2]; + unsigned int w[4]; + } j0; /* initial counter value */ + unsigned char k[32]; /* key */ +} S390X_KMA_PARAMS; + +#endif + +typedef struct prov_gcm_ctx_st { + unsigned int mode; /* The mode that we are using */ + size_t keylen; + size_t ivlen; + size_t taglen; + size_t tls_aad_pad_sz; + size_t tls_aad_len; /* TLS AAD length */ + uint64_t tls_enc_records; /* Number of TLS records encrypted */ + + /* + * num contains the number of bytes of |iv| which are valid for modes that + * manage partial blocks themselves. + */ + size_t num; + size_t bufsz; /* Number of bytes in buf */ + uint64_t flags; + + unsigned int iv_state; /* set to one of IV_STATE_XXX */ + unsigned int enc:1; /* Set to 1 if we are encrypting or 0 otherwise */ + unsigned int pad:1; /* Whether padding should be used or not */ + unsigned int key_set:1; /* Set if key initialised */ + unsigned int iv_gen_rand:1; /* No IV was specified, so generate a rand IV */ + unsigned int iv_gen:1; /* It is OK to generate IVs */ + + unsigned char iv[GCM_IV_MAX_SIZE]; /* Buffer to use for IV's */ + unsigned char buf[AES_BLOCK_SIZE]; /* Buffer of partial blocks processed via update calls */ + + OSSL_LIB_CTX *libctx; /* needed for rand calls */ + const PROV_GCM_HW *hw; /* hardware specific methods */ + GCM128_CONTEXT gcm; + ctr128_f ctr; + const void *ks; +} PROV_GCM_CTX; + +PROV_CIPHER_FUNC(int, GCM_setkey, (PROV_GCM_CTX *ctx, const unsigned char *key, + size_t keylen)); +PROV_CIPHER_FUNC(int, GCM_setiv, (PROV_GCM_CTX *dat, const unsigned char *iv, + size_t ivlen)); +PROV_CIPHER_FUNC(int, GCM_aadupdate, (PROV_GCM_CTX *ctx, + const unsigned char *aad, size_t aadlen)); +PROV_CIPHER_FUNC(int, GCM_cipherupdate, (PROV_GCM_CTX *ctx, + const unsigned char *in, size_t len, + unsigned char *out)); +PROV_CIPHER_FUNC(int, GCM_cipherfinal, (PROV_GCM_CTX *ctx, unsigned char *tag)); +PROV_CIPHER_FUNC(int, GCM_oneshot, (PROV_GCM_CTX *ctx, unsigned char *aad, + size_t aad_len, const unsigned char *in, + size_t in_len, unsigned char *out, + unsigned char *tag, size_t taglen)); +struct prov_gcm_hw_st { + OSSL_GCM_setkey_fn setkey; + OSSL_GCM_setiv_fn setiv; + OSSL_GCM_aadupdate_fn aadupdate; + OSSL_GCM_cipherupdate_fn cipherupdate; + OSSL_GCM_cipherfinal_fn cipherfinal; + OSSL_GCM_oneshot_fn oneshot; +}; + +OSSL_FUNC_cipher_encrypt_init_fn ossl_gcm_einit; +OSSL_FUNC_cipher_decrypt_init_fn ossl_gcm_dinit; +OSSL_FUNC_cipher_get_ctx_params_fn ossl_gcm_get_ctx_params; +OSSL_FUNC_cipher_set_ctx_params_fn ossl_gcm_set_ctx_params; +OSSL_FUNC_cipher_cipher_fn ossl_gcm_cipher; +OSSL_FUNC_cipher_update_fn ossl_gcm_stream_update; +OSSL_FUNC_cipher_final_fn ossl_gcm_stream_final; +void ossl_gcm_initctx(void *provctx, PROV_GCM_CTX *ctx, size_t keybits, + const PROV_GCM_HW *hw); + +int ossl_gcm_setiv(PROV_GCM_CTX *ctx, const unsigned char *iv, size_t ivlen); +int ossl_gcm_aad_update(PROV_GCM_CTX *ctx, const unsigned char *aad, + size_t aad_len); +int ossl_gcm_cipher_final(PROV_GCM_CTX *ctx, unsigned char *tag); +int ossl_gcm_one_shot(PROV_GCM_CTX *ctx, unsigned char *aad, size_t aad_len, + const unsigned char *in, size_t in_len, + unsigned char *out, unsigned char *tag, size_t tag_len); +int ossl_gcm_cipher_update(PROV_GCM_CTX *ctx, const unsigned char *in, + size_t len, unsigned char *out); + +#define GCM_HW_SET_KEY_CTR_FN(ks, fn_set_enc_key, fn_block, fn_ctr) \ + ctx->ks = ks; \ + fn_set_enc_key(key, keylen * 8, ks); \ + CRYPTO_gcm128_init(&ctx->gcm, ks, (block128_f)fn_block); \ + ctx->ctr = (ctr128_f)fn_ctr; \ + ctx->key_set = 1; |