Exemplo n.º 1
0
int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, unsigned char **ek,
	     int *ekl, unsigned char *iv, EVP_PKEY **pubk, int npubk)
	{
	unsigned char key[EVP_MAX_KEY_LENGTH];
	int i;
	
	if(type) {
		EVP_CIPHER_CTX_init(ctx);
		if(!EVP_EncryptInit_ex(ctx,type,NULL,NULL,NULL)) return 0;
	}
	if ((npubk <= 0) || !pubk)
		return 1;
	if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
		return 0;
	if (EVP_CIPHER_CTX_iv_length(ctx))
		RAND_pseudo_bytes(iv,EVP_CIPHER_CTX_iv_length(ctx));

	if(!EVP_EncryptInit_ex(ctx,NULL,NULL,key,iv)) return 0;

	for (i=0; i<npubk; i++)
		{
		ekl[i]=EVP_PKEY_encrypt_old(ek[i],key,EVP_CIPHER_CTX_key_length(ctx),
			pubk[i]);
		if (ekl[i] <= 0) return(-1);
		}
	return(npubk);
	}
Exemplo n.º 2
0
int main()
{
	int ret = -1;
	int verbose = 0;
	BIO *out = NULL;

	int id = EVP_PKEY_SM2;
	const EVP_MD *md = EVP_sm3();
	ENGINE *engine = NULL;

	EVP_PKEY_CTX *pkctx = NULL;
	EVP_PKEY *pkey = NULL;
	EVP_MD_CTX *mdctx = NULL;
	EVP_CIPHER_CTX *cpctx = NULL;

	unsigned char dgst[EVP_MAX_MD_SIZE] = "hello world";
	size_t dgstlen = 32;
	unsigned char sig[256];
	size_t siglen = sizeof(sig);

	unsigned char msg[] = "hello world this is the message";
	size_t msglen = sizeof(msg);
	unsigned char cbuf[512];
	size_t cbuflen = sizeof(cbuf);
	unsigned char mbuf[512];
	size_t mbuflen = sizeof(mbuf);

	int len;
	unsigned int ulen;

	ERR_load_crypto_strings();

	out = BIO_new_fp(stdout, BIO_NOCLOSE);

	if (!(pkctx = EVP_PKEY_CTX_new_id(id, engine))) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (!EVP_PKEY_keygen_init(pkctx)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (!EVP_PKEY_keygen(pkctx, &pkey)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	EVP_PKEY_CTX_free(pkctx);

	if (0) {
		EVP_PKEY_print_public(out, pkey, 4, NULL);
		BIO_printf(out, "\n");
		EVP_PKEY_print_private(out, pkey, 4, NULL);
		BIO_printf(out, "\n");
	}

	if (!(pkctx = EVP_PKEY_CTX_new(pkey, engine))) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	/* EVP_PKEY_sign() */

	if (!EVP_PKEY_sign_init(pkctx)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	bzero(sig, sizeof(sig));
	siglen = sizeof(sig);
	dgstlen = 32;

	if (!EVP_PKEY_sign(pkctx, sig, &siglen, dgst, dgstlen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (verbose) {
		size_t i;
		printf("signature (%zu bytes) = ", siglen);
		for (i = 0; i < siglen; i++) {
			printf("%02X", sig[i]);
		}
		printf("\n");
	}

	if (!EVP_PKEY_verify_init(pkctx)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (EVP_PKEY_verify(pkctx, sig, siglen, dgst, dgstlen) != SM2_VERIFY_SUCCESS) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (verbose) {
		printf("signature verification success!\n");
	}

	/* EVP_PKEY_encrypt() */

	if (!EVP_PKEY_encrypt_init(pkctx)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	cbuflen = sizeof(cbuf);
	if (!EVP_PKEY_encrypt(pkctx, cbuf, &cbuflen, msg, msglen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (verbose) {
		size_t i;
		printf("ciphertext (%zu bytes) = ", cbuflen);
		for (i = 0; i < cbuflen; i++) {
			printf("%02X", cbuf[i]);
		}
		printf("\n");
	}

	if (!EVP_PKEY_decrypt_init(pkctx)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	bzero(mbuf, sizeof(mbuf));
	mbuflen = sizeof(mbuf);
	if (!EVP_PKEY_decrypt(pkctx, mbuf, &mbuflen, cbuf, cbuflen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (verbose) {
		printf("original  message = %s\n", msg);
		printf("decrypted message = %s\n", mbuf);
	}


	/* EVP_PKEY_encrypt_old */


	if ((len = EVP_PKEY_encrypt_old(cbuf, msg, (int)msglen, pkey)) <= 0) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (verbose) {
		int i;
		printf("ciphertext (%d bytes) = ", len);
		for (i = 0; i < len; i++) {
			printf("%02X", cbuf[i]);
		}
		printf("\n");
	}

	bzero(mbuf, sizeof(mbuf));
	if ((len = EVP_PKEY_decrypt_old(mbuf, cbuf, len, pkey)) <= 0) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (verbose) {
		printf("original  message = %s\n", msg);
		printf("decrypted message = %s\n", mbuf);
	}

	if (!(mdctx = EVP_MD_CTX_create())) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	
	/* EVP_SignInit_ex/Update/Final_ex */

	if (!EVP_SignInit_ex(mdctx, EVP_sm3(), engine)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (!EVP_SignUpdate(mdctx, msg, msglen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (!EVP_SignFinal(mdctx, sig, &ulen, pkey)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}
	siglen = ulen;

	if (verbose) {
		size_t i;
		printf("signature (%zu bytes) = ", siglen);
		for (i = 0; i < siglen; i++) {
			printf("%02X", sig[i]);
		}
		printf("\n");
	}

	if (!EVP_VerifyInit_ex(mdctx, EVP_sm3(), engine)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (!EVP_VerifyUpdate(mdctx, msg, msglen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (EVP_VerifyFinal(mdctx, sig, ulen, pkey) != SM2_VERIFY_SUCCESS) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}


	/* EVP_DigestSignInit/Update/Final() */
	// FIXME: return values might be different, not just 1 or 0
	if (!EVP_DigestSignInit(mdctx, &pkctx, md, engine, pkey)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (!EVP_DigestSignUpdate(mdctx, msg, msglen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	siglen = sizeof(sig);
	if (!EVP_DigestSignFinal(mdctx, sig, &siglen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	pkctx = NULL;	
	if (!EVP_DigestVerifyInit(mdctx, &pkctx, md, engine, pkey)) {
		ERR_print_errors_fp(stderr);
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (!EVP_DigestVerifyUpdate(mdctx, msg, msglen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (!EVP_DigestVerifyFinal(mdctx, sig, siglen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}


	/* EVP_SealInit/Update/Final() EVP_OpenInit/Update/Final() */
	/*
	EVP_PKEY *pk[NUM_PKEYS] = {0};
	unsigned char iv[16];
	unsigned char ek[NUM_PKEYS][256];
	int eklen[NUM_PKEYS];

	RAND_pseudo_bytes(iv, sizeof(iv));

	int i;
	for (i = 0; i < NUM_PKEYS; i++) {
	}

	if (!(cpctx = EVP_CIPHER_CTX_new())) {
		goto end;
	}

	if (!EVP_SealInit(cpctx, cipher, ek, &ekl, iv, pubk, npubk)) {
		goto end;
	}

	if (!EVP_SealUpdate(cpctx, msg, msglen)) {
		goto end;
	}

	if (!EVP_SealFinal(cpctx, cbuf, (int *)&cbuflen)) {
		goto end;
	}
	*/

	printf("test success!\n");
	ret = 1;
end:
	ERR_print_errors_fp(stderr);
	return ret;
}
Exemplo n.º 3
0
/**
@fn int soap_mec_init(struct soap *soap, struct soap_mec_data *data, int alg, SOAP_MEC_KEY_TYPE *pkey, unsigned char *key, int *keylen)
@brief Initialize mecevp engine state and create context for
encryption/decryption algorithm using a private/public key or symmetric secret
key.
@param soap context
@param[in,out] data mecevp engine context
@param[in] alg encryption/decryption algorithm
@param[in] pkey public/private key or NULL
@param[in,out] key secret key or encrypted ephemeral secret key set with envelope encryption, or NULL
@param[in,out] keylen secret key length
@return SOAP_OK or SOAP_SSL_ERROR
*/
int
soap_mec_init(struct soap *soap, struct soap_mec_data *data, int alg, SOAP_MEC_KEY_TYPE *pkey, unsigned char *key, int *keylen)
{ int ok = 1;
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_mec_init()\n"));
  soap_ssl_init();
  data->ctx = (EVP_CIPHER_CTX*)SOAP_MALLOC(soap, sizeof(EVP_CIPHER_CTX));
  if (!data->ctx)
    return soap->error = SOAP_EOM;
  EVP_CIPHER_CTX_init(data->ctx);
  data->alg = alg;
  data->state = SOAP_MEC_STATE_NONE;
  if (alg & SOAP_MEC_DES_CBC)
    data->type = EVP_des_ede3_cbc(); /* triple DES CBC */
  else if (alg & SOAP_MEC_AES128_CBC)
    data->type = EVP_get_cipherbyname("AES128");
  else if (alg & SOAP_MEC_AES192_CBC)
    data->type = EVP_get_cipherbyname("AES192");
  else if (alg & SOAP_MEC_AES256_CBC)
    data->type = EVP_get_cipherbyname("AES256");
  else if (alg & SOAP_MEC_AES512_CBC)
    data->type = EVP_get_cipherbyname("AES512");
  else
    data->type = EVP_enc_null();
  data->buf = NULL;
  data->rest = NULL;
  data->restlen = 0;
  if (alg & SOAP_MEC_ENC)
  { if (!data->type)
      return soap_mec_check(soap, data, 0, "soap_mec_init() failed: cannot load cipher");
    EVP_EncryptInit_ex(data->ctx, data->type, NULL, NULL, NULL);
  }
  if (alg & SOAP_MEC_OAEP)
    EVP_CIPHER_CTX_set_padding(data->ctx, RSA_PKCS1_OAEP_PADDING);
  else
    EVP_CIPHER_CTX_set_padding(data->ctx, RSA_PKCS1_PADDING);
  switch (alg & SOAP_MEC_MASK)
  { case SOAP_MEC_ENV_ENC_AES128_CBC:
    case SOAP_MEC_ENV_ENC_AES192_CBC:
    case SOAP_MEC_ENV_ENC_AES256_CBC:
    case SOAP_MEC_ENV_ENC_AES512_CBC:
    case SOAP_MEC_ENV_ENC_DES_CBC:
      ok = EVP_CIPHER_CTX_rand_key(data->ctx, data->ekey);
      /* generate ephemeral secret key */
#if (OPENSSL_VERSION_NUMBER >= 0x01000000L)
      *keylen = EVP_PKEY_encrypt_old(key, data->ekey, EVP_CIPHER_CTX_key_length(data->ctx), pkey);
#else
      *keylen = EVP_PKEY_encrypt(key, data->ekey, EVP_CIPHER_CTX_key_length(data->ctx), pkey);
#endif
      key = data->ekey;
      /* fall through to next arm */
    case SOAP_MEC_ENC_DES_CBC:
    case SOAP_MEC_ENC_AES128_CBC:
    case SOAP_MEC_ENC_AES192_CBC:
    case SOAP_MEC_ENC_AES256_CBC:
    case SOAP_MEC_ENC_AES512_CBC:
      data->bufidx = 0;
      data->buflen = 1024; /* > iv in base64 must fit */
      data->buf = (char*)SOAP_MALLOC(soap, data->buflen);
      data->key = key;
      break;
    case SOAP_MEC_ENV_DEC_AES128_CBC:
    case SOAP_MEC_ENV_DEC_AES192_CBC:
    case SOAP_MEC_ENV_DEC_AES256_CBC:
    case SOAP_MEC_ENV_DEC_AES512_CBC:
    case SOAP_MEC_ENV_DEC_DES_CBC:
    case SOAP_MEC_DEC_DES_CBC:
    case SOAP_MEC_DEC_AES128_CBC:
    case SOAP_MEC_DEC_AES192_CBC:
    case SOAP_MEC_DEC_AES256_CBC:
    case SOAP_MEC_DEC_AES512_CBC:
      data->pkey = pkey;
      data->key = key;
      data->keylen = *keylen;
      break;
    default:
      return soap_set_receiver_error(soap, "Unsupported encryption algorithm", NULL, SOAP_SSL_ERROR);
  }
  return soap_mec_check(soap, data, ok, "soap_mec_init() failed");
}