Fix the S390X support for the basic AES ciphers
[openssl.git] / providers / common / ciphers / aes_basic.c
index edc6d38..e467622 100644 (file)
@@ -186,7 +186,7 @@ static const PROV_AES_CIPHER aesni_##mode = { \
 static const PROV_AES_CIPHER aes_##mode = { \
         aes_init_key,                   \
         aes_##mode##_cipher}; \
-const PROV_AES_CIPHER *PROV_AES_CIPHER_##mode(void) \
+const PROV_AES_CIPHER *PROV_AES_CIPHER_##mode(size_t keylen) \
 { return AESNI_CAPABLE?&aesni_##mode:&aes_##mode; }
 
 
@@ -358,7 +358,7 @@ static const PROV_AES_CIPHER aes_t4_##mode = { \
 static const PROV_AES_CIPHER aes_##mode = { \
         aes_init_key,                   \
         aes_##mode##_cipher}; \
-const PROV_AES_CIPHER *PROV_AES_CIPHER_##mode(void) \
+const PROV_AES_CIPHER *PROV_AES_CIPHER_##mode(size_t keylen) \
 { return SPARC_AES_CAPABLE?&aes_t4_##mode:&aes_##mode; }
 
 
@@ -368,57 +368,6 @@ const PROV_AES_CIPHER *PROV_AES_CIPHER_##mode(void) \
  */
 # include "s390x_arch.h"
 
-typedef struct {
-    union {
-        double align;
-        /*-
-         * KM-AES parameter block - begin
-         * (see z/Architecture Principles of Operation >= SA22-7832-06)
-         */
-        struct {
-            unsigned char k[32];
-        } param;
-        /* KM-AES parameter block - end */
-    } km;
-    unsigned int fc;
-} S390X_AES_ECB_CTX;
-
-typedef struct {
-    union {
-        double align;
-        /*-
-         * KMO-AES parameter block - begin
-         * (see z/Architecture Principles of Operation >= SA22-7832-08)
-         */
-        struct {
-            unsigned char cv[16];
-            unsigned char k[32];
-        } param;
-        /* KMO-AES parameter block - end */
-    } kmo;
-    unsigned int fc;
-
-    int res;
-} S390X_AES_OFB_CTX;
-
-typedef struct {
-    union {
-        double align;
-        /*-
-         * KMF-AES parameter block - begin
-         * (see z/Architecture Principles of Operation >= SA22-7832-08)
-         */
-        struct {
-            unsigned char cv[16];
-            unsigned char k[32];
-        } param;
-        /* KMF-AES parameter block - end */
-    } kmf;
-    unsigned int fc;
-
-    int res;
-} S390X_AES_CFB_CTX;
-
 /* Convert key size to function code: [16,24,32] -> [18,19,20]. */
 # define S390X_AES_FC(keylen)  (S390X_AES_128 + ((((keylen) << 3) - 128) >> 6))
 
@@ -431,83 +380,71 @@ typedef struct {
                                 S390X_CAPBIT(S390X_AES_256))
 
 # define s390x_aes_init_key aes_init_key
-static int s390x_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-                              const unsigned char *iv, int enc);
+static int s390x_aes_init_key(PROV_AES_KEY *dat, const unsigned char *key,
+                              size_t keylen);
 
-# define S390X_aes_128_cbc_CAPABLE     1       /* checked by callee */
-# define S390X_aes_192_cbc_CAPABLE     1
-# define S390X_aes_256_cbc_CAPABLE     1
-# define S390X_AES_CBC_CTX             PROV_AES_KEY
+# define S390X_aes_128_cbc_CAPABLE  1  /* checked by callee */
+# define S390X_aes_192_cbc_CAPABLE  1
+# define S390X_aes_256_cbc_CAPABLE  1
+# define S390X_AES_CBC_CTX          PROV_AES_KEY
 
 # define s390x_aes_cbc_init_key aes_init_key
 
 # define s390x_aes_cbc_cipher aes_cbc_cipher
-static int s390x_aes_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+static int s390x_aes_cbc_cipher(PROV_AES_KEY *dat, unsigned char *out,
                                 const unsigned char *in, size_t len);
 
-# define S390X_aes_128_ecb_CAPABLE     S390X_aes_128_CAPABLE
-# define S390X_aes_192_ecb_CAPABLE     S390X_aes_192_CAPABLE
-# define S390X_aes_256_ecb_CAPABLE     S390X_aes_256_CAPABLE
+# define S390X_aes_128_ecb_CAPABLE  S390X_aes_128_CAPABLE
+# define S390X_aes_192_ecb_CAPABLE  S390X_aes_192_CAPABLE
+# define S390X_aes_256_ecb_CAPABLE  S390X_aes_256_CAPABLE
 
-static int s390x_aes_ecb_init_key(EVP_CIPHER_CTX *ctx,
-                                  const unsigned char *key,
-                                  const unsigned char *iv, int enc)
+static int s390x_aes_ecb_init_key(PROV_AES_KEY *dat, const unsigned char *key,
+                                  size_t keylen)
 {
-    S390X_AES_ECB_CTX *cctx = EVP_C_DATA(S390X_AES_ECB_CTX, ctx);
-    const int keylen = EVP_CIPHER_CTX_key_length(ctx);
-
-    cctx->fc = S390X_AES_FC(keylen);
-    if (!enc)
-        cctx->fc |= S390X_DECRYPT;
+    dat->plat.s390x.fc = S390X_AES_FC(keylen);
+    if (!dat->enc)
+        dat->plat.s390x.fc |= S390X_DECRYPT;
 
-    memcpy(cctx->km.param.k, key, keylen);
+    memcpy(dat->plat.s390x.param.km.k, key, keylen);
     return 1;
 }
 
-static int s390x_aes_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+static int s390x_aes_ecb_cipher(PROV_AES_KEY *dat, unsigned char *out,
                                 const unsigned char *in, size_t len)
 {
-    S390X_AES_ECB_CTX *cctx = EVP_C_DATA(S390X_AES_ECB_CTX, ctx);
-
-    s390x_km(in, len, out, cctx->fc, &cctx->km.param);
+    s390x_km(in, len, out, dat->plat.s390x.fc,
+             &dat->plat.s390x.param.km);
     return 1;
 }
 
-# define S390X_aes_128_ofb_CAPABLE (S390X_aes_128_CAPABLE &&           \
-                                    (OPENSSL_s390xcap_P.kmo[0] &       \
+# define S390X_aes_128_ofb_CAPABLE (S390X_aes_128_CAPABLE &&        \
+                                    (OPENSSL_s390xcap_P.kmo[0] &    \
                                      S390X_CAPBIT(S390X_AES_128)))
-# define S390X_aes_192_ofb_CAPABLE (S390X_aes_192_CAPABLE &&           \
-                                    (OPENSSL_s390xcap_P.kmo[0] &       \
+# define S390X_aes_192_ofb_CAPABLE (S390X_aes_192_CAPABLE &&        \
+                                    (OPENSSL_s390xcap_P.kmo[0] &    \
                                      S390X_CAPBIT(S390X_AES_192)))
-# define S390X_aes_256_ofb_CAPABLE (S390X_aes_256_CAPABLE &&           \
-                                    (OPENSSL_s390xcap_P.kmo[0] &       \
+# define S390X_aes_256_ofb_CAPABLE (S390X_aes_256_CAPABLE &&        \
+                                    (OPENSSL_s390xcap_P.kmo[0] &    \
                                      S390X_CAPBIT(S390X_AES_256)))
 
-static int s390x_aes_ofb_init_key(EVP_CIPHER_CTX *ctx,
-                                  const unsigned char *key,
-                                  const unsigned char *ivec, int enc)
+static int s390x_aes_ofb_init_key(PROV_AES_KEY *dat, const unsigned char *key,
+                                  size_t keylen)
 {
-    S390X_AES_OFB_CTX *cctx = EVP_C_DATA(S390X_AES_OFB_CTX, ctx);
-    const unsigned char *iv = EVP_CIPHER_CTX_original_iv(ctx);
-    const int keylen = EVP_CIPHER_CTX_key_length(ctx);
-    const int ivlen = EVP_CIPHER_CTX_iv_length(ctx);
-
-    memcpy(cctx->kmo.param.cv, iv, ivlen);
-    memcpy(cctx->kmo.param.k, key, keylen);
-    cctx->fc = S390X_AES_FC(keylen);
-    cctx->res = 0;
+    memcpy(dat->plat.s390x.param.kmo_kmf.cv, dat->iv, AES_BLOCK_SIZE);
+    memcpy(dat->plat.s390x.param.kmo_kmf.k, key, keylen);
+    dat->plat.s390x.fc = S390X_AES_FC(keylen);
+    dat->plat.s390x.res = 0;
     return 1;
 }
 
-static int s390x_aes_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+static int s390x_aes_ofb_cipher(PROV_AES_KEY *dat, unsigned char *out,
                                 const unsigned char *in, size_t len)
 {
-    S390X_AES_OFB_CTX *cctx = EVP_C_DATA(S390X_AES_OFB_CTX, ctx);
-    int n = cctx->res;
+    int n = dat->plat.s390x.res;
     int rem;
 
     while (n && len) {
-        *out = *in ^ cctx->kmo.param.cv[n];
+        *out = *in ^ dat->plat.s390x.param.kmo_kmf.cv[n];
         n = (n + 1) & 0xf;
         --len;
         ++in;
@@ -518,70 +455,63 @@ static int s390x_aes_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
 
     len &= ~(size_t)0xf;
     if (len) {
-        s390x_kmo(in, len, out, cctx->fc, &cctx->kmo.param);
+        s390x_kmo(in, len, out, dat->plat.s390x.fc,
+                  &dat->plat.s390x.param.kmo_kmf);
 
         out += len;
         in += len;
     }
 
     if (rem) {
-        s390x_km(cctx->kmo.param.cv, 16, cctx->kmo.param.cv, cctx->fc,
-                 cctx->kmo.param.k);
+        s390x_km(dat->plat.s390x.param.kmo_kmf.cv, 16,
+                 dat->plat.s390x.param.kmo_kmf.cv, dat->plat.s390x.fc,
+                 dat->plat.s390x.param.kmo_kmf.k);
 
         while (rem--) {
-            out[n] = in[n] ^ cctx->kmo.param.cv[n];
+            out[n] = in[n] ^ dat->plat.s390x.param.kmo_kmf.cv[n];
             ++n;
         }
     }
 
-    cctx->res = n;
+    dat->plat.s390x.res = n;
     return 1;
 }
 
-# define S390X_aes_128_cfb_CAPABLE (S390X_aes_128_CAPABLE &&           \
-                                    (OPENSSL_s390xcap_P.kmf[0] &       \
+# define S390X_aes_128_cfb_CAPABLE (S390X_aes_128_CAPABLE &&        \
+                                    (OPENSSL_s390xcap_P.kmf[0] &    \
                                      S390X_CAPBIT(S390X_AES_128)))
-# define S390X_aes_192_cfb_CAPABLE (S390X_aes_192_CAPABLE &&           \
-                                    (OPENSSL_s390xcap_P.kmf[0] &       \
+# define S390X_aes_192_cfb_CAPABLE (S390X_aes_192_CAPABLE &&        \
+                                    (OPENSSL_s390xcap_P.kmf[0] &    \
                                      S390X_CAPBIT(S390X_AES_192)))
-# define S390X_aes_256_cfb_CAPABLE (S390X_aes_256_CAPABLE &&           \
-                                    (OPENSSL_s390xcap_P.kmf[0] &       \
+# define S390X_aes_256_cfb_CAPABLE (S390X_aes_256_CAPABLE &&        \
+                                    (OPENSSL_s390xcap_P.kmf[0] &    \
                                      S390X_CAPBIT(S390X_AES_256)))
 
-static int s390x_aes_cfb_init_key(EVP_CIPHER_CTX *ctx,
-                                  const unsigned char *key,
-                                  const unsigned char *ivec, int enc)
+static int s390x_aes_cfb_init_key(PROV_AES_KEY *dat, const unsigned char *key,
+                                  size_t keylen)
 {
-    S390X_AES_CFB_CTX *cctx = EVP_C_DATA(S390X_AES_CFB_CTX, ctx);
-    const unsigned char *iv = EVP_CIPHER_CTX_original_iv(ctx);
-    const int keylen = EVP_CIPHER_CTX_key_length(ctx);
-    const int ivlen = EVP_CIPHER_CTX_iv_length(ctx);
-
-    cctx->fc = S390X_AES_FC(keylen);
-    cctx->fc |= 16 << 24;   /* 16 bytes cipher feedback */
-    if (!enc)
-        cctx->fc |= S390X_DECRYPT;
-
-    cctx->res = 0;
-    memcpy(cctx->kmf.param.cv, iv, ivlen);
-    memcpy(cctx->kmf.param.k, key, keylen);
+    dat->plat.s390x.fc = S390X_AES_FC(keylen);
+    dat->plat.s390x.fc |= 16 << 24;   /* 16 bytes cipher feedback */
+    if (!dat->enc)
+        dat->plat.s390x.fc |= S390X_DECRYPT;
+
+    dat->plat.s390x.res = 0;
+    memcpy(dat->plat.s390x.param.kmo_kmf.cv, dat->iv, AES_BLOCK_SIZE);
+    memcpy(dat->plat.s390x.param.kmo_kmf.k, key, keylen);
     return 1;
 }
 
-static int s390x_aes_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+static int s390x_aes_cfb_cipher(PROV_AES_KEY *dat, unsigned char *out,
                                 const unsigned char *in, size_t len)
 {
-    S390X_AES_CFB_CTX *cctx = EVP_C_DATA(S390X_AES_CFB_CTX, ctx);
-    const int keylen = EVP_CIPHER_CTX_key_length(ctx);
-    const int enc = EVP_CIPHER_CTX_encrypting(ctx);
-    int n = cctx->res;
+    int n = dat->plat.s390x.res;
     int rem;
     unsigned char tmp;
 
     while (n && len) {
         tmp = *in;
-        *out = cctx->kmf.param.cv[n] ^ tmp;
-        cctx->kmf.param.cv[n] = enc ? *out : tmp;
+        *out = dat->plat.s390x.param.kmo_kmf.cv[n] ^ tmp;
+        dat->plat.s390x.param.kmo_kmf.cv[n] = dat->enc ? *out : tmp;
         n = (n + 1) & 0xf;
         --len;
         ++in;
@@ -592,120 +522,96 @@ static int s390x_aes_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
 
     len &= ~(size_t)0xf;
     if (len) {
-        s390x_kmf(in, len, out, cctx->fc, &cctx->kmf.param);
+        s390x_kmf(in, len, out, dat->plat.s390x.fc,
+                  &dat->plat.s390x.param.kmo_kmf);
 
         out += len;
         in += len;
     }
 
     if (rem) {
-        s390x_km(cctx->kmf.param.cv, 16, cctx->kmf.param.cv,
-                 S390X_AES_FC(keylen), cctx->kmf.param.k);
+        s390x_km(dat->plat.s390x.param.kmo_kmf.cv, 16,
+                 dat->plat.s390x.param.kmo_kmf.cv,
+                 S390X_AES_FC(dat->keylen), dat->plat.s390x.param.kmo_kmf.k);
 
         while (rem--) {
             tmp = in[n];
-            out[n] = cctx->kmf.param.cv[n] ^ tmp;
-            cctx->kmf.param.cv[n] = enc ? out[n] : tmp;
+            out[n] = dat->plat.s390x.param.kmo_kmf.cv[n] ^ tmp;
+            dat->plat.s390x.param.kmo_kmf.cv[n] = dat->enc ? out[n] : tmp;
             ++n;
         }
     }
 
-    cctx->res = n;
+    dat->plat.s390x.res = n;
     return 1;
 }
 
-# define S390X_aes_128_cfb8_CAPABLE (OPENSSL_s390xcap_P.kmf[0] &       \
+# define S390X_aes_128_cfb8_CAPABLE (OPENSSL_s390xcap_P.kmf[0] &    \
                                      S390X_CAPBIT(S390X_AES_128))
-# define S390X_aes_192_cfb8_CAPABLE (OPENSSL_s390xcap_P.kmf[0] &       \
+# define S390X_aes_192_cfb8_CAPABLE (OPENSSL_s390xcap_P.kmf[0] &    \
                                      S390X_CAPBIT(S390X_AES_192))
-# define S390X_aes_256_cfb8_CAPABLE (OPENSSL_s390xcap_P.kmf[0] &       \
+# define S390X_aes_256_cfb8_CAPABLE (OPENSSL_s390xcap_P.kmf[0] &    \
                                      S390X_CAPBIT(S390X_AES_256))
 
