Example #1
0
static int test_gcm128(int idx)
{
    unsigned char out[512];
    SIZED_DATA K = gcm128_vectors[idx].K;
    SIZED_DATA IV = gcm128_vectors[idx].IV;
    SIZED_DATA A = gcm128_vectors[idx].A;
    SIZED_DATA P = gcm128_vectors[idx].P;
    SIZED_DATA C = gcm128_vectors[idx].C;
    SIZED_DATA T = gcm128_vectors[idx].T;
    GCM128_CONTEXT ctx;
    AES_KEY key;

    /* Size 1 inputs are special-cased to signal NULL. */
    if (A.size == 1)
        A.data = NULL;
    if (P.size == 1)
        P.data = NULL;
    if (C.size == 1)
        C.data = NULL;

    AES_set_encrypt_key(K.data, K.size * 8, &key);

    CRYPTO_gcm128_init(&ctx, &key, (block128_f)AES_encrypt);
    CRYPTO_gcm128_setiv(&ctx, IV.data, IV.size);
    memset(out, 0, P.size);
    if (A.data != NULL)
        CRYPTO_gcm128_aad(&ctx, A.data, A.size);
    if (P.data != NULL)
        CRYPTO_gcm128_encrypt( &ctx, P.data, out, P.size);
    if (!TEST_false(CRYPTO_gcm128_finish(&ctx, T.data, 16))
            || (C.data != NULL
                    && !TEST_mem_eq(out, P.size, C.data, P.size)))
        return 0;

    CRYPTO_gcm128_setiv(&ctx, IV.data, IV.size);
    memset(out, 0, P.size);
    if (A.data != NULL)
        CRYPTO_gcm128_aad(&ctx, A.data, A.size);
    if (C.data != NULL)
        CRYPTO_gcm128_decrypt(&ctx, C.data, out, P.size);
    if (!TEST_false(CRYPTO_gcm128_finish(&ctx, T.data, 16))
            || (P.data != NULL
                    && !TEST_mem_eq(out, P.size, P.data, P.size)))
        return 0;

    return 1;
}
Example #2
0
static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
                          size_t len) {
  EVP_AES_GCM_CTX *gctx = ctx->cipher_data;

  // If not set up, return error
  if (!gctx->key_set) {
    return -1;
  }
  if (!gctx->iv_set) {
    return -1;
  }

  if (in) {
    if (out == NULL) {
      if (!CRYPTO_gcm128_aad(&gctx->gcm, in, len)) {
        return -1;
      }
    } else if (ctx->encrypt) {
      if (gctx->ctr) {
        if (!CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, &gctx->ks.ks, in, out, len,
                                         gctx->ctr)) {
          return -1;
        }
      } else {
        if (!CRYPTO_gcm128_encrypt(&gctx->gcm, &gctx->ks.ks, in, out, len)) {
          return -1;
        }
      }
    } else {
      if (gctx->ctr) {
        if (!CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, &gctx->ks.ks, in, out, len,
                                         gctx->ctr)) {
          return -1;
        }
      } else {
        if (!CRYPTO_gcm128_decrypt(&gctx->gcm, &gctx->ks.ks, in, out, len)) {
          return -1;
        }
      }
    }
    return len;
  } else {
    if (!ctx->encrypt) {
      if (gctx->taglen < 0 ||
          !CRYPTO_gcm128_finish(&gctx->gcm, ctx->buf, gctx->taglen)) {
        return -1;
      }
      gctx->iv_set = 0;
      return 0;
    }
    CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, 16);
    gctx->taglen = 16;
    // Don't reuse the IV
    gctx->iv_set = 0;
    return 0;
  }
}
Example #3
0
static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
                          const unsigned char *in, size_t len)
{
    EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
    /* If not set up, return error */
    if (!gctx->key_set)
        return -1;

    if (gctx->tls_aad_len >= 0)
        return aes_gcm_tls_cipher(ctx, out, in, len);

    if (!gctx->iv_set)
        return -1;
    if (in) {
        if (out == NULL) {
            if (CRYPTO_gcm128_aad(&gctx->gcm, in, len))
                return -1;
        } else if (ctx->encrypt) {
            if (gctx->ctr) {
                if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm,
                                                in, out, len, gctx->ctr))
                    return -1;
            } else {
                if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len))
                    return -1;
            }
        } else {
            if (gctx->ctr) {
                if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm,
                                                in, out, len, gctx->ctr))
                    return -1;
            } else {
                if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, len))
                    return -1;
            }
        }
        return len;
    } else {
        if (!ctx->encrypt) {
            if (gctx->taglen < 0)
                return -1;
            if (CRYPTO_gcm128_finish(&gctx->gcm, ctx->buf, gctx->taglen) != 0)
                return -1;
            gctx->iv_set = 0;
            return 0;
        }
        CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, 16);
        gctx->taglen = 16;
        /* Don't reuse the IV */
        gctx->iv_set = 0;
        return 0;
    }

}
Example #4
0
static int aria_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
                          const unsigned char *in, size_t len)
{
    EVP_ARIA_GCM_CTX *gctx = EVP_C_DATA(EVP_ARIA_GCM_CTX,ctx);

    /* If not set up, return error */
    if (!gctx->key_set)
        return -1;

    if (gctx->tls_aad_len >= 0)
        return aria_gcm_tls_cipher(ctx, out, in, len);

    if (!gctx->iv_set)
        return -1;
    if (in) {
        if (out == NULL) {
            if (CRYPTO_gcm128_aad(&gctx->gcm, in, len))
                return -1;
        } else if (EVP_CIPHER_CTX_encrypting(ctx)) {
            if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len))
                return -1;
        } else {
            if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, len))
                return -1;
        }
        return len;
    }
    if (!EVP_CIPHER_CTX_encrypting(ctx)) {
        if (gctx->taglen < 0)
            return -1;
        if (CRYPTO_gcm128_finish(&gctx->gcm,
                                 EVP_CIPHER_CTX_buf_noconst(ctx),
                                 gctx->taglen) != 0)
            return -1;
        gctx->iv_set = 0;
        return 0;
    }
    CRYPTO_gcm128_tag(&gctx->gcm, EVP_CIPHER_CTX_buf_noconst(ctx), 16);
    gctx->taglen = 16;
    /* Don't reuse the IV */
    gctx->iv_set = 0;
    return 0;
}
Example #5
0
static int run_test_case(unsigned test_num, const struct test_case *test) {
  size_t key_len, plaintext_len, additional_data_len, nonce_len, ciphertext_len,
      tag_len;
  uint8_t *key = NULL, *plaintext = NULL, *additional_data = NULL,
          *nonce = NULL, *ciphertext = NULL, *tag = NULL, *out = NULL;
  int ret = 0;
  AES_KEY aes_key;
  GCM128_CONTEXT ctx;

  if (!decode_hex(&key, &key_len, test->key, test_num, "key") ||
      !decode_hex(&plaintext, &plaintext_len, test->plaintext, test_num,
                  "plaintext") ||
      !decode_hex(&additional_data, &additional_data_len, test->additional_data,
                  test_num, "additional_data") ||
      !decode_hex(&nonce, &nonce_len, test->nonce, test_num, "nonce") ||
      !decode_hex(&ciphertext, &ciphertext_len, test->ciphertext, test_num,
                  "ciphertext") ||
      !decode_hex(&tag, &tag_len, test->tag, test_num, "tag")) {
    goto out;
  }

  if (plaintext_len != ciphertext_len) {
    fprintf(stderr, "%u: plaintext and ciphertext have differing lengths.\n",
            test_num);
    goto out;
  }

  if (key_len != 16 && key_len != 24 && key_len != 32) {
    fprintf(stderr, "%u: bad key length.\n", test_num);
    goto out;
  }

  if (tag_len != 16) {
    fprintf(stderr, "%u: bad tag length.\n", test_num);
    goto out;
  }

  out = OPENSSL_malloc(plaintext_len);
  if (AES_set_encrypt_key(key, key_len*8, &aes_key)) {
    fprintf(stderr, "%u: AES_set_encrypt_key failed.\n", test_num);
    goto out;
  }

  CRYPTO_gcm128_init(&ctx, &aes_key, (block128_f) AES_encrypt);
  CRYPTO_gcm128_setiv(&ctx, nonce, nonce_len);
  memset(out, 0, plaintext_len);
  if (additional_data) {
    CRYPTO_gcm128_aad(&ctx, additional_data, additional_data_len);
  }
  if (plaintext) {
    CRYPTO_gcm128_encrypt(&ctx, plaintext, out, plaintext_len);
  }
  if (!CRYPTO_gcm128_finish(&ctx, tag, tag_len) ||
      (ciphertext && memcmp(out, ciphertext, plaintext_len) != 0)) {
    fprintf(stderr, "%u: encrypt failed.\n", test_num);
    hexdump("got ", out, plaintext_len);
    hexdump("want", ciphertext, plaintext_len);
    goto out;
  }

  CRYPTO_gcm128_setiv(&ctx, nonce, nonce_len);
  memset(out, 0, plaintext_len);
  if (additional_data) {
    CRYPTO_gcm128_aad(&ctx, additional_data, additional_data_len);
  }
  if (ciphertext) {
    CRYPTO_gcm128_decrypt(&ctx, ciphertext, out, plaintext_len);
  }
  if (!CRYPTO_gcm128_finish(&ctx, tag, tag_len)) {
    fprintf(stderr, "%u: decrypt failed.\n", test_num);
    goto out;
  }
  if (plaintext && memcmp(out, plaintext, plaintext_len)) {
    fprintf(stderr, "%u: plaintext doesn't match.\n", test_num);
    goto out;
  }

  ret = 1;

out:
  OPENSSL_free(key);
  OPENSSL_free(plaintext);
  OPENSSL_free(additional_data);
  OPENSSL_free(nonce);
  OPENSSL_free(ciphertext);
  OPENSSL_free(tag);
  OPENSSL_free(out);
  return ret;
}
static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
                          size_t len) {
  EVP_AES_GCM_CTX *gctx = ctx->cipher_data;

  /* If not set up, return error */
  if (!gctx->key_set) {
    return -1;
  }
  if (!gctx->iv_set) {
    return -1;
  }

  if (in) {
    if (out == NULL) {
      if (!CRYPTO_gcm128_aad(&gctx->gcm, in, len)) {
        return -1;
      }
    } else if (ctx->encrypt) {
      if (gctx->ctr) {
        size_t bulk = 0;
#if defined(AES_GCM_ASM)
        if (len >= 32 && AES_GCM_ASM(gctx)) {
          size_t res = (16 - gctx->gcm.mres) % 16;

          if (!CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, res)) {
            return -1;
          }

          bulk = AES_gcm_encrypt(in + res, out + res, len - res, gctx->gcm.key,
                                 gctx->gcm.Yi.c, gctx->gcm.Xi.u);
          gctx->gcm.len.u[1] += bulk;
          bulk += res;
        }
#endif
        if (!CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, in + bulk, out + bulk,
                                        len - bulk, gctx->ctr)) {
          return -1;
        }
      } else {
        size_t bulk = 0;
        if (!CRYPTO_gcm128_encrypt(&gctx->gcm, in + bulk, out + bulk,
                                  len - bulk)) {
          return -1;
        }
      }
    } else {
      if (gctx->ctr) {
        size_t bulk = 0;
#if defined(AES_GCM_ASM)
        if (len >= 16 && AES_GCM_ASM(gctx)) {
          size_t res = (16 - gctx->gcm.mres) % 16;

          if (!CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, res)) {
            return -1;
          }

          bulk = AES_gcm_decrypt(in + res, out + res, len - res, gctx->gcm.key,
                                 gctx->gcm.Yi.c, gctx->gcm.Xi.u);
          gctx->gcm.len.u[1] += bulk;
          bulk += res;
        }
#endif
        if (!CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, in + bulk, out + bulk,
                                        len - bulk, gctx->ctr)) {
          return -1;
        }
      } else {
        size_t bulk = 0;
        if (!CRYPTO_gcm128_decrypt(&gctx->gcm, in + bulk, out + bulk,
                                  len - bulk)) {
          return -1;
        }
      }
    }
    return len;
  } else {
    if (!ctx->encrypt) {
      if (gctx->taglen < 0 ||
          !CRYPTO_gcm128_finish(&gctx->gcm, ctx->buf, gctx->taglen) != 0) {
        return -1;
      }
      gctx->iv_set = 0;
      return 0;
    }
    CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, 16);
    gctx->taglen = 16;
    /* Don't reuse the IV */
    gctx->iv_set = 0;
    return 0;
  }
}