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