-static int s390x_aes_cfb8_init_key(EVP_CIPHER_CTX *ctx,
-                                   const unsigned char *key,
-                                   const unsigned char *ivec, int enc)
+static int s390x_aes_cfb8_init_key(PROV_AES_KEY *dat, const unsigned char *key,
+                                  size_t keylen)
 {
-    S390X_AES_CFB_CTX *cctx = EVP_C_DATA(S390X_AES_CFB_CTX, ctx);
-    const unsigned char *iv = EVP_CIPHER_CTX_original_iv(ctx);
-    const int keylen = EVP_CIPHER_CTX_key_length(ctx);
-    const int ivlen = EVP_CIPHER_CTX_iv_length(ctx);
-
-    cctx->fc = S390X_AES_FC(keylen);
-    cctx->fc |= 1 << 24;   /* 1 byte cipher feedback */
-    if (!enc)
-        cctx->fc |= S390X_DECRYPT;
-
-    memcpy(cctx->kmf.param.cv, iv, ivlen);
-    memcpy(cctx->kmf.param.k, key, keylen);
+    dat->plat.s390x.fc = S390X_AES_FC(keylen);
+    dat->plat.s390x.fc |= 1 << 24;   /* 1 byte cipher feedback */
+    if (!dat->enc)
+        dat->plat.s390x.fc |= S390X_DECRYPT;
+
+    memcpy(dat->plat.s390x.param.kmo_kmf.cv, dat->iv, AES_BLOCK_SIZE);
+    memcpy(dat->plat.s390x.param.kmo_kmf.k, key, keylen);
     return 1;
 }
 
-static int s390x_aes_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+static int s390x_aes_cfb8_cipher(PROV_AES_KEY *dat, unsigned char *out,
                                  const unsigned char *in, size_t len)
 {
-    S390X_AES_CFB_CTX *cctx = EVP_C_DATA(S390X_AES_CFB_CTX, ctx);
-
-    s390x_kmf(in, len, out, cctx->fc, &cctx->kmf.param);
+    s390x_kmf(in, len, out, dat->plat.s390x.fc,
+              &dat->plat.s390x.param.kmo_kmf);
     return 1;
 }
 
-# define S390X_aes_128_cfb1_CAPABLE    0
-# define S390X_aes_192_cfb1_CAPABLE    0
-# define S390X_aes_256_cfb1_CAPABLE    0
+# define S390X_aes_128_cfb1_CAPABLE 0
+# define S390X_aes_192_cfb1_CAPABLE 0
+# define S390X_aes_256_cfb1_CAPABLE 0
 
 # define s390x_aes_cfb1_init_key aes_init_key
 
 # define s390x_aes_cfb1_cipher aes_cfb1_cipher
-static int s390x_aes_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+static int s390x_aes_cfb1_cipher(PROV_AES_KEY *dat, unsigned char *out,
                                  const unsigned char *in, size_t len);
 
-# define S390X_aes_128_ctr_CAPABLE     1       /* checked by callee */
-# define S390X_aes_192_ctr_CAPABLE     1
-# define S390X_aes_256_ctr_CAPABLE     1
-# define S390X_AES_CTR_CTX             PROV_AES_KEY
+# define S390X_aes_128_ctr_CAPABLE  1  /* checked by callee */
+# define S390X_aes_192_ctr_CAPABLE  1
+# define S390X_aes_256_ctr_CAPABLE  1
+# define S390X_AES_CTR_CTX          PROV_AES_KEY
 
 # define s390x_aes_ctr_init_key aes_init_key
 
 # define s390x_aes_ctr_cipher aes_ctr_cipher
-static int s390x_aes_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+static int s390x_aes_ctr_cipher(PROV_AES_KEY *dat, unsigned char *out,
                                 const unsigned char *in, size_t len);
 
-
-# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,   \
-                              MODE,flags)                              \
-static const EVP_CIPHER s390x_aes_##keylen##_##mode = {                        \
-    nid##_##keylen##_##nmode,blocksize,                                        \
-    keylen / 8,                                                                \
-    ivlen,                                                             \
-    flags | EVP_CIPH_##MODE##_MODE,                                    \
-    s390x_aes_##mode##_init_key,                                       \
-    s390x_aes_##mode##_cipher,                                         \
-    NULL,                                                              \
-    sizeof(S390X_AES_##MODE##_CTX),                                    \
-    NULL,                                                              \
-    NULL,                                                              \
-    NULL,                                                              \
-    NULL                                                               \
-};                                                                     \
-static const EVP_CIPHER aes_##keylen##_##mode = {                      \
-    nid##_##keylen##_##nmode,                                          \
-    blocksize,                                                         \
-    keylen / 8,                                                                \
-    ivlen,                                                             \
-    flags | EVP_CIPH_##MODE##_MODE,                                    \
-    aes_init_key,                                                      \
-    aes_##mode##_cipher,                                               \
-    NULL,                                                              \
-    sizeof(PROV_AES_KEY),                                              \
-    NULL,                                                              \
-    NULL,                                                              \
-    NULL,                                                              \
-    NULL                                                               \
-};                                                                     \
-const EVP_CIPHER *EVP_aes_##keylen##_##mode(void)                      \
-{                                                                      \
-    return S390X_aes_##keylen##_##mode##_CAPABLE ?                     \
-           &s390x_aes_##keylen##_##mode : &aes_##keylen##_##mode;      \
+# define BLOCK_CIPHER_generic_prov(mode) \
+static const PROV_AES_CIPHER s390x_aes_##mode = { \
+        s390x_aes_##mode##_init_key,    \
+        s390x_aes_##mode##_cipher       \
+};  \
+static const PROV_AES_CIPHER aes_##mode = { \
+        aes_init_key,           \
+        aes_##mode##_cipher     \
+}; \
+const PROV_AES_CIPHER *PROV_AES_CIPHER_##mode(size_t keylen) \
+{   \
+    if ((keylen == 128 && S390X_aes_128_##mode##_CAPABLE)           \
+            || (keylen == 192 && S390X_aes_192_##mode##_CAPABLE)    \
+            || (keylen == 256 && S390X_aes_256_##mode##_CAPABLE))   \
+        return &s390x_aes_##mode;   \
+    \
+    return &aes_##mode; \
 }
 
 #else
@@ -714,7 +620,7 @@ const EVP_CIPHER *EVP_aes_##keylen##_##mode(void)                   \
 static const PROV_AES_CIPHER aes_##mode = { \
         aes_init_key,                   \
         aes_##mode##_cipher}; \
-const PROV_AES_CIPHER *PROV_AES_CIPHER_##mode(void) \
+const PROV_AES_CIPHER *PROV_AES_CIPHER_##mode(size_t keylen) \
 { return &aes_##mode; }
 
 #endif