1*b077aed3SPierre Pronchery 2*b077aed3SPierre Pronchery /* 3*b077aed3SPierre Pronchery * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. 4*b077aed3SPierre Pronchery * 5*b077aed3SPierre Pronchery * Licensed under the Apache License 2.0 (the "License"). You may not use 6*b077aed3SPierre Pronchery * this file except in compliance with the License. You can obtain a copy 7*b077aed3SPierre Pronchery * in the file LICENSE in the source distribution or at 8*b077aed3SPierre Pronchery * https://www.openssl.org/source/license.html 9*b077aed3SPierre Pronchery */ 10*b077aed3SPierre Pronchery 11*b077aed3SPierre Pronchery #include <openssl/aes.h> 12*b077aed3SPierre Pronchery #include "ciphercommon_aead.h" 13*b077aed3SPierre Pronchery 14*b077aed3SPierre Pronchery typedef struct prov_gcm_hw_st PROV_GCM_HW; 15*b077aed3SPierre Pronchery 16*b077aed3SPierre Pronchery #define GCM_IV_DEFAULT_SIZE 12 /* IV's for AES_GCM should normally be 12 bytes */ 17*b077aed3SPierre Pronchery #define GCM_IV_MAX_SIZE (1024 / 8) 18*b077aed3SPierre Pronchery #define GCM_TAG_MAX_SIZE 16 19*b077aed3SPierre Pronchery 20*b077aed3SPierre Pronchery #if defined(OPENSSL_CPUID_OBJ) && defined(__s390__) 21*b077aed3SPierre Pronchery /*- 22*b077aed3SPierre Pronchery * KMA-GCM-AES parameter block - begin 23*b077aed3SPierre Pronchery * (see z/Architecture Principles of Operation >= SA22-7832-11) 24*b077aed3SPierre Pronchery */ 25*b077aed3SPierre Pronchery typedef struct S390X_kma_params_st { 26*b077aed3SPierre Pronchery unsigned char reserved[12]; 27*b077aed3SPierre Pronchery union { 28*b077aed3SPierre Pronchery unsigned int w; 29*b077aed3SPierre Pronchery unsigned char b[4]; 30*b077aed3SPierre Pronchery } cv; /* 32 bit counter value */ 31*b077aed3SPierre Pronchery union { 32*b077aed3SPierre Pronchery unsigned long long g[2]; 33*b077aed3SPierre Pronchery unsigned char b[16]; 34*b077aed3SPierre Pronchery } t; /* tag */ 35*b077aed3SPierre Pronchery unsigned char h[16]; /* hash subkey */ 36*b077aed3SPierre Pronchery unsigned long long taadl; /* total AAD length */ 37*b077aed3SPierre Pronchery unsigned long long tpcl; /* total plaintxt/ciphertxt len */ 38*b077aed3SPierre Pronchery union { 39*b077aed3SPierre Pronchery unsigned long long g[2]; 40*b077aed3SPierre Pronchery unsigned int w[4]; 41*b077aed3SPierre Pronchery } j0; /* initial counter value */ 42*b077aed3SPierre Pronchery unsigned char k[32]; /* key */ 43*b077aed3SPierre Pronchery } S390X_KMA_PARAMS; 44*b077aed3SPierre Pronchery 45*b077aed3SPierre Pronchery #endif 46*b077aed3SPierre Pronchery 47*b077aed3SPierre Pronchery typedef struct prov_gcm_ctx_st { 48*b077aed3SPierre Pronchery unsigned int mode; /* The mode that we are using */ 49*b077aed3SPierre Pronchery size_t keylen; 50*b077aed3SPierre Pronchery size_t ivlen; 51*b077aed3SPierre Pronchery size_t taglen; 52*b077aed3SPierre Pronchery size_t tls_aad_pad_sz; 53*b077aed3SPierre Pronchery size_t tls_aad_len; /* TLS AAD length */ 54*b077aed3SPierre Pronchery uint64_t tls_enc_records; /* Number of TLS records encrypted */ 55*b077aed3SPierre Pronchery 56*b077aed3SPierre Pronchery /* 57*b077aed3SPierre Pronchery * num contains the number of bytes of |iv| which are valid for modes that 58*b077aed3SPierre Pronchery * manage partial blocks themselves. 59*b077aed3SPierre Pronchery */ 60*b077aed3SPierre Pronchery size_t num; 61*b077aed3SPierre Pronchery size_t bufsz; /* Number of bytes in buf */ 62*b077aed3SPierre Pronchery uint64_t flags; 63*b077aed3SPierre Pronchery 64*b077aed3SPierre Pronchery unsigned int iv_state; /* set to one of IV_STATE_XXX */ 65*b077aed3SPierre Pronchery unsigned int enc:1; /* Set to 1 if we are encrypting or 0 otherwise */ 66*b077aed3SPierre Pronchery unsigned int pad:1; /* Whether padding should be used or not */ 67*b077aed3SPierre Pronchery unsigned int key_set:1; /* Set if key initialised */ 68*b077aed3SPierre Pronchery unsigned int iv_gen_rand:1; /* No IV was specified, so generate a rand IV */ 69*b077aed3SPierre Pronchery unsigned int iv_gen:1; /* It is OK to generate IVs */ 70*b077aed3SPierre Pronchery 71*b077aed3SPierre Pronchery unsigned char iv[GCM_IV_MAX_SIZE]; /* Buffer to use for IV's */ 72*b077aed3SPierre Pronchery unsigned char buf[AES_BLOCK_SIZE]; /* Buffer of partial blocks processed via update calls */ 73*b077aed3SPierre Pronchery 74*b077aed3SPierre Pronchery OSSL_LIB_CTX *libctx; /* needed for rand calls */ 75*b077aed3SPierre Pronchery const PROV_GCM_HW *hw; /* hardware specific methods */ 76*b077aed3SPierre Pronchery GCM128_CONTEXT gcm; 77*b077aed3SPierre Pronchery ctr128_f ctr; 78*b077aed3SPierre Pronchery const void *ks; 79*b077aed3SPierre Pronchery } PROV_GCM_CTX; 80*b077aed3SPierre Pronchery 81*b077aed3SPierre Pronchery PROV_CIPHER_FUNC(int, GCM_setkey, (PROV_GCM_CTX *ctx, const unsigned char *key, 82*b077aed3SPierre Pronchery size_t keylen)); 83*b077aed3SPierre Pronchery PROV_CIPHER_FUNC(int, GCM_setiv, (PROV_GCM_CTX *dat, const unsigned char *iv, 84*b077aed3SPierre Pronchery size_t ivlen)); 85*b077aed3SPierre Pronchery PROV_CIPHER_FUNC(int, GCM_aadupdate, (PROV_GCM_CTX *ctx, 86*b077aed3SPierre Pronchery const unsigned char *aad, size_t aadlen)); 87*b077aed3SPierre Pronchery PROV_CIPHER_FUNC(int, GCM_cipherupdate, (PROV_GCM_CTX *ctx, 88*b077aed3SPierre Pronchery const unsigned char *in, size_t len, 89*b077aed3SPierre Pronchery unsigned char *out)); 90*b077aed3SPierre Pronchery PROV_CIPHER_FUNC(int, GCM_cipherfinal, (PROV_GCM_CTX *ctx, unsigned char *tag)); 91*b077aed3SPierre Pronchery PROV_CIPHER_FUNC(int, GCM_oneshot, (PROV_GCM_CTX *ctx, unsigned char *aad, 92*b077aed3SPierre Pronchery size_t aad_len, const unsigned char *in, 93*b077aed3SPierre Pronchery size_t in_len, unsigned char *out, 94*b077aed3SPierre Pronchery unsigned char *tag, size_t taglen)); 95*b077aed3SPierre Pronchery struct prov_gcm_hw_st { 96*b077aed3SPierre Pronchery OSSL_GCM_setkey_fn setkey; 97*b077aed3SPierre Pronchery OSSL_GCM_setiv_fn setiv; 98*b077aed3SPierre Pronchery OSSL_GCM_aadupdate_fn aadupdate; 99*b077aed3SPierre Pronchery OSSL_GCM_cipherupdate_fn cipherupdate; 100*b077aed3SPierre Pronchery OSSL_GCM_cipherfinal_fn cipherfinal; 101*b077aed3SPierre Pronchery OSSL_GCM_oneshot_fn oneshot; 102*b077aed3SPierre Pronchery }; 103*b077aed3SPierre Pronchery 104*b077aed3SPierre Pronchery OSSL_FUNC_cipher_encrypt_init_fn ossl_gcm_einit; 105*b077aed3SPierre Pronchery OSSL_FUNC_cipher_decrypt_init_fn ossl_gcm_dinit; 106*b077aed3SPierre Pronchery OSSL_FUNC_cipher_get_ctx_params_fn ossl_gcm_get_ctx_params; 107*b077aed3SPierre Pronchery OSSL_FUNC_cipher_set_ctx_params_fn ossl_gcm_set_ctx_params; 108*b077aed3SPierre Pronchery OSSL_FUNC_cipher_cipher_fn ossl_gcm_cipher; 109*b077aed3SPierre Pronchery OSSL_FUNC_cipher_update_fn ossl_gcm_stream_update; 110*b077aed3SPierre Pronchery OSSL_FUNC_cipher_final_fn ossl_gcm_stream_final; 111*b077aed3SPierre Pronchery void ossl_gcm_initctx(void *provctx, PROV_GCM_CTX *ctx, size_t keybits, 112*b077aed3SPierre Pronchery const PROV_GCM_HW *hw); 113*b077aed3SPierre Pronchery 114*b077aed3SPierre Pronchery int ossl_gcm_setiv(PROV_GCM_CTX *ctx, const unsigned char *iv, size_t ivlen); 115*b077aed3SPierre Pronchery int ossl_gcm_aad_update(PROV_GCM_CTX *ctx, const unsigned char *aad, 116*b077aed3SPierre Pronchery size_t aad_len); 117*b077aed3SPierre Pronchery int ossl_gcm_cipher_final(PROV_GCM_CTX *ctx, unsigned char *tag); 118*b077aed3SPierre Pronchery int ossl_gcm_one_shot(PROV_GCM_CTX *ctx, unsigned char *aad, size_t aad_len, 119*b077aed3SPierre Pronchery const unsigned char *in, size_t in_len, 120*b077aed3SPierre Pronchery unsigned char *out, unsigned char *tag, size_t tag_len); 121*b077aed3SPierre Pronchery int ossl_gcm_cipher_update(PROV_GCM_CTX *ctx, const unsigned char *in, 122*b077aed3SPierre Pronchery size_t len, unsigned char *out); 123*b077aed3SPierre Pronchery 124*b077aed3SPierre Pronchery #define GCM_HW_SET_KEY_CTR_FN(ks, fn_set_enc_key, fn_block, fn_ctr) \ 125*b077aed3SPierre Pronchery ctx->ks = ks; \ 126*b077aed3SPierre Pronchery fn_set_enc_key(key, keylen * 8, ks); \ 127*b077aed3SPierre Pronchery CRYPTO_gcm128_init(&ctx->gcm, ks, (block128_f)fn_block); \ 128*b077aed3SPierre Pronchery ctx->ctr = (ctr128_f)fn_ctr; \ 129*b077aed3SPierre Pronchery ctx->key_set = 1; 130