Exemple #1
0
//The partner decryption function to above
unsigned char *blowfish_dec(unsigned char *key, unsigned char* data, int size)
{
	unsigned char* out = malloc(size);
	int outlen;
	int tmplen;
	unsigned char iv[] = {0}; //TODO maybe not this?
	EVP_CIPHER_CTX ctx;
	EVP_CIPHER_CTX_init(&ctx);
	EVP_DecryptInit_ex(&ctx, EVP_bf_ecb(), NULL, key, iv);
	EVP_CIPHER_CTX_set_padding(&ctx, 0);
	
	EVP_DecryptUpdate(&ctx, out, &outlen, data, size);

	if(!EVP_DecryptFinal_ex(&ctx, out + outlen, &tmplen)) {
		ssl_error("Didn't do decrypt final");
	}
	outlen += tmplen;
	EVP_CIPHER_CTX_cleanup(&ctx);
	return out;
}
Exemple #2
0
static LUA_FUNCTION(openssl_cipher_encrypt_new)
{
  const EVP_CIPHER* cipher  = get_cipher(L, 1, NULL);
  if (cipher)
  {
    size_t key_len = 0;
    const char *key = luaL_optlstring(L, 2, NULL, &key_len); /* can be NULL */
    size_t iv_len = 0;
    const char *iv = luaL_optlstring(L, 3, NULL, &iv_len); /* can be NULL */
    int pad = lua_isnoneornil(L, 4) ? 1 : lua_toboolean(L, 4);
    ENGINE *e = lua_isnoneornil(L, 5) ? NULL : CHECK_OBJECT(5, ENGINE, "openssl.engine");
    EVP_CIPHER_CTX *c = NULL;

    char evp_key[EVP_MAX_KEY_LENGTH] = {0};
    char evp_iv[EVP_MAX_IV_LENGTH] = {0};
    if (key)
    {
      key_len = EVP_MAX_KEY_LENGTH > key_len ? key_len : EVP_MAX_KEY_LENGTH;
      memcpy(evp_key, key, key_len);
    }
    if (iv_len > 0 && iv)
    {
      iv_len = EVP_MAX_IV_LENGTH > iv_len ? iv_len : EVP_MAX_IV_LENGTH;
      memcpy(evp_iv, iv, iv_len);
    }
    c = EVP_CIPHER_CTX_new();
    EVP_CIPHER_CTX_init(c);
    if (!EVP_EncryptInit_ex(c, cipher, e, key ? (const byte*)evp_key : NULL, iv_len > 0 ? (const byte*)evp_iv : NULL))
    {
      EVP_CIPHER_CTX_set_padding(c, pad);
      luaL_error(L, "EVP_CipherInit_ex failed, please check openssl error");
    }
    PUSH_OBJECT(c, "openssl.evp_cipher_ctx");
    lua_pushinteger(L, DO_ENCRYPT);
    lua_rawsetp(L, LUA_REGISTRYINDEX, c);
  }
  else
    luaL_error(L, "argument #1 is not a valid cipher algorithm or openssl.evp_cipher object");

  return 1;
}
static int sqlcipher_openssl_cipher(void *ctx, int mode, unsigned char *key, int key_sz, unsigned char *iv, unsigned char *in, int in_sz, unsigned char *out) {
  int tmp_csz, csz, rc = SQLITE_OK;
  EVP_CIPHER_CTX* ectx = EVP_CIPHER_CTX_new();
  if(ectx == NULL) goto error;
  if(!EVP_CipherInit_ex(ectx, ((openssl_ctx *)ctx)->evp_cipher, NULL, NULL, NULL, mode)) goto error; 
  if(!EVP_CIPHER_CTX_set_padding(ectx, 0)) goto error; /* no padding */
  if(!EVP_CipherInit_ex(ectx, NULL, NULL, key, iv, mode)) goto error;
  if(!EVP_CipherUpdate(ectx, out, &tmp_csz, in, in_sz)) goto error;
  csz = tmp_csz;  
  out += tmp_csz;
  if(!EVP_CipherFinal_ex(ectx, out, &tmp_csz)) goto error;
  csz += tmp_csz;
  assert(in_sz == csz);

  goto cleanup;
error:
  rc = SQLITE_ERROR;
cleanup:
  if(ectx) EVP_CIPHER_CTX_free(ectx);
  return rc; 
}
int32_t psAesInitCBC(psAesCbc_t *ctx,
    const unsigned char IV[AES_IVLEN],
    const unsigned char key[AES_MAXKEYLEN], uint8_t keylen,
    uint32_t flags)
{
    OpenSSL_add_all_algorithms();
    EVP_CIPHER_CTX_init(ctx);
    if (EVP_CipherInit_ex(ctx, EVP_aes_cbc(keylen), NULL, key, IV,
            flags & PS_AES_ENCRYPT ? 1 : 0))
    {
        /* Turn off padding so all the encrypted/decrypted data will be
            returned in the single call to Update.  This will require that
            all the incoming data be an exact block multiple (which is true
            for TLS usage where all padding is accounted for) */
        EVP_CIPHER_CTX_set_padding(ctx, 0);
        return PS_SUCCESS;
    }
    EVP_CIPHER_CTX_cleanup(ctx);
    psAssert(0);
    return PS_FAIL;
}
Exemple #5
0
static int init_encryptor_decryptor(int (*init_fun)(EVP_CIPHER_CTX*, const EVP_CIPHER*, ENGINE*, const unsigned char*, const unsigned char*),
                                    lua_State *L, EVP_CIPHER_CTX *c, const EVP_CIPHER* cipher, const char* key, size_t key_len,
                                    const char* iv, size_t iv_len, int pad, int* size_to_return)
{
  unsigned char the_key[EVP_MAX_KEY_LENGTH] = {0};
  unsigned char the_iv[EVP_MAX_IV_LENGTH] = {0};

  EVP_CIPHER_CTX_init(c);
  TRY_CTX(init_fun(c, cipher, NULL, NULL, NULL))

  if (!pad)
    TRY_CTX(EVP_CIPHER_CTX_set_padding(c, 0))

  if (iv)
    memcpy(the_iv, iv, iv_len);

  memcpy(the_key, key, key_len);
  TRY_CTX(init_fun(c, NULL, NULL, the_key, the_iv))

  return 1;
}
Exemple #6
0
static int
aes_ctr_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
	     const unsigned char *iv, int enc) /* init key */
{
    aes_ctr_ctx *c = malloc(sizeof(*c));
    const EVP_CIPHER *aes_cipher;
    (void) enc;

    if (c == NULL)
	return 0;

    switch (ctx->key_len) {
        case 16:
            aes_cipher = EVP_aes_128_ecb();
            break;
        case 24:
            aes_cipher = EVP_aes_192_ecb();
            break;
        case 32:
            aes_cipher = EVP_aes_256_ecb();
            break;
        default:
            return 0;
    }
    c->aes_ctx = malloc(sizeof(EVP_CIPHER_CTX));
    if (c->aes_ctx == NULL)
	return 0;

    if (EVP_EncryptInit(c->aes_ctx, aes_cipher, key, NULL) != 1) {
        return 0;
    }

    EVP_CIPHER_CTX_set_padding(c->aes_ctx, 0);

    memcpy(c->ctr, iv, AES_BLOCK_SIZE);

    EVP_CIPHER_CTX_set_app_data(ctx, c);

    return 1;
}
Exemple #7
0
static int aead_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len,
                         size_t tag_len, enum evp_aead_direction_t dir,
                         const EVP_CIPHER *cipher, const EVP_MD *md,
                         char implicit_iv) {
  if (tag_len != EVP_AEAD_DEFAULT_TAG_LENGTH &&
      tag_len != EVP_MD_size(md)) {
    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_TAG_SIZE);
    return 0;
  }

  if (key_len != EVP_AEAD_key_length(ctx->aead)) {
    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
    return 0;
  }

  size_t mac_key_len = EVP_MD_size(md);
  size_t enc_key_len = EVP_CIPHER_key_length(cipher);
  assert(mac_key_len + enc_key_len +
         (implicit_iv ? EVP_CIPHER_iv_length(cipher) : 0) == key_len);

  AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)&ctx->state;
  EVP_CIPHER_CTX_init(&tls_ctx->cipher_ctx);
  HMAC_CTX_init(&tls_ctx->hmac_ctx);
  assert(mac_key_len <= EVP_MAX_MD_SIZE);
  OPENSSL_memcpy(tls_ctx->mac_key, key, mac_key_len);
  tls_ctx->mac_key_len = (uint8_t)mac_key_len;
  tls_ctx->implicit_iv = implicit_iv;

  if (!EVP_CipherInit_ex(&tls_ctx->cipher_ctx, cipher, NULL, &key[mac_key_len],
                         implicit_iv ? &key[mac_key_len + enc_key_len] : NULL,
                         dir == evp_aead_seal) ||
      !HMAC_Init_ex(&tls_ctx->hmac_ctx, key, mac_key_len, md, NULL)) {
    aead_tls_cleanup(ctx);
    return 0;
  }
  EVP_CIPHER_CTX_set_padding(&tls_ctx->cipher_ctx, 0);

  return 1;
}
Exemple #8
0
size_t ssl_des3_encrypt(const unsigned char *key, size_t key_len, const unsigned char *input, size_t input_len,
                        const unsigned char *iv, unsigned char **res)
{
    int output_length = 0;
    EVP_CIPHER_CTX ctx;

    *res = g_new0(unsigned char, 72);

    /* Don't set key or IV because we will modify the parameters */
    EVP_CIPHER_CTX_init(&ctx);
    EVP_CipherInit_ex(&ctx, EVP_des_ede3_cbc(), NULL, NULL, NULL, 1);
    EVP_CIPHER_CTX_set_key_length(&ctx, key_len);
    EVP_CIPHER_CTX_set_padding(&ctx, 0);
    /* We finished modifying parameters so now we can set key and IV */
    EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, 1);
    EVP_CipherUpdate(&ctx, *res, &output_length, input, input_len);
    EVP_CipherFinal_ex(&ctx, *res, &output_length);
    EVP_CIPHER_CTX_cleanup(&ctx);
    //EVP_cleanup();

    return output_length;
}
Exemple #9
0
/*
 * ctx - codec context
 * pgno - page number in database
 * size - size in bytes of input and output buffers
 * mode - 1 to encrypt, 0 to decrypt
 * in - pointer to input bytes
 * out - pouter to output bytes
 */
static int codec_cipher(codec_ctx *ctx, Pgno pgno, int mode, int size, void *in, void *out) {
  EVP_CIPHER_CTX ectx;
  void *iv;
  int tmp_csz, csz;

  /* when this is an encryption operation and rekey is not null, we will actually encrypt
  ** data with the new rekey data */
  void *key = ((mode == CIPHER_ENCRYPT && ctx->rekey != NULL) ? ctx->rekey : ctx->key);

  /* just copy raw data from in to out whenever 
  ** 1. key is NULL; or 
  ** 2. this is a decrypt operation and rekey_plaintext is true
  */ 
  if(key == NULL || (mode==CIPHER_DECRYPT && ctx->rekey_plaintext)) {
    memcpy(out, in, size);
    return SQLITE_OK;
  } 

  size = size - ctx->iv_sz; /* adjust size to useable size and memset reserve at end of page */
  iv = out + size;
  if(mode == CIPHER_ENCRYPT) {
    RAND_pseudo_bytes(iv, ctx->iv_sz);
  } else {
    memcpy(iv, in+size, ctx->iv_sz);
  } 
  
  EVP_CipherInit(&ectx, CIPHER, NULL, NULL, mode);
  EVP_CIPHER_CTX_set_padding(&ectx, 0);
  EVP_CipherInit(&ectx, NULL, key, iv, mode);
  EVP_CipherUpdate(&ectx, out, &tmp_csz, in, size);
  csz = tmp_csz;  
  out += tmp_csz;
  EVP_CipherFinal(&ectx, out, &tmp_csz);
  csz += tmp_csz;
  EVP_CIPHER_CTX_cleanup(&ectx);
  assert(size == csz);

  return SQLITE_OK;
}
Exemple #10
0
int s3fs::Crypto::decrypt_block(const unsigned char encrypted[], int inlen, unsigned char outbuf[])
{
    int outlen;
    int tmplen;

    EVP_CIPHER_CTX_init(&ctx);
    EVP_CIPHER_CTX_set_padding(&ctx, 1L);
    EVP_DecryptInit_ex(&ctx, EVP_aes_256_ctr(), NULL, key, iv);
    if(!EVP_DecryptUpdate(&ctx, outbuf, &outlen, encrypted, inlen))
    {
        cerr << "An error has occurred while decrypting the encrypted text." << endl;
        EVP_CIPHER_CTX_cleanup(&ctx);
    }
    if(!EVP_DecryptFinal_ex(&ctx, outbuf + outlen, &tmplen))
    {
        cerr << "An error has occurred while decrypting the encrypted text." << endl;
        EVP_CIPHER_CTX_cleanup(&ctx);
    }
    outlen += tmplen;
    EVP_CIPHER_CTX_cleanup(&ctx);

    return outlen;
}
Exemple #11
0
void cipher_context_init(cipher_ctx_t *evp, int method, int enc)
{
    if (method <= TABLE || method >= CIPHER_NUM) {
        LOGE("cipher_context_init(): Illegal method");
        return;
    }

    const char *ciphername = supported_ciphers[method];
    const cipher_kt_t *cipher = get_cipher_type(method);
#if defined(USE_CRYPTO_OPENSSL)
    if (cipher == NULL) {
        LOGE("Cipher %s not found in OpenSSL library", ciphername);
        FATAL("Cannot initialize cipher");
    }
    EVP_CIPHER_CTX_init(evp);
    if (!EVP_CipherInit_ex(evp, cipher, NULL, NULL, NULL, enc)) {
        LOGE("Cannot initialize cipher %s", ciphername);
        exit(EXIT_FAILURE);
    }
    if (!EVP_CIPHER_CTX_set_key_length(evp, enc_key_len)) {
        EVP_CIPHER_CTX_cleanup(evp);
        LOGE("Invalid key length: %d", enc_key_len);
        exit(EXIT_FAILURE);
    }
    if (method > RC4) {
        EVP_CIPHER_CTX_set_padding(evp, 1);
    }
#elif defined(USE_CRYPTO_POLARSSL)
    if (cipher == NULL) {
        LOGE("Cipher %s not found in PolarSSL library", ciphername);
        FATAL("Cannot initialize PolarSSL cipher");
    }
    if (cipher_init_ctx(evp, cipher) != 0) {
        FATAL("Cannot initialize PolarSSL cipher context");
    }
#endif
}
static bool aes_decrypt(void *dst, const void *src, size_t len,
			const struct enckey *enckey, const struct iv *iv)
{
	EVP_CIPHER_CTX evpctx;
	int outlen;

	/* Counter mode allows parallelism in future. */
	if (EVP_DecryptInit(&evpctx, EVP_aes_128_ctr(),
			    memcheck(enckey->k.u.u8, sizeof(enckey->k)),
			    memcheck(iv->iv, sizeof(iv->iv))) != 1)
		return false;

	/* No padding, we're a multiple of 128 bits. */
	if (EVP_CIPHER_CTX_set_padding(&evpctx, 0) != 1)
		return false;

	EVP_DecryptUpdate(&evpctx, dst, &outlen, memcheck(src, len), len);
	assert(outlen == len);
	/* Shouldn't happen (no padding) */
	if (EVP_DecryptFinal(&evpctx, dst, &outlen) != 1)
		return false;
	assert(outlen == 0);
	return true;
}
Exemple #13
0
	/*
		@note don't use padding = true
	*/
	void setup(Mode mode, const std::string& key, const std::string& iv, bool padding = false)
	{
		const int keyLen = static_cast<int>(key.size());
		const int expectedKeyLen = EVP_CIPHER_key_length(cipher_);
		if (keyLen != expectedKeyLen) {
			throw cybozu::Exception("crypto:Cipher:setup:keyLen") << keyLen << expectedKeyLen;
		}

		int ret = EVP_CipherInit_ex(&ctx_, cipher_, NULL, cybozu::cast<const uint8_t*>(key.c_str()), cybozu::cast<const uint8_t*>(iv.c_str()), mode == Encoding ? 1 : 0);
		if (ret != 1) {
			throw cybozu::Exception("crypto:Cipher:setup:EVP_CipherInit_ex") << ret;
		}
		ret = EVP_CIPHER_CTX_set_padding(&ctx_, padding ? 1 : 0);
		if (ret != 1) {
			throw cybozu::Exception("crypto:Cipher:setup:EVP_CIPHER_CTX_set_padding") << ret;
		}
/*
		const int ivLen = static_cast<int>(iv.size());
		const int expectedIvLen = EVP_CIPHER_CTX_iv_length(&ctx_);
		if (ivLen != expectedIvLen) {
			throw cybozu::Exception("crypto:Cipher:setup:ivLen") << ivLen << expectedIvLen;
		}
*/
	}
Exemple #14
0
/*
 * ctx - codec context
 * pgno - page number in database
 * size - size in bytes of input and output buffers
 * mode - 1 to encrypt, 0 to decrypt
 * in - pointer to input bytes
 * out - pouter to output bytes
 */
static int codec_cipher(cipher_ctx *ctx, Pgno pgno, int mode, int size, unsigned char *in, unsigned char *out) {
  EVP_CIPHER_CTX ectx;
  unsigned char *iv;
  int tmp_csz, csz;

  CODEC_TRACE(("codec_cipher:entered pgno=%d, mode=%d, size=%d\n", pgno, mode, size));

  /* just copy raw data from in to out when key size is 0
   * i.e. during a rekey of a plaintext database */ 
  if(ctx->key_sz == 0) {
    memcpy(out, in, size);
    return SQLITE_OK;
  } 

  // FIXME - only run if using an IV
  size = size - ctx->iv_sz; /* adjust size to useable size and memset reserve at end of page */
  iv = out + size;
  if(mode == CIPHER_ENCRYPT) {
    RAND_pseudo_bytes(iv, ctx->iv_sz);
  } else {
    memcpy(iv, in+size, ctx->iv_sz);
  } 
  
  EVP_CipherInit(&ectx, ctx->evp_cipher, NULL, NULL, mode);
  EVP_CIPHER_CTX_set_padding(&ectx, 0);
  EVP_CipherInit(&ectx, NULL, ctx->key, iv, mode);
  EVP_CipherUpdate(&ectx, out, &tmp_csz, in, size);
  csz = tmp_csz;  
  out += tmp_csz;
  EVP_CipherFinal(&ectx, out, &tmp_csz);
  csz += tmp_csz;
  EVP_CIPHER_CTX_cleanup(&ectx);
  assert(size == csz);

  return SQLITE_OK;
}
Exemple #15
0
int MAIN(int argc, char **argv)
	{
	static const char magic[]="Salted__";
	char mbuf[sizeof magic-1];
	char *strbuf=NULL;
	unsigned char *buff=NULL,*bufsize=NULL;
	int bsize=BSIZE,verbose=0;
	int ret=1,inl;
	int nopad = 0;
	unsigned char key[EVP_MAX_KEY_LENGTH],iv[EVP_MAX_IV_LENGTH];
	unsigned char salt[PKCS5_SALT_LEN];
	char *str=NULL, *passarg = NULL, *pass = NULL;
	char *hkey=NULL,*hiv=NULL,*hsalt = NULL;
	char *md=NULL;
	int enc=1,printkey=0,i,base64=0;
#ifdef ZLIB
	int do_zlib=0;
	BIO *bzl = NULL;
#endif
	int debug=0,olb64=0,nosalt=0;
	const EVP_CIPHER *cipher=NULL,*c;
	EVP_CIPHER_CTX *ctx = NULL;
	char *inf=NULL,*outf=NULL;
	BIO *in=NULL,*out=NULL,*b64=NULL,*benc=NULL,*rbio=NULL,*wbio=NULL;
#define PROG_NAME_SIZE  39
	char pname[PROG_NAME_SIZE+1];
#ifndef OPENSSL_NO_ENGINE
	char *engine = NULL;
#endif
	const EVP_MD *dgst=NULL;
	int non_fips_allow = 0;

	apps_startup();

	if (bio_err == NULL)
		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);

	if (!load_config(bio_err, NULL))
		goto end;

	/* first check the program name */
	program_name(argv[0],pname,sizeof pname);
	if (strcmp(pname,"base64") == 0)
		base64=1;
#ifdef ZLIB
	if (strcmp(pname,"zlib") == 0)
		do_zlib=1;
#endif

	cipher=EVP_get_cipherbyname(pname);
#ifdef ZLIB
	if (!do_zlib && !base64 && (cipher == NULL)
				&& (strcmp(pname,"enc") != 0))
#else
	if (!base64 && (cipher == NULL) && (strcmp(pname,"enc") != 0))
#endif
		{
		BIO_printf(bio_err,"%s is an unknown cipher\n",pname);
		goto bad;
		}

	argc--;
	argv++;
	while (argc >= 1)
		{
		if	(strcmp(*argv,"-e") == 0)
			enc=1;
		else if (strcmp(*argv,"-in") == 0)
			{
			if (--argc < 1) goto bad;
			inf= *(++argv);
			}
		else if (strcmp(*argv,"-out") == 0)
			{
			if (--argc < 1) goto bad;
			outf= *(++argv);
			}
		else if (strcmp(*argv,"-pass") == 0)
			{
			if (--argc < 1) goto bad;
			passarg= *(++argv);
			}
#ifndef OPENSSL_NO_ENGINE
		else if (strcmp(*argv,"-engine") == 0)
			{
			if (--argc < 1) goto bad;
			engine= *(++argv);
			}
#endif
		else if	(strcmp(*argv,"-d") == 0)
			enc=0;
		else if	(strcmp(*argv,"-p") == 0)
			printkey=1;
		else if	(strcmp(*argv,"-v") == 0)
			verbose=1;
		else if	(strcmp(*argv,"-nopad") == 0)
			nopad=1;
		else if	(strcmp(*argv,"-salt") == 0)
			nosalt=0;
		else if	(strcmp(*argv,"-nosalt") == 0)
			nosalt=1;
		else if	(strcmp(*argv,"-debug") == 0)
			debug=1;
		else if	(strcmp(*argv,"-P") == 0)
			printkey=2;
		else if	(strcmp(*argv,"-A") == 0)
			olb64=1;
		else if	(strcmp(*argv,"-a") == 0)
			base64=1;
		else if	(strcmp(*argv,"-base64") == 0)
			base64=1;
#ifdef ZLIB
		else if	(strcmp(*argv,"-z") == 0)
			do_zlib=1;
#endif
		else if (strcmp(*argv,"-bufsize") == 0)
			{
			if (--argc < 1) goto bad;
			bufsize=(unsigned char *)*(++argv);
			}
		else if (strcmp(*argv,"-k") == 0)
			{
			if (--argc < 1) goto bad;
			str= *(++argv);
			}
		else if (strcmp(*argv,"-kfile") == 0)
			{
			static char buf[128];
			FILE *infile;
			char *file;

			if (--argc < 1) goto bad;
			file= *(++argv);
			infile=fopen(file,"r");
			if (infile == NULL)
				{
				BIO_printf(bio_err,"unable to read key from '%s'\n",
					file);
				goto bad;
				}
			buf[0]='\0';
			if (!fgets(buf,sizeof buf,infile))
				{
				BIO_printf(bio_err,"unable to read key from '%s'\n",
					file);
				goto bad;
				}
			fclose(infile);
			i=strlen(buf);
			if ((i > 0) &&
				((buf[i-1] == '\n') || (buf[i-1] == '\r')))
				buf[--i]='\0';
			if ((i > 0) &&
				((buf[i-1] == '\n') || (buf[i-1] == '\r')))
				buf[--i]='\0';
			if (i < 1)
				{
				BIO_printf(bio_err,"zero length password\n");
				goto bad;
				}
			str=buf;
			}
		else if (strcmp(*argv,"-K") == 0)
			{
			if (--argc < 1) goto bad;
			hkey= *(++argv);
			}
		else if (strcmp(*argv,"-S") == 0)
			{
			if (--argc < 1) goto bad;
			hsalt= *(++argv);
			}
		else if (strcmp(*argv,"-iv") == 0)
			{
			if (--argc < 1) goto bad;
			hiv= *(++argv);
			}
		else if (strcmp(*argv,"-md") == 0)
			{
			if (--argc < 1) goto bad;
			md= *(++argv);
			}
		else if (strcmp(*argv,"-non-fips-allow") == 0)
			non_fips_allow = 1;
		else if	((argv[0][0] == '-') &&
			((c=EVP_get_cipherbyname(&(argv[0][1]))) != NULL))
			{
			cipher=c;
			}
		else if (strcmp(*argv,"-none") == 0)
			cipher=NULL;
		else
			{
			BIO_printf(bio_err,"unknown option '%s'\n",*argv);
bad:
			BIO_printf(bio_err,"options are\n");
			BIO_printf(bio_err,"%-14s input file\n","-in <file>");
			BIO_printf(bio_err,"%-14s output file\n","-out <file>");
			BIO_printf(bio_err,"%-14s pass phrase source\n","-pass <arg>");
			BIO_printf(bio_err,"%-14s encrypt\n","-e");
			BIO_printf(bio_err,"%-14s decrypt\n","-d");
			BIO_printf(bio_err,"%-14s base64 encode/decode, depending on encryption flag\n","-a/-base64");
			BIO_printf(bio_err,"%-14s passphrase is the next argument\n","-k");
			BIO_printf(bio_err,"%-14s passphrase is the first line of the file argument\n","-kfile");
			BIO_printf(bio_err,"%-14s the next argument is the md to use to create a key\n","-md");
			BIO_printf(bio_err,"%-14s   from a passphrase.  One of md2, md5, sha or sha1\n","");
			BIO_printf(bio_err,"%-14s salt in hex is the next argument\n","-S");
			BIO_printf(bio_err,"%-14s key/iv in hex is the next argument\n","-K/-iv");
			BIO_printf(bio_err,"%-14s print the iv/key (then exit if -P)\n","-[pP]");
			BIO_printf(bio_err,"%-14s buffer size\n","-bufsize <n>");
			BIO_printf(bio_err,"%-14s disable standard block padding\n","-nopad");
#ifndef OPENSSL_NO_ENGINE
			BIO_printf(bio_err,"%-14s use engine e, possibly a hardware device.\n","-engine e");
#endif

			BIO_printf(bio_err,"Cipher Types\n");
			OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH,
					       show_ciphers,
					       bio_err);
			BIO_printf(bio_err,"\n");

			goto end;
			}
		argc--;
		argv++;
		}

#ifndef OPENSSL_NO_ENGINE
        setup_engine(bio_err, engine, 0);
#endif

	if (md && (dgst=EVP_get_digestbyname(md)) == NULL)
		{
		BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
		goto end;
		}

	if (dgst == NULL)
		{
		dgst = EVP_md5();
		}

	if (bufsize != NULL)
		{
		unsigned long n;

		for (n=0; *bufsize; bufsize++)
			{
			i= *bufsize;
			if ((i <= '9') && (i >= '0'))
				n=n*10+i-'0';
			else if (i == 'k')
				{
				n*=1024;
				bufsize++;
				break;
				}
			}
		if (*bufsize != '\0')
			{
			BIO_printf(bio_err,"invalid 'bufsize' specified.\n");
			goto end;
			}

		/* It must be large enough for a base64 encoded line */
		if (base64 && n < 80) n=80;

		bsize=(int)n;
		if (verbose) BIO_printf(bio_err,"bufsize=%d\n",bsize);
		}

	strbuf=OPENSSL_malloc(SIZE);
	buff=(unsigned char *)OPENSSL_malloc(EVP_ENCODE_LENGTH(bsize));
	if ((buff == NULL) || (strbuf == NULL))
		{
		BIO_printf(bio_err,"OPENSSL_malloc failure %ld\n",(long)EVP_ENCODE_LENGTH(bsize));
		goto end;
		}

	in=BIO_new(BIO_s_file());
	out=BIO_new(BIO_s_file());
	if ((in == NULL) || (out == NULL))
		{
		ERR_print_errors(bio_err);
		goto end;
		}
	if (debug)
		{
		BIO_set_callback(in,BIO_debug_callback);
		BIO_set_callback(out,BIO_debug_callback);
		BIO_set_callback_arg(in,(char *)bio_err);
		BIO_set_callback_arg(out,(char *)bio_err);
		}

	if (inf == NULL)
	        {
#ifndef OPENSSL_NO_SETVBUF_IONBF
		if (bufsize != NULL)
			setvbuf(stdin, (char *)NULL, _IONBF, 0);
#endif /* ndef OPENSSL_NO_SETVBUF_IONBF */
		BIO_set_fp(in,stdin,BIO_NOCLOSE);
	        }
	else
		{
		if (BIO_read_filename(in,inf) <= 0)
			{
			perror(inf);
			goto end;
			}
		}

	if(!str && passarg) {
		if(!app_passwd(bio_err, passarg, NULL, &pass, NULL)) {
			BIO_printf(bio_err, "Error getting password\n");
			goto end;
		}
		str = pass;
	}

	if ((str == NULL) && (cipher != NULL) && (hkey == NULL))
		{
		for (;;)
			{
			char buf[200];

			BIO_snprintf(buf,sizeof buf,"enter %s %s password:"******"encryption":"decryption");
			strbuf[0]='\0';
			i=EVP_read_pw_string((char *)strbuf,SIZE,buf,enc);
			if (i == 0)
				{
				if (strbuf[0] == '\0')
					{
					ret=1;
					goto end;
					}
				str=strbuf;
				break;
				}
			if (i < 0)
				{
				BIO_printf(bio_err,"bad password read\n");
				goto end;
				}
			}
		}


	if (outf == NULL)
		{
		BIO_set_fp(out,stdout,BIO_NOCLOSE);
#ifndef OPENSSL_NO_SETVBUF_IONBF
		if (bufsize != NULL)
			setvbuf(stdout, (char *)NULL, _IONBF, 0);
#endif /* ndef OPENSSL_NO_SETVBUF_IONBF */
#ifdef OPENSSL_SYS_VMS
		{
		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
		out = BIO_push(tmpbio, out);
		}
#endif
		}
	else
		{
		if (BIO_write_filename(out,outf) <= 0)
			{
			perror(outf);
			goto end;
			}
		}

	rbio=in;
	wbio=out;

#ifdef ZLIB

	if (do_zlib)
		{
		if ((bzl=BIO_new(BIO_f_zlib())) == NULL)
			goto end;
		if (enc)
			wbio=BIO_push(bzl,wbio);
		else
			rbio=BIO_push(bzl,rbio);
		}
#endif

	if (base64)
		{
		if ((b64=BIO_new(BIO_f_base64())) == NULL)
			goto end;
		if (debug)
			{
			BIO_set_callback(b64,BIO_debug_callback);
			BIO_set_callback_arg(b64,(char *)bio_err);
			}
		if (olb64)
			BIO_set_flags(b64,BIO_FLAGS_BASE64_NO_NL);
		if (enc)
			wbio=BIO_push(b64,wbio);
		else
			rbio=BIO_push(b64,rbio);
		}

	if (cipher != NULL)
		{
		/* Note that str is NULL if a key was passed on the command
		 * line, so we get no salt in that case. Is this a bug?
		 */
		if (str != NULL)
			{
			/* Salt handling: if encrypting generate a salt and
			 * write to output BIO. If decrypting read salt from
			 * input BIO.
			 */
			unsigned char *sptr;
			if(nosalt) sptr = NULL;
			else {
				if(enc) {
					if(hsalt) {
						if(!set_hex(hsalt,salt,sizeof salt)) {
							BIO_printf(bio_err,
								"invalid hex salt value\n");
							goto end;
						}
					} else if (RAND_pseudo_bytes(salt, sizeof salt) < 0)
						goto end;
					/* If -P option then don't bother writing */
					if((printkey != 2)
					   && (BIO_write(wbio,magic,
							 sizeof magic-1) != sizeof magic-1
					       || BIO_write(wbio,
							    (char *)salt,
							    sizeof salt) != sizeof salt)) {
						BIO_printf(bio_err,"error writing output file\n");
						goto end;
					}
				} else if(BIO_read(rbio,mbuf,sizeof mbuf) != sizeof mbuf
					  || BIO_read(rbio,
						      (unsigned char *)salt,
				    sizeof salt) != sizeof salt) {
					BIO_printf(bio_err,"error reading input file\n");
					goto end;
				} else if(memcmp(mbuf,magic,sizeof magic-1)) {
				    BIO_printf(bio_err,"bad magic number\n");
				    goto end;
				}

				sptr = salt;
			}

			EVP_BytesToKey(cipher,dgst,sptr,
				(unsigned char *)str,
				strlen(str),1,key,iv);
			/* zero the complete buffer or the string
			 * passed from the command line
			 * bug picked up by
			 * Larry J. Hughes Jr. <*****@*****.**> */
			if (str == strbuf)
				OPENSSL_cleanse(str,SIZE);
			else
				OPENSSL_cleanse(str,strlen(str));
			}
		if ((hiv != NULL) && !set_hex(hiv,iv,sizeof iv))
			{
			BIO_printf(bio_err,"invalid hex iv value\n");
			goto end;
			}
		if ((hiv == NULL) && (str == NULL)
		    && EVP_CIPHER_iv_length(cipher) != 0)
			{
			/* No IV was explicitly set and no IV was generated
			 * during EVP_BytesToKey. Hence the IV is undefined,
			 * making correct decryption impossible. */
			BIO_printf(bio_err, "iv undefined\n");
			goto end;
			}
		if ((hkey != NULL) && !set_hex(hkey,key,sizeof key))
			{
			BIO_printf(bio_err,"invalid hex key value\n");
			goto end;
			}

		if ((benc=BIO_new(BIO_f_cipher())) == NULL)
			goto end;

		/* Since we may be changing parameters work on the encryption
		 * context rather than calling BIO_set_cipher().
		 */

		BIO_get_cipher_ctx(benc, &ctx);

		if (non_fips_allow)
			EVP_CIPHER_CTX_set_flags(ctx,
				EVP_CIPH_FLAG_NON_FIPS_ALLOW);

		if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc))
			{
			BIO_printf(bio_err, "Error setting cipher %s\n",
				EVP_CIPHER_name(cipher));
			ERR_print_errors(bio_err);
			goto end;
			}

		if (nopad)
			EVP_CIPHER_CTX_set_padding(ctx, 0);

		if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc))
			{
			BIO_printf(bio_err, "Error setting cipher %s\n",
				EVP_CIPHER_name(cipher));
			ERR_print_errors(bio_err);
			goto end;
			}

		if (debug)
			{
			BIO_set_callback(benc,BIO_debug_callback);
			BIO_set_callback_arg(benc,(char *)bio_err);
			}

		if (printkey)
			{
			if (!nosalt)
				{
				printf("salt=");
				for (i=0; i<(int)sizeof(salt); i++)
					printf("%02X",salt[i]);
				printf("\n");
				}
			if (cipher->key_len > 0)
				{
				printf("key=");
				for (i=0; i<cipher->key_len; i++)
					printf("%02X",key[i]);
				printf("\n");
				}
			if (cipher->iv_len > 0)
				{
				printf("iv =");
				for (i=0; i<cipher->iv_len; i++)
					printf("%02X",iv[i]);
				printf("\n");
				}
			if (printkey == 2)
				{
				ret=0;
				goto end;
				}
			}
		}

	/* Only encrypt/decrypt as we write the file */
	if (benc != NULL)
		wbio=BIO_push(benc,wbio);

	for (;;)
		{
		inl=BIO_read(rbio,(char *)buff,bsize);
		if (inl <= 0) break;
		if (BIO_write(wbio,(char *)buff,inl) != inl)
			{
			BIO_printf(bio_err,"error writing output file\n");
			goto end;
			}
		}
	if (!BIO_flush(wbio))
		{
		BIO_printf(bio_err,"bad decrypt\n");
		goto end;
		}

	ret=0;
	if (verbose)
		{
		BIO_printf(bio_err,"bytes read   :%8ld\n",BIO_number_read(in));
		BIO_printf(bio_err,"bytes written:%8ld\n",BIO_number_written(out));
		}
end:
	ERR_print_errors(bio_err);
	if (strbuf != NULL) OPENSSL_free(strbuf);
	if (buff != NULL) OPENSSL_free(buff);
	if (in != NULL) BIO_free(in);
	if (out != NULL) BIO_free_all(out);
	if (benc != NULL) BIO_free(benc);
	if (b64 != NULL) BIO_free(b64);
#ifdef ZLIB
	if (bzl != NULL) BIO_free(bzl);
#endif
	if(pass) OPENSSL_free(pass);
	apps_shutdown();
	OPENSSL_EXIT(ret);
	}
void AESCryptoKey::TransformBlock(bool           encrypt,
                                  const uint8_t *pbIn,
                                  uint32_t       cbIn,
                                  uint8_t       *pbOut,
                                  uint32_t     & cbOut,
                                  const uint8_t *pbIv,
                                  uint32_t       cbIv)
{
  if (pbIn == nullptr) {
    throw exceptions::RMSCryptoNullPointerException("Null pointer pbIn exception");
  }

  if (pbOut == nullptr) {
    throw exceptions::RMSCryptoNullPointerException("Null pointer pbOut exception");
  }

  if (((cbIv == 0) && (pbIv != nullptr)) || ((cbIv != 0) && (pbIv == nullptr))) {
    pbIv = nullptr;
    cbIv = 0;
  }

  int totalOut = static_cast<int>(cbOut);
  EVP_CIPHER_CTX ctx;
  EVP_CIPHER_CTX_init(&ctx);
  const EVP_CIPHER *cipher = nullptr;

  switch (m_algorithm) {
  case api::CRYPTO_ALGORITHM_AES_ECB:
    switch(m_key.size()) {
    case 16:
       cipher = EVP_aes_128_ecb();
       break;
    case 24:
       cipher = EVP_aes_192_ecb();
       break;
    case 32:
       cipher = EVP_aes_256_ecb();
       break;
    default:
        throw exceptions::RMSCryptoInvalidArgumentException("Invalid key length");
    }
    break;

  case api::CRYPTO_ALGORITHM_AES_CBC:
  case api::CRYPTO_ALGORITHM_AES_CBC_PKCS7:
      switch(m_key.size()) {
      case 16:
         cipher = EVP_aes_128_cbc();
         break;
      case 24:
         cipher = EVP_aes_192_cbc();
         break;
      case 32:
         cipher = EVP_aes_256_cbc();
         break;
      default:
          throw exceptions::RMSCryptoInvalidArgumentException("Invalid key length");
      }
      break;
    break;

  default:
    throw exceptions::RMSCryptoInvalidArgumentException("Unsupported algorithm");
  }

  // check lengths
  if ((pbIv != nullptr) &&
      (EVP_CIPHER_iv_length(cipher) != static_cast<int>(cbIv))) {
    throw exceptions::RMSCryptoInvalidArgumentException(
            "Invalid initial vector length");
  }

  if (EVP_CIPHER_key_length(cipher) != static_cast<int>(m_key.size())) {
    throw exceptions::RMSCryptoInvalidArgumentException("Invalid key length");
  }

  EVP_CipherInit_ex(&ctx, cipher, NULL, m_key.data(), pbIv, encrypt ? 1 : 0);

  if (m_algorithm == api::CRYPTO_ALGORITHM_AES_CBC_PKCS7) {
    EVP_CIPHER_CTX_set_padding(&ctx, 1);
  } else {
    EVP_CIPHER_CTX_set_padding(&ctx, 0);
  }

  if (!EVP_CipherUpdate(&ctx, pbOut, &totalOut, pbIn, static_cast<int>(cbIn))) {
    throw exceptions::RMSCryptoIOException(
            exceptions::RMSCryptoException::UnknownError,
            "Failed to transform data");
  }

  pbOut += totalOut;

  // add padding if necessary
  if (m_algorithm == api::CRYPTO_ALGORITHM_AES_CBC_PKCS7) {
    int remain = cbOut - totalOut;

    if (remain < EVP_CIPHER_block_size(cipher)) {
      throw exceptions::RMSCryptoInsufficientBufferException(
              "No enough buffer size");
    }

    if (!EVP_CipherFinal_ex(&ctx, pbOut, &remain)) {
      throw exceptions::RMSCryptoIOException(
              exceptions::RMSCryptoException::UnknownError,
              "Failed to transform final block");
    }
    totalOut += remain;
  }

  EVP_CIPHER_CTX_cleanup(&ctx);

  // remember total size
  cbOut = static_cast<uint32_t>(totalOut);
}
void mexserver() //gestisco i job
{
    
    long ret,quanti=0;
    char key[32] ;
    unsigned char * msg;
    long numblocchi;
    unsigned char **p;
    unsigned char zero[16];
    int index;
    EVP_CIPHER_CTX* ctx;
    unsigned char ** ciphertext;
    
    unsigned char* L;
    printf("mexdalserver\n");
    //key=malloc(32);
    ret = recv(sk, (void *)key, 32, 0);//key
    if(ret==-1) {
        printf("mexserver errore: errore in ricezione idjob dal server!\n");
        exit(1);
    }
    
    printf("key : \n");
    
    printf("key : %s\n",key);
    
    printf("\n");
    if(ret==0) { //server si e' disconnesso
        printf("Il server ha chiuso la connessione!!/n");
        exit(3);
    }
    ret = recv(sk, (void *)&index, sizeof(int), 0); //mi serve per il calcolo di p
    if(ret==-1) {
        printf("mexserver errore: errore in ricezione lunghezza dal server3!\n");
        exit(1);
    }
    printf("ricevuto index: %d\n",index);
    ret = recv(sk, (void *)&quanti, sizeof(long), 0); //ricevo lunghezza stringa
    if(ret==-1) {
        printf("mexserver errore: errore in ricezione lunghezza dal server1!\n");
        exit(1);
    }
    printf("ricevuto quanti: %ld\n",quanti);
    msg=malloc(quanti);
    ret = recv(sk, (void *)msg, quanti, 0); //ricevo file da cifrare
    if(ret==-1) {
        printf("mexserver errore: errore in ricezione lunghezza dal server2!\n");
        exit(1);
    }
    printf("ricevuto msg\n");
    printf("\n MSG %s\n",msg);
    numblocchi=quanti/16;
    printf("stai elaborando %ld\n",numblocchi);
    printf("blocchi \n");
    //**************************
    exit(1);//****************crush************************
    //****************************
    p=malloc(sizeof(unsigned char*)* numblocchi );
#pragma omp parallel for
    for (int z=1; z<numblocchi; z++) {
        p[z]=malloc(16);
        //l'ultimo carattere mi dice se completato..
    }
    ciphertext=malloc(sizeof(unsigned char*)*numblocchi);
    ctx = (EVP_CIPHER_CTX*)malloc(sizeof(EVP_CIPHER_CTX));
    EVP_CIPHER_CTX_init(ctx);
    int outlen=0;
    L=malloc(16);
    /* Context setup for encryption */
    EVP_EncryptInit(ctx, EVP_aes_256_ecb(), key, NULL);
    EVP_CIPHER_CTX_set_padding(ctx, 0);
    EVP_EncryptUpdate(ctx, L, &outlen, (unsigned char*)zero, 16);
    if (!EVP_EncryptFinal(ctx, L+outlen, &outlen)) { // se == 0 -> errore
     	printf("Errore in EVP_EncryptFinal\n");
    	exit(-1);
	}
	EVP_CIPHER_CTX_cleanup(ctx);
	EVP_CIPHER_CTX_free(ctx);
    for (int i=0; i<16; i++)
        printf(" %02X",  (unsigned char)L[i]);
    printf("\n");
    memset(zero, 0, 16);
    zero[15]=1;
    for (int i; i<16; i++)
        L[i]|=zero[i];
    
    //L trovata adessi IL;
    calcolaLI(numblocchi, L, p,index);
    char carry=0;
    char ris;
#pragma omp parallel for private(ctx, outlen)
    for (int i=0;i<numblocchi ; i++) { //fa il cipher
        for(int z=0;z <16;z++){
            // msg[i*16+z]+=p[i][z];{
            ris = msg[i*16+z]&127 || p[i][z]&127;
            msg[i*16+z]+= p[i][z] + carry;
            if (ris==1 && (msg[i*16+z]&127)==0)
                carry=1;
            else
                carry=0;
        }
        ciphertext[i]=malloc(16);
        carry=0;
        ctx = (EVP_CIPHER_CTX*)malloc(sizeof(EVP_CIPHER_CTX));
        EVP_CIPHER_CTX_init(ctx);
        outlen = 0;
        EVP_EncryptInit(ctx, EVP_aes_256_ecb(), key, NULL);
        EVP_CIPHER_CTX_set_padding(ctx, 0);
        EVP_EncryptUpdate(ctx, ciphertext[i], &outlen, &msg[i*16], 16);
        if (!EVP_EncryptFinal(ctx, ciphertext[i]+outlen, &outlen)) { // se == 0 -> errore
        	printf("Errore in EVP_EncryptFinal\n");
           	exit(-1);
		}
        EVP_CIPHER_CTX_cleanup(ctx);
		EVP_CIPHER_CTX_free(ctx);
        
    }
    
    
#pragma omp parallel for
    for (int i=0;i<numblocchi ; i++) { //xor tra i cipher calcolati
        for(int z=0;z <16;z++)
            zero[z]^=ciphertext[i][z];
        
    }
    char x='a';
    ret=send(sk,(void*)&x,sizeof(char),0);//mando risultato
    if (ret ==-1)
    {
        printf ("errore nel mandare comando e' il mex d'uscita");
        exit(1);
    }
    printf("zero : \n");
    for (int i=0; i<16; i++)
        printf(" %02X",  (unsigned char)zero[i]);
    printf("\n");
    ret=send(sk,(void*)zero,16,0);//mando risultato
    if (ret ==-1)
    {
        printf ("errore nel mandare comando e' il mex d'uscita");
        exit(1);
    }
    printf("finito un job\n");
}
Exemple #18
0
int
enc_main(int argc, char **argv)
{
	static const char magic[] = "Salted__";
	char mbuf[sizeof magic - 1];
	char *strbuf = NULL, *pass = NULL;
	unsigned char *buff = NULL;
	int bsize = BSIZE;
	int ret = 1, inl;
	unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
	unsigned char salt[PKCS5_SALT_LEN];
#ifdef ZLIB
	BIO *bzl = NULL;
#endif
	EVP_CIPHER_CTX *ctx = NULL;
	const EVP_MD *dgst = NULL;
	BIO *in = NULL, *out = NULL, *b64 = NULL, *benc = NULL;
	BIO *rbio = NULL, *wbio = NULL;
#define PROG_NAME_SIZE  39
	char pname[PROG_NAME_SIZE + 1];
	int i;

	if (single_execution) {
		if (pledge("stdio rpath wpath cpath tty", NULL) == -1) {
			perror("pledge");
			exit(1);
		}
	}

	memset(&enc_config, 0, sizeof(enc_config));
	enc_config.enc = 1;

	/* first check the program name */
	program_name(argv[0], pname, sizeof(pname));

	if (strcmp(pname, "base64") == 0)
		enc_config.base64 = 1;

#ifdef ZLIB
	if (strcmp(pname, "zlib") == 0)
		enc_config.do_zlib = 1;
#endif

	enc_config.cipher = EVP_get_cipherbyname(pname);

#ifdef ZLIB
	if (!enc_config.do_zlib && !enc_config.base64 &&
	    enc_config.cipher == NULL && strcmp(pname, "enc") != 0)
#else
	if (!enc_config.base64 && enc_config.cipher == NULL &&
	    strcmp(pname, "enc") != 0)
#endif
	{
		BIO_printf(bio_err, "%s is an unknown cipher\n", pname);
		goto end;
	}

	if (options_parse(argc, argv, enc_options, NULL, NULL) != 0) {
		enc_usage();
		goto end;
	}

	if (enc_config.keyfile != NULL) {
		static char buf[128];
		FILE *infile;

		infile = fopen(enc_config.keyfile, "r");
		if (infile == NULL) {
			BIO_printf(bio_err, "unable to read key from '%s'\n",
			    enc_config.keyfile);
			goto end;
		}
		buf[0] = '\0';
		if (!fgets(buf, sizeof buf, infile)) {
			BIO_printf(bio_err, "unable to read key from '%s'\n",
			    enc_config.keyfile);
			fclose(infile);
			goto end;
		}
		fclose(infile);
		i = strlen(buf);
		if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r')))
			buf[--i] = '\0';
		if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r')))
			buf[--i] = '\0';
		if (i < 1) {
			BIO_printf(bio_err, "zero length password\n");
			goto end;
		}
		enc_config.keystr = buf;
	}

	if (enc_config.md != NULL &&
	    (dgst = EVP_get_digestbyname(enc_config.md)) == NULL) {
		BIO_printf(bio_err,
		    "%s is an unsupported message digest type\n",
		    enc_config.md);
		goto end;
	}
	if (dgst == NULL) {
		dgst = EVP_md5();	/* XXX */
	}

	if (enc_config.bufsize != NULL) {
		char *p = enc_config.bufsize;
		unsigned long n;

		/* XXX - provide an OPTION_ARG_DISKUNIT. */
		for (n = 0; *p != '\0'; p++) {
			i = *p;
			if ((i <= '9') && (i >= '0'))
				n = n * 10 + i - '0';
			else if (i == 'k') {
				n *= 1024;
				p++;
				break;
			}
		}
		if (*p != '\0') {
			BIO_printf(bio_err, "invalid 'bufsize' specified.\n");
			goto end;
		}
		/* It must be large enough for a base64 encoded line. */
		if (enc_config.base64 && n < 80)
			n = 80;

		bsize = (int)n;
		if (enc_config.verbose)
			BIO_printf(bio_err, "bufsize=%d\n", bsize);
	}
	strbuf = malloc(SIZE);
	buff = malloc(EVP_ENCODE_LENGTH(bsize));
	if ((buff == NULL) || (strbuf == NULL)) {
		BIO_printf(bio_err, "malloc failure %ld\n", (long) EVP_ENCODE_LENGTH(bsize));
		goto end;
	}
	in = BIO_new(BIO_s_file());
	out = BIO_new(BIO_s_file());
	if ((in == NULL) || (out == NULL)) {
		ERR_print_errors(bio_err);
		goto end;
	}
	if (enc_config.debug) {
		BIO_set_callback(in, BIO_debug_callback);
		BIO_set_callback(out, BIO_debug_callback);
		BIO_set_callback_arg(in, (char *) bio_err);
		BIO_set_callback_arg(out, (char *) bio_err);
	}
	if (enc_config.inf == NULL) {
		if (enc_config.bufsize != NULL)
			setvbuf(stdin, (char *) NULL, _IONBF, 0);
		BIO_set_fp(in, stdin, BIO_NOCLOSE);
	} else {
		if (BIO_read_filename(in, enc_config.inf) <= 0) {
			perror(enc_config.inf);
			goto end;
		}
	}

	if (!enc_config.keystr && enc_config.passarg) {
		if (!app_passwd(bio_err, enc_config.passarg, NULL,
		    &pass, NULL)) {
			BIO_printf(bio_err, "Error getting password\n");
			goto end;
		}
		enc_config.keystr = pass;
	}
	if (enc_config.keystr == NULL && enc_config.cipher != NULL &&
	    enc_config.hkey == NULL) {
		for (;;) {
			char buf[200];
			int retval;

			retval = snprintf(buf, sizeof buf,
			    "enter %s %s password:"******"encryption" : "decryption");
			if ((size_t)retval >= sizeof buf) {
				BIO_printf(bio_err,
				    "Password prompt too long\n");
				goto end;
			}
			strbuf[0] = '\0';
			i = EVP_read_pw_string((char *)strbuf, SIZE, buf,
			    enc_config.enc);
			if (i == 0) {
				if (strbuf[0] == '\0') {
					ret = 1;
					goto end;
				}
				enc_config.keystr = strbuf;
				break;
			}
			if (i < 0) {
				BIO_printf(bio_err, "bad password read\n");
				goto end;
			}
		}
	}
	if (enc_config.outf == NULL) {
		BIO_set_fp(out, stdout, BIO_NOCLOSE);
		if (enc_config.bufsize != NULL)
			setvbuf(stdout, (char *)NULL, _IONBF, 0);
	} else {
		if (BIO_write_filename(out, enc_config.outf) <= 0) {
			perror(enc_config.outf);
			goto end;
		}
	}

	rbio = in;
	wbio = out;

#ifdef ZLIB
	if (do_zlib) {
		if ((bzl = BIO_new(BIO_f_zlib())) == NULL)
			goto end;
		if (enc)
			wbio = BIO_push(bzl, wbio);
		else
			rbio = BIO_push(bzl, rbio);
	}
#endif

	if (enc_config.base64) {
		if ((b64 = BIO_new(BIO_f_base64())) == NULL)
			goto end;
		if (enc_config.debug) {
			BIO_set_callback(b64, BIO_debug_callback);
			BIO_set_callback_arg(b64, (char *) bio_err);
		}
		if (enc_config.olb64)
			BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
		if (enc_config.enc)
			wbio = BIO_push(b64, wbio);
		else
			rbio = BIO_push(b64, rbio);
	}
	if (enc_config.cipher != NULL) {
		/*
		 * Note that keystr is NULL if a key was passed on the command
		 * line, so we get no salt in that case. Is this a bug?
		 */
		if (enc_config.keystr != NULL) {
			/*
			 * Salt handling: if encrypting generate a salt and
			 * write to output BIO. If decrypting read salt from
			 * input BIO.
			 */
			unsigned char *sptr;
			if (enc_config.nosalt)
				sptr = NULL;
			else {
				if (enc_config.enc) {
					if (enc_config.hsalt) {
						if (!set_hex(enc_config.hsalt, salt, sizeof salt)) {
							BIO_printf(bio_err,
							    "invalid hex salt value\n");
							goto end;
						}
					} else
						arc4random_buf(salt,
						    sizeof(salt));
					/*
					 * If -P option then don't bother
					 * writing
					 */
					if ((enc_config.printkey != 2)
					    && (BIO_write(wbio, magic,
						    sizeof magic - 1) != sizeof magic - 1
						|| BIO_write(wbio,
						    (char *) salt,
						    sizeof salt) != sizeof salt)) {
						BIO_printf(bio_err, "error writing output file\n");
						goto end;
					}
				} else if (BIO_read(rbio, mbuf, sizeof mbuf) != sizeof mbuf
					    || BIO_read(rbio,
						(unsigned char *) salt,
					sizeof salt) != sizeof salt) {
					BIO_printf(bio_err, "error reading input file\n");
					goto end;
				} else if (memcmp(mbuf, magic, sizeof magic - 1)) {
					BIO_printf(bio_err, "bad magic number\n");
					goto end;
				}
				sptr = salt;
			}

			EVP_BytesToKey(enc_config.cipher, dgst, sptr,
			    (unsigned char *)enc_config.keystr,
			    strlen(enc_config.keystr), 1, key, iv);
			/*
			 * zero the complete buffer or the string passed from
			 * the command line bug picked up by Larry J. Hughes
			 * Jr. <*****@*****.**>
			 */
			if (enc_config.keystr == strbuf)
				explicit_bzero(enc_config.keystr, SIZE);
			else
				explicit_bzero(enc_config.keystr,
				    strlen(enc_config.keystr));
		}
		if (enc_config.hiv != NULL &&
		    !set_hex(enc_config.hiv, iv, sizeof iv)) {
			BIO_printf(bio_err, "invalid hex iv value\n");
			goto end;
		}
		if (enc_config.hiv == NULL && enc_config.keystr == NULL &&
		    EVP_CIPHER_iv_length(enc_config.cipher) != 0) {
			/*
			 * No IV was explicitly set and no IV was generated
			 * during EVP_BytesToKey. Hence the IV is undefined,
			 * making correct decryption impossible.
			 */
			BIO_printf(bio_err, "iv undefined\n");
			goto end;
		}
		if (enc_config.hkey != NULL &&
		    !set_hex(enc_config.hkey, key, sizeof key)) {
			BIO_printf(bio_err, "invalid hex key value\n");
			goto end;
		}
		if ((benc = BIO_new(BIO_f_cipher())) == NULL)
			goto end;

		/*
		 * Since we may be changing parameters work on the encryption
		 * context rather than calling BIO_set_cipher().
		 */

		BIO_get_cipher_ctx(benc, &ctx);

		if (!EVP_CipherInit_ex(ctx, enc_config.cipher, NULL, NULL,
		    NULL, enc_config.enc)) {
			BIO_printf(bio_err, "Error setting cipher %s\n",
			    EVP_CIPHER_name(enc_config.cipher));
			ERR_print_errors(bio_err);
			goto end;
		}
		if (enc_config.nopad)
			EVP_CIPHER_CTX_set_padding(ctx, 0);

		if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv,
		    enc_config.enc)) {
			BIO_printf(bio_err, "Error setting cipher %s\n",
			    EVP_CIPHER_name(enc_config.cipher));
			ERR_print_errors(bio_err);
			goto end;
		}
		if (enc_config.debug) {
			BIO_set_callback(benc, BIO_debug_callback);
			BIO_set_callback_arg(benc, (char *) bio_err);
		}
		if (enc_config.printkey) {
			if (!enc_config.nosalt) {
				printf("salt=");
				for (i = 0; i < (int) sizeof(salt); i++)
					printf("%02X", salt[i]);
				printf("\n");
			}
			if (enc_config.cipher->key_len > 0) {
				printf("key=");
				for (i = 0; i < enc_config.cipher->key_len; i++)
					printf("%02X", key[i]);
				printf("\n");
			}
			if (enc_config.cipher->iv_len > 0) {
				printf("iv =");
				for (i = 0; i < enc_config.cipher->iv_len; i++)
					printf("%02X", iv[i]);
				printf("\n");
			}
			if (enc_config.printkey == 2) {
				ret = 0;
				goto end;
			}
		}
	}
	/* Only encrypt/decrypt as we write the file */
	if (benc != NULL)
		wbio = BIO_push(benc, wbio);

	for (;;) {
		inl = BIO_read(rbio, (char *) buff, bsize);
		if (inl <= 0)
			break;
		if (BIO_write(wbio, (char *) buff, inl) != inl) {
			BIO_printf(bio_err, "error writing output file\n");
			goto end;
		}
	}
	if (!BIO_flush(wbio)) {
		BIO_printf(bio_err, "bad decrypt\n");
		goto end;
	}
	ret = 0;
	if (enc_config.verbose) {
		BIO_printf(bio_err, "bytes read   :%8ld\n", BIO_number_read(in));
		BIO_printf(bio_err, "bytes written:%8ld\n", BIO_number_written(out));
	}
end:
	ERR_print_errors(bio_err);
	free(strbuf);
	free(buff);
	BIO_free(in);
	if (out != NULL)
		BIO_free_all(out);
	BIO_free(benc);
	BIO_free(b64);
#ifdef ZLIB
	BIO_free(bzl);
#endif
	free(pass);

	return (ret);
}
void CC_AES(const EVP_CIPHER *cipher,
						C_BLOB &Param1,
						C_BLOB &Param2,
						C_LONGINT &Param3,
						C_LONGINT &Param5,
						C_LONGINT &Param6,
						C_BLOB &Param7,
						C_BLOB &Param8,
						C_TEXT &returnValue)
{
	EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
	
	unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
	
	const unsigned char *source = (const unsigned char *)Param1.getBytesPtr();
	int source_len = Param1.getBytesLength();
	int crypted_len, tail_len;
	
	bool key_and_iv_is_valid = false;
	
	if(  !Param2.getBytesLength()
		 && Param7.getBytesLength()
		 && Param8.getBytesLength()
		 && Param7.getBytesLength() <= EVP_MAX_KEY_LENGTH
		 && Param8.getBytesLength() <= EVP_MAX_IV_LENGTH)
	{
		memset(key, 0, EVP_MAX_KEY_LENGTH);
		memset( iv, 0, EVP_MAX_IV_LENGTH );
		memcpy(key, Param7.getBytesPtr(), Param7.getBytesLength());
		memcpy( iv, Param8.getBytesPtr(), Param8.getBytesLength());
		key_and_iv_is_valid = true;
	}else
	{
		// passphrase -> key, iv
		key_and_iv_is_valid = (EVP_BytesToKey(cipher, EVP_md5(), NULL,
																					Param2.getBytesPtr(), Param2.getBytesLength(),
																					2048, key, iv) > 0);
	}
	
	if (key_and_iv_is_valid) {
		if(EVP_CipherInit(ctx, cipher, key, iv, 0 == Param3.getIntValue()))
		{
			if(Param6.getIntValue())
			{
				EVP_CIPHER_CTX_set_padding(ctx, 0);
			}
			size_t buf_size = source_len + EVP_MAX_BLOCK_LENGTH;
			unsigned char *buf = (unsigned char *)calloc(buf_size, sizeof(unsigned char));
			if(EVP_CipherUpdate(ctx, buf, &crypted_len, source, source_len))
			{
				if(EVP_CipherFinal(ctx, (buf + crypted_len), &tail_len))
				{
					crypted_len += tail_len;
					C_BLOB temp;
					temp.setBytes((const uint8_t *)buf, crypted_len);
					
					switch (Param5.getIntValue())
					{
						case 1:
							temp.toB64Text(&returnValue);
							break;
						case 2:
							temp.toB64Text(&returnValue, true);
							break;
						default:
							temp.toHexText(&returnValue);
							break;
					}
				}
			}
			free(buf);
		}
		EVP_CIPHER_CTX_free(ctx);
	}
}
/*
 * lanplus_decrypt_aes_cbc_128
 *
 * Decrypt with the AES CBC 128 algorithm
 *
 * param iv is the 16 byte initialization vector
 * param key is the 16 byte key used by the AES algorithm
 * param input is the data to be decrypted
 * param input_length is the number of bytes to be decrypted.  This MUST
 *       be a multiple of the block size, 16.
 * param output is the decrypted output
 * param bytes_written is the number of bytes written.  This param is set
 *       to 0 on failure, or if 0 bytes were input.
 */
void
lanplus_decrypt_aes_cbc_128(const uint8_t * iv,
							const uint8_t * key,
							const uint8_t * input,
							uint32_t          input_length,
							uint8_t       * output,
							uint32_t        * bytes_written)
{
	EVP_CIPHER_CTX ctx;
	EVP_CIPHER_CTX_init(&ctx);
	EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv);
	EVP_CIPHER_CTX_set_padding(&ctx, 0);


	if (verbose >= 5)
	{
		printbuf(iv,  16, "decrypting with this IV");
		printbuf(key, 16, "decrypting with this key");
		printbuf(input, input_length, "decrypting this data");
	}


	*bytes_written = 0;

	if (input_length == 0)
		return;

	/*
	 * The default implementation adds a whole block of padding if the input
	 * data is perfectly aligned.  We would like to keep that from happening.
	 * We have made a point to have our input perfectly padded.
	 */
	assert((input_length % IPMI_CRYPT_AES_CBC_128_BLOCK_SIZE) == 0);


	if (!EVP_DecryptUpdate(&ctx, output, (int *)bytes_written, input, input_length))
	{
		/* Error */
		lprintf(LOG_DEBUG, "ERROR: decrypt update failed");
		*bytes_written = 0;
		return;
	}
	else
	{
		uint32_t tmplen;

		if (!EVP_DecryptFinal_ex(&ctx, output + *bytes_written, (int *)&tmplen))
		{
			char buffer[1000];
			ERR_error_string(ERR_get_error(), buffer);
			lprintf(LOG_DEBUG, "the ERR error %s", buffer);
			lprintf(LOG_DEBUG, "ERROR: decrypt final failed");
			*bytes_written = 0;
			return; /* Error */
		}
		else
		{
			/* Success */
			*bytes_written += tmplen;
			EVP_CIPHER_CTX_cleanup(&ctx);
		}
	}

	if (verbose >= 5)
	{
		lprintf(LOG_DEBUG, "Decrypted %d encrypted bytes", input_length);
		printbuf(output, *bytes_written, "Decrypted this data");
	}
}
Exemple #21
0
static void test1(const EVP_CIPHER *c,const unsigned char *key,int kn,
		  const unsigned char *iv,int in,
		  const unsigned char *plaintext,int pn,
		  const unsigned char *ciphertext,int cn,
		  const unsigned char *aad,int an,
		  const unsigned char *tag,int tn,
		  int encdec)
    {
    EVP_CIPHER_CTX ctx;
    unsigned char out[4096];
    int outl,outl2,mode;

    printf("Testing cipher %s%s\n",EVP_CIPHER_name(c),
	   (encdec == 1 ? "(encrypt)" : (encdec == 0 ? "(decrypt)" : "(encrypt/decrypt)")));
    hexdump(stdout,"Key",key,kn);
    if(in)
	hexdump(stdout,"IV",iv,in);
    hexdump(stdout,"Plaintext",plaintext,pn);
    hexdump(stdout,"Ciphertext",ciphertext,cn);
    if (an)
    	hexdump(stdout,"AAD",aad,an);
    if (tn)
    	hexdump(stdout,"Tag",tag,tn);
    mode = EVP_CIPHER_mode(c); 
    if(kn != EVP_CIPHER_key_length(c))
	{
	fprintf(stderr,"Key length doesn't match, got %d expected %lu\n",kn,
		(unsigned long)EVP_CIPHER_key_length(c));
	test1_exit(5);
	}
    EVP_CIPHER_CTX_init(&ctx);
    if (encdec != 0)
        {
	if (mode == EVP_CIPH_GCM_MODE)
	    {
	    if(!EVP_EncryptInit_ex(&ctx,c,NULL,NULL,NULL))
	        {
		fprintf(stderr,"EncryptInit failed\n");
		ERR_print_errors_fp(stderr);
		test1_exit(10);
		}
	    if(!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, in, NULL))
	        {
		fprintf(stderr,"IV length set failed\n");
		ERR_print_errors_fp(stderr);
		test1_exit(11);
		}
	    if(!EVP_EncryptInit_ex(&ctx,NULL,NULL,key,iv))
	        {
		fprintf(stderr,"Key/IV set failed\n");
		ERR_print_errors_fp(stderr);
		test1_exit(12);
		}
	    if (an && !EVP_EncryptUpdate(&ctx,NULL,&outl,aad,an))
	        {
		fprintf(stderr,"AAD set failed\n");
		ERR_print_errors_fp(stderr);
		test1_exit(13);
		}
	    }
	else if (mode == EVP_CIPH_CCM_MODE)
	    {
	    if(!EVP_EncryptInit_ex(&ctx,c,NULL,NULL,NULL))
	        {
		fprintf(stderr,"EncryptInit failed\n");
		ERR_print_errors_fp(stderr);
		test1_exit(10);
		}
	    if(!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_IVLEN, in, NULL))
	        {
		fprintf(stderr,"IV length set failed\n");
		ERR_print_errors_fp(stderr);
		test1_exit(11);
		}
	    if(!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_TAG, tn, NULL))
	        {
		fprintf(stderr,"Tag length set failed\n");
		ERR_print_errors_fp(stderr);
		test1_exit(11);
		}
	    if(!EVP_EncryptInit_ex(&ctx,NULL,NULL,key,iv))
	        {
		fprintf(stderr,"Key/IV set failed\n");
		ERR_print_errors_fp(stderr);
		test1_exit(12);
		}
	    if (!EVP_EncryptUpdate(&ctx,NULL,&outl,NULL,pn))
	        {
		fprintf(stderr,"Plaintext length set failed\n");
		ERR_print_errors_fp(stderr);
		test1_exit(12);
		}
	    if (an && !EVP_EncryptUpdate(&ctx,NULL,&outl,aad,an))
	        {
		fprintf(stderr,"AAD set failed\n");
		ERR_print_errors_fp(stderr);
		test1_exit(13);
		}
	    }
	else if(!EVP_EncryptInit_ex(&ctx,c,NULL,key,iv))
	    {
	    fprintf(stderr,"EncryptInit failed\n");
	    ERR_print_errors_fp(stderr);
	    test1_exit(10);
	    }
	EVP_CIPHER_CTX_set_padding(&ctx,0);

	if(!EVP_EncryptUpdate(&ctx,out,&outl,plaintext,pn))
	    {
	    fprintf(stderr,"Encrypt failed\n");
	    ERR_print_errors_fp(stderr);
	    test1_exit(6);
	    }
	if(!EVP_EncryptFinal_ex(&ctx,out+outl,&outl2))
	    {
	    fprintf(stderr,"EncryptFinal failed\n");
	    ERR_print_errors_fp(stderr);
	    test1_exit(7);
	    }

	if(outl+outl2 != cn)
	    {
	    fprintf(stderr,"Ciphertext length mismatch got %d expected %d\n",
		    outl+outl2,cn);
	    test1_exit(8);
	    }

	if(memcmp(out,ciphertext,cn))
	    {
	    fprintf(stderr,"Ciphertext mismatch\n");
	    hexdump(stderr,"Got",out,cn);
	    hexdump(stderr,"Expected",ciphertext,cn);
	    test1_exit(9);
	    }
	if (mode == EVP_CIPH_GCM_MODE || mode == EVP_CIPH_CCM_MODE)
	    {
	    unsigned char rtag[16];
	    /* Note: EVP_CTRL_CCM_GET_TAG has same value as 
	     * EVP_CTRL_GCM_GET_TAG
	     */
	    if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, tn, rtag))
	        {
		fprintf(stderr,"Get tag failed\n");
		ERR_print_errors_fp(stderr);
		test1_exit(14);
		}
	    if (memcmp(rtag, tag, tn))
		{
		fprintf(stderr,"Tag mismatch\n");
		hexdump(stderr,"Got",rtag,tn);
		hexdump(stderr,"Expected",tag,tn);
		test1_exit(9);
	    	}
	    }
	}

    if (encdec <= 0)
        {
	if (mode == EVP_CIPH_GCM_MODE)
	    {
	    if(!EVP_DecryptInit_ex(&ctx,c,NULL,NULL,NULL))
	        {
		fprintf(stderr,"EncryptInit failed\n");
		ERR_print_errors_fp(stderr);
		test1_exit(10);
		}
	    if(!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, in, NULL))
	        {
		fprintf(stderr,"IV length set failed\n");
		ERR_print_errors_fp(stderr);
		test1_exit(11);
		}
	    if(!EVP_DecryptInit_ex(&ctx,NULL,NULL,key,iv))
	        {
		fprintf(stderr,"Key/IV set failed\n");
		ERR_print_errors_fp(stderr);
		test1_exit(12);
		}
	    if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_TAG, tn, (void *)tag))
	        {
		fprintf(stderr,"Set tag failed\n");
		ERR_print_errors_fp(stderr);
		test1_exit(14);
		}
	    if (an && !EVP_DecryptUpdate(&ctx,NULL,&outl,aad,an))
	        {
		fprintf(stderr,"AAD set failed\n");
		ERR_print_errors_fp(stderr);
		test1_exit(13);
		}
	    }
	else if (mode == EVP_CIPH_CCM_MODE)
	    {
	    if(!EVP_DecryptInit_ex(&ctx,c,NULL,NULL,NULL))
	        {
		fprintf(stderr,"DecryptInit failed\n");
		ERR_print_errors_fp(stderr);
		test1_exit(10);
		}
	    if(!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_IVLEN, in, NULL))
	        {
		fprintf(stderr,"IV length set failed\n");
		ERR_print_errors_fp(stderr);
		test1_exit(11);
		}
	    if(!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_TAG, tn, (void *)tag))
	        {
		fprintf(stderr,"Tag length set failed\n");
		ERR_print_errors_fp(stderr);
		test1_exit(11);
		}
	    if(!EVP_DecryptInit_ex(&ctx,NULL,NULL,key,iv))
	        {
		fprintf(stderr,"Key/Nonce set failed\n");
		ERR_print_errors_fp(stderr);
		test1_exit(12);
		}
	    if (!EVP_DecryptUpdate(&ctx,NULL,&outl,NULL,pn))
	        {
		fprintf(stderr,"Plaintext length set failed\n");
		ERR_print_errors_fp(stderr);
		test1_exit(12);
		}
	    if (an && !EVP_EncryptUpdate(&ctx,NULL,&outl,aad,an))
	        {
		fprintf(stderr,"AAD set failed\n");
		ERR_print_errors_fp(stderr);
		test1_exit(13);
		}
	    }
	else if(!EVP_DecryptInit_ex(&ctx,c,NULL,key,iv))
	    {
	    fprintf(stderr,"DecryptInit failed\n");
	    ERR_print_errors_fp(stderr);
	    test1_exit(11);
	    }
	EVP_CIPHER_CTX_set_padding(&ctx,0);

	if(!EVP_DecryptUpdate(&ctx,out,&outl,ciphertext,cn))
	    {
	    fprintf(stderr,"Decrypt failed\n");
	    ERR_print_errors_fp(stderr);
	    test1_exit(6);
	    }
	if(mode != EVP_CIPH_CCM_MODE && !EVP_DecryptFinal_ex(&ctx,out+outl,&outl2))
	    {
	    fprintf(stderr,"DecryptFinal failed\n");
	    ERR_print_errors_fp(stderr);
	    test1_exit(7);
	    }

	if(outl+outl2 != pn)
	    {
	    fprintf(stderr,"Plaintext length mismatch got %d expected %d\n",
		    outl+outl2,pn);
	    test1_exit(8);
	    }

	if(memcmp(out,plaintext,pn))
	    {
	    fprintf(stderr,"Plaintext mismatch\n");
	    hexdump(stderr,"Got",out,pn);
	    hexdump(stderr,"Expected",plaintext,pn);
	    test1_exit(9);
	    }
	}

    EVP_CIPHER_CTX_cleanup(&ctx);

    printf("\n");
    }
CK_RV PKCS11_Encryption_OpenSSL::InitHelper(Cryptoki_Session_Context* pSessionCtx, CK_MECHANISM_PTR pEncryptMech, CK_OBJECT_HANDLE hKey, BOOL isEncrypt)
{
    OPENSSL_HEADER();
    
    OpenSSLEncryptData* pEnc;
    const EVP_CIPHER* pCipher;
    int padding = 0;

    if(             pSessionCtx                 == NULL) return CKR_SESSION_CLOSED;
    if( isEncrypt && pSessionCtx->EncryptionCtx != NULL) return CKR_SESSION_PARALLEL_NOT_SUPPORTED;
    if(!isEncrypt && pSessionCtx->DecryptionCtx != NULL) return CKR_SESSION_PARALLEL_NOT_SUPPORTED;
    
    pEnc = (OpenSSLEncryptData*)TINYCLR_SSL_MALLOC(sizeof(*pEnc));

    if(pEnc == NULL) return CKR_DEVICE_MEMORY;

    TINYCLR_SSL_MEMSET(pEnc, 0, sizeof(*pEnc));

    pEnc->Key = PKCS11_Keys_OpenSSL::GetKeyFromHandle(pSessionCtx, hKey, !isEncrypt);

    pEnc->IsSymmetric = TRUE;

    switch(pEncryptMech->mechanism)
    {
        case CKM_AES_CBC:
        case CKM_AES_CBC_PAD:
            switch(pEnc->Key->size)
            {
                case 128:
                    pCipher = EVP_aes_128_cbc();
                    break;
                case 192:
                    pCipher = EVP_aes_192_cbc();
                    break;
                case 256:
                    pCipher = EVP_aes_256_cbc();
                    break;
                default:
                    OPENSSL_SET_AND_LEAVE(CKR_MECHANISM_INVALID);
            }
            if(pEncryptMech->mechanism == CKM_AES_CBC_PAD)
            {
                padding = 1;
            }
            break;

        case CKM_AES_ECB:
        case CKM_AES_ECB_PAD:
            switch(pEnc->Key->size)
            {
                case 128:
                    pCipher = EVP_aes_128_ecb();
                    break;
                case 192:
                    pCipher = EVP_aes_192_ecb();
                    break;
                case 256:
                    pCipher = EVP_aes_256_ecb();
                    break;
                default:
                    OPENSSL_SET_AND_LEAVE(CKR_MECHANISM_INVALID);
            }
            if(pEncryptMech->mechanism == CKM_AES_ECB_PAD)
            {
                padding = 1;
            }
            break;

        case CKM_DES3_CBC:
            pCipher = EVP_des_ede3_cbc();
            break;

        case CKM_DES3_CBC_PAD:
            pCipher = EVP_des_ede3_cbc();
            padding = 1;
            break;

        case CKM_RSA_PKCS:
            pEnc->IsSymmetric= FALSE;
            padding = RSA_PKCS1_PADDING;
            break;

        default:
            OPENSSL_SET_AND_LEAVE(CKR_MECHANISM_INVALID);
    }

    if(pEnc->IsSymmetric)
    {
        if(pEncryptMech->ulParameterLen > 0 && pEncryptMech->ulParameterLen > 0)
        {
            memcpy(pEnc->IV, pEncryptMech->pParameter, pEncryptMech->ulParameterLen);
        }

        pEnc->Key->ctx = &pEnc->SymmetricCtx;

        if(isEncrypt) 
        {
            OPENSSL_CHECKRESULT(EVP_EncryptInit(&pEnc->SymmetricCtx, pCipher, (const UINT8*)pEnc->Key->key, pEnc->IV));
        }
        else
        {
            OPENSSL_CHECKRESULT(EVP_DecryptInit(&pEnc->SymmetricCtx, pCipher, (const UINT8*)pEnc->Key->key, pEnc->IV));
        }

        OPENSSL_CHECKRESULT(EVP_CIPHER_CTX_set_padding(&pEnc->SymmetricCtx, padding));
    }
    else
    {
        pEnc->Key->ctx = EVP_PKEY_CTX_new((EVP_PKEY*)pEnc->Key->key, NULL);

        if(isEncrypt)
        {
            OPENSSL_CHECKRESULT(EVP_PKEY_encrypt_init       ((EVP_PKEY_CTX*)pEnc->Key->ctx         ));
            OPENSSL_CHECKRESULT(EVP_PKEY_CTX_set_rsa_padding((EVP_PKEY_CTX*)pEnc->Key->ctx, padding));
        }
        else
        {
            OPENSSL_CHECKRESULT(EVP_PKEY_decrypt_init       ((EVP_PKEY_CTX*)pEnc->Key->ctx         ));
            OPENSSL_CHECKRESULT(EVP_PKEY_CTX_set_rsa_padding((EVP_PKEY_CTX*)pEnc->Key->ctx, padding));
        }
    }

    if(isEncrypt) pSessionCtx->EncryptionCtx = pEnc;
    else          pSessionCtx->DecryptionCtx = pEnc;

    OPENSSL_CLEANUP();
    if(retVal != CKR_OK && pEnc != NULL)
    {
        TINYCLR_SSL_FREE(pEnc);
    }
    OPENSSL_RETURN();
    
}
Exemple #23
0
    jdoubleArray Java_de_blinkt_openvpn_core_NativeUtils_getOpenSSLSpeed(JNIEnv* env, jclass thiz, jstring algorithm, jint testnumber)
{
    static const unsigned char key16[16] = {
        0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
        0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12
    };
    const EVP_CIPHER *evp_cipher = NULL;

    const char* alg = (*env)->GetStringUTFChars( env, algorithm , NULL ) ;

    evp_cipher = EVP_get_cipherbyname(alg);
    if (evp_cipher == NULL)
        evp_md = EVP_get_digestbyname(alg);
    if (evp_cipher == NULL && evp_md == NULL) {
        //        BIO_printf(bio_err, "%s: %s is an unknown cipher or digest\n", prog, opt_arg());
        //jniThrowException(env, "java/security/NoSuchAlgorithmException", "Algorithm not found");
        return NULL;
    }


    const char* name;

    loopargs_t *loopargs = NULL;
    int loopargs_len = 1;
    int async_jobs=0;
    loopargs = malloc(loopargs_len * sizeof(loopargs_t));
    memset(loopargs, 0, loopargs_len * sizeof(loopargs_t));


    jdoubleArray ret = (*env)->NewDoubleArray(env, 3);

    if (testnum < 0 || testnum >= SIZE_NUM)
        return NULL;

    testnum = testnumber;


    for (int i = 0; i < loopargs_len; i++) {
        int misalign=0;
        loopargs[i].buf_malloc = malloc((int)BUFSIZE + MAX_MISALIGNMENT + 1);
        loopargs[i].buf2_malloc = malloc((int)BUFSIZE + MAX_MISALIGNMENT + 1);
        /* Align the start of buffers on a 64 byte boundary */
        loopargs[i].buf = loopargs[i].buf_malloc + misalign;
        loopargs[i].buf2 = loopargs[i].buf2_malloc + misalign;
    }


    int count;
    float d;
    if (evp_cipher) {
        name = OBJ_nid2ln(EVP_CIPHER_nid(evp_cipher));
        /*
         * -O3 -fschedule-insns messes up an optimization here!
         * names[D_EVP] somehow becomes NULL
         */


        for (int k = 0; k < loopargs_len; k++) {
            loopargs[k].ctx = EVP_CIPHER_CTX_new();
            if (decrypt)
                EVP_DecryptInit_ex(loopargs[k].ctx, evp_cipher, NULL, key16, iv);
            else
                EVP_EncryptInit_ex(loopargs[k].ctx, evp_cipher, NULL, key16, iv);
            EVP_CIPHER_CTX_set_padding(loopargs[k].ctx, 0);
        }

        Time_F(START);
        pthread_t timer_thread;

        if (pthread_create(&timer_thread, NULL, stop_run, NULL))
            return NULL;

        count = run_benchmark(async_jobs, EVP_Update_loop, loopargs);
        d = Time_F(STOP);
        for (int k = 0; k < loopargs_len; k++) {
            EVP_CIPHER_CTX_free(loopargs[k].ctx);
        }
    }
    if (evp_md) {
        name = OBJ_nid2ln(EVP_MD_type(evp_md));
        //            print_message(names[D_EVP], save_count, lengths[testnum]);

        pthread_t timer_thread;
        if (pthread_create(&timer_thread, NULL, stop_run, NULL))
            return NULL;

        Time_F(START);
        count = run_benchmark(async_jobs, EVP_Digest_loop, loopargs);
        d = Time_F(STOP);
    }

    // Save results in hacky way
    double results[] = {(double) lengths[testnum], (double) count, d};


    (*env)->SetDoubleArrayRegion(env, ret, 0, 3, results);
    //        print_result(D_EVP, testnum, count, d);


    return ret;
}
Exemple #24
0
bool
crypto_aes_decrypt(struct string *ciphertext, struct string *aes_key, struct string *aes_iv, struct string *decrypted)
{
    bool retval = false;
    EVP_CIPHER_CTX ctx;
    int decryptspace;
    int decryptdone;

    EVP_CIPHER_CTX_init(&ctx);
    if (!EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL,
        (unsigned char *)string_get(aes_key),
        (unsigned char *)string_get(aes_iv))) {
        log_err("crypto_aes_decrypt: init failed\n");
        ERR_print_errors_fp(stderr);
        goto bail_out;
    }
    EVP_CIPHER_CTX_set_padding(&ctx, 1);
    
    if (string_length(aes_key) != EVP_CIPHER_CTX_key_length(&ctx)) {
        log_err("crypto_aes_decrypt: invalid key size (%" PRIuPTR " vs expected %d)\n",
                string_length(aes_key), EVP_CIPHER_CTX_key_length(&ctx));
        goto bail_out;
    }
    if (string_length(aes_iv) != EVP_CIPHER_CTX_iv_length(&ctx)) {
        log_err("crypto_aes_decrypt: invalid iv size (%" PRIuPTR " vs expected %d)\n",
                string_length(aes_iv), EVP_CIPHER_CTX_iv_length(&ctx));
        goto bail_out;
    }

    decryptspace = string_length(ciphertext) + EVP_MAX_BLOCK_LENGTH;

    string_free(decrypted); /* free previous buffer */
    string_init(decrypted, decryptspace, 1024);
    if (string_size(decrypted) < decryptspace) {
        log_err("crypto_aes_decrypt: decrypt buffer malloc error\n");
        goto bail_out;
    }
    
    if (EVP_DecryptUpdate(&ctx, (unsigned char*)string_get(decrypted),
            &decryptdone, (unsigned char*)string_get(ciphertext),
            string_length(ciphertext))) {
        /* TODO: need cleaner way: */
        decrypted->_u._s.length = decryptdone;
    } else {
        log_err("crypto_aes_decrypt: decrypt failed\n");
        ERR_print_errors_fp(stderr);
        goto bail_out;
    }
    
    if (EVP_DecryptFinal_ex(&ctx,
            (unsigned char*)string_get(decrypted)+string_length(decrypted),
            &decryptdone)) {
        /* TODO: need cleaner way: */
        decrypted->_u._s.length += decryptdone;
    } else {
        log_err("crypto_aes_decrypt: decrypt final failed\n");
        ERR_print_errors_fp(stderr);
        goto bail_out;
    }

    retval = true;

bail_out:
    EVP_CIPHER_CTX_cleanup(&ctx);
    return retval;
}
Exemple #25
0
static int entersafe_mac_apdu(sc_card_t *card, sc_apdu_t *apdu,
							  u8 * key,size_t keylen,
							  u8 * buff,size_t buffsize)
{
	 int r;
	 u8 iv[8];
	 u8 *tmp=0,*tmp_rounded=NULL;
	 size_t tmpsize=0,tmpsize_rounded=0;
	 int outl=0;
	 EVP_CIPHER_CTX ctx;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	 assert(card);
	 assert(apdu);
	 assert(key);
	 assert(buff);

	 if(apdu->cse != SC_APDU_CASE_3_SHORT)
		  return SC_ERROR_INTERNAL;
	 if(keylen!=8 && keylen!=16)
		  return SC_ERROR_INTERNAL;

	 r=entersafe_gen_random(card,iv,sizeof(iv));
	 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL,r,"entersafe gen random failed");

	 /* encode the APDU in the buffer */
	 if ((r=sc_apdu_get_octets(card->ctx, apdu, &tmp, &tmpsize,SC_PROTO_RAW)) != SC_SUCCESS)
		  goto out;

	 /* round to 8 */
	 tmpsize_rounded=(tmpsize/8+1)*8;

	 tmp_rounded = malloc(tmpsize_rounded);
	 if (tmp_rounded == NULL)
	 {
		  r =  SC_ERROR_OUT_OF_MEMORY;
		  goto out;
	 }
	 
	 /*build content and padded buffer by 0x80 0x00 0x00..... */
	 memset(tmp_rounded,0,tmpsize_rounded);
	 memcpy(tmp_rounded,tmp,tmpsize);
	 tmp_rounded[4]+=4;
	 tmp_rounded[tmpsize]=0x80;

	 /* block_size-1 blocks*/
	 EVP_CIPHER_CTX_init(&ctx);
	 EVP_CIPHER_CTX_set_padding(&ctx,0);
	 EVP_EncryptInit_ex(&ctx, EVP_des_cbc(), NULL, key, iv);

	 if(tmpsize_rounded>8){
		  if(!EVP_EncryptUpdate(&ctx,tmp_rounded,&outl,tmp_rounded,tmpsize_rounded-8)){
			   r = SC_ERROR_INTERNAL;
			   goto out;			   
		  }
	 }
	 /* last block */
	 if(keylen==8)
	 {
		  if(!EVP_EncryptUpdate(&ctx,tmp_rounded+outl,&outl,tmp_rounded+outl,8)){
			   r = SC_ERROR_INTERNAL;
			   goto out;			   
		  }
	 }
	 else
	 {
		  EVP_EncryptInit_ex(&ctx, EVP_des_ede_cbc(), NULL, key,tmp_rounded+outl-8);
		  if(!EVP_EncryptUpdate(&ctx,tmp_rounded+outl,&outl,tmp_rounded+outl,8)){
			   r = SC_ERROR_INTERNAL;
			   goto out;			   
		  }
	 }

	 if (!EVP_CIPHER_CTX_cleanup(&ctx)){
		  r = SC_ERROR_INTERNAL;
		  goto out;			   
	 }

	 memcpy(buff,apdu->data,apdu->lc);
	 /* use first 4 bytes of last block as mac value*/
	 memcpy(buff+apdu->lc,tmp_rounded+tmpsize_rounded-8,4);
	 apdu->data=buff;
	 apdu->lc+=4;
	 apdu->datalen=apdu->lc;

out:
	 if(tmp)
		  free(tmp);
	 if(tmp_rounded)
		  free(tmp_rounded);

	 SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
}
Exemple #26
0
/**
 * @brief Initialise a context for decrypting arbitrary data using the given key.
 * @note If *ctx is NULL, a apr_crypto_block_t will be created from a pool. If
 *       *ctx is not NULL, *ctx must point at a previously created structure.
 * @param ctx The block context returned, see note.
 * @param blockSize The block size of the cipher.
 * @param iv Optional initialisation vector. If the buffer pointed to is NULL,
 *           an IV will be created at random, in space allocated from the pool.
 *           If the buffer is not NULL, the IV in the buffer will be used.
 * @param key The key structure.
 * @param p The pool to use.
 * @return Returns APR_ENOIV if an initialisation vector is required but not specified.
 *         Returns APR_EINIT if the backend failed to initialise the context. Returns
 *         APR_ENOTIMPL if not implemented.
 */
static apr_status_t crypto_block_decrypt_init(apr_crypto_block_t **ctx,
        apr_size_t *blockSize, const unsigned char *iv,
        const apr_crypto_key_t *key, apr_pool_t *p)
{
    apr_crypto_config_t *config = key->f->config;
    apr_crypto_block_t *block = *ctx;
    if (!block) {
        *ctx = block = apr_pcalloc(p, sizeof(apr_crypto_block_t));
    }
    if (!block) {
        return APR_ENOMEM;
    }
    block->f = key->f;
    block->pool = p;
    block->provider = key->provider;

    apr_pool_cleanup_register(p, block, crypto_block_cleanup_helper,
            apr_pool_cleanup_null);

    /* create a new context for encryption */
    EVP_CIPHER_CTX_init(&block->cipherCtx);
    block->initialised = 1;

    /* generate an IV, if necessary */
    if (key->ivSize) {
        if (iv == NULL) {
            return APR_ENOIV;
        }
    }

    /* set up our encryption context */
#if CRYPTO_OPENSSL_CONST_BUFFERS
    if (!EVP_DecryptInit_ex(&block->cipherCtx, key->cipher, config->engine,
            key->key, iv)) {
#else
        if (!EVP_DecryptInit_ex(&block->cipherCtx, key->cipher, config->engine, (unsigned char *) key->key, (unsigned char *) iv)) {
#endif
        return APR_EINIT;
    }

    /* Clear up any read padding */
    if (!EVP_CIPHER_CTX_set_padding(&block->cipherCtx, key->doPad)) {
        return APR_EPADDING;
    }

    if (blockSize) {
        *blockSize = EVP_CIPHER_block_size(key->cipher);
    }

    return APR_SUCCESS;

}

/**
 * @brief Decrypt data provided by in, write it to out.
 * @note The number of bytes written will be written to outlen. If
 *       out is NULL, outlen will contain the maximum size of the
 *       buffer needed to hold the data, including any data
 *       generated by apr_crypto_block_decrypt_finish below. If *out points
 *       to NULL, a buffer sufficiently large will be created from
 *       the pool provided. If *out points to a not-NULL value, this
 *       value will be used as a buffer instead.
 * @param out Address of a buffer to which data will be written,
 *        see note.
 * @param outlen Length of the output will be written here.
 * @param in Address of the buffer to read.
 * @param inlen Length of the buffer to read.
 * @param ctx The block context to use.
 * @return APR_ECRYPT if an error occurred. Returns APR_ENOTIMPL if
 *         not implemented.
 */
static apr_status_t crypto_block_decrypt(unsigned char **out,
        apr_size_t *outlen, const unsigned char *in, apr_size_t inlen,
        apr_crypto_block_t *ctx)
{
    int outl = *outlen;
    unsigned char *buffer;

    /* are we after the maximum size of the out buffer? */
    if (!out) {
        *outlen = inlen + EVP_MAX_BLOCK_LENGTH;
        return APR_SUCCESS;
    }

    /* must we allocate the output buffer from a pool? */
    if (!(*out)) {
        buffer = apr_palloc(ctx->pool, inlen + EVP_MAX_BLOCK_LENGTH);
        if (!buffer) {
            return APR_ENOMEM;
        }
        apr_crypto_clear(ctx->pool, buffer, inlen + EVP_MAX_BLOCK_LENGTH);
        *out = buffer;
    }

#if CRYPT_OPENSSL_CONST_BUFFERS
    if (!EVP_DecryptUpdate(&ctx->cipherCtx, *out, &outl, in, inlen)) {
#else
    if (!EVP_DecryptUpdate(&ctx->cipherCtx, *out, &outl, (unsigned char *) in,
            inlen)) {
#endif
        return APR_ECRYPT;
    }
    *outlen = outl;

    return APR_SUCCESS;

}

/**
 * @brief Decrypt final data block, write it to out.
 * @note If necessary the final block will be written out after being
 *       padded. Typically the final block will be written to the
 *       same buffer used by apr_crypto_block_decrypt, offset by the
 *       number of bytes returned as actually written by the
 *       apr_crypto_block_decrypt() call. After this call, the context
 *       is cleaned and can be reused by apr_crypto_block_decrypt_init().
 * @param out Address of a buffer to which data will be written. This
 *            buffer must already exist, and is usually the same
 *            buffer used by apr_evp_crypt(). See note.
 * @param outlen Length of the output will be written here.
 * @param ctx The block context to use.
 * @return APR_ECRYPT if an error occurred.
 * @return APR_EPADDING if padding was enabled and the block was incorrectly
 *         formatted.
 * @return APR_ENOTIMPL if not implemented.
 */
static apr_status_t crypto_block_decrypt_finish(unsigned char *out,
        apr_size_t *outlen, apr_crypto_block_t *ctx)
{

    int len = *outlen;

    if (EVP_DecryptFinal_ex(&ctx->cipherCtx, out, &len) == 0) {
        return APR_EPADDING;
    }
    *outlen = len;

    return APR_SUCCESS;

}
Exemple #27
0
void cipher_context_init(cipher_ctx_t *ctx, int method, int enc)
{
    if (method <= TABLE || method >= CIPHER_NUM) {
        LOGE("cipher_context_init(): Illegal method");
        return;
    }

    if (method >= SALSA20) {
        enc_iv_len = supported_ciphers_iv_size[method];
        return;
    }

    const char *ciphername = supported_ciphers[method];
#if defined(USE_CRYPTO_APPLECC)
    cipher_cc_t *cc = &ctx->cc;
    cc->cryptor = NULL;
    cc->cipher  = supported_ciphers_applecc[method];
    if (cc->cipher == kCCAlgorithmInvalid) {
        cc->valid = kCCContextInvalid;
    } else {
        cc->valid = kCCContextValid;
        if (cc->cipher == kCCAlgorithmRC4) {
            cc->mode    = kCCModeRC4;
            cc->padding = ccNoPadding;
        } else {
            cc->mode    = kCCModeCFB;
            cc->padding = ccPKCS7Padding;
        }
        return;
    }
#endif

    cipher_evp_t *evp         = &ctx->evp;
    const cipher_kt_t *cipher = get_cipher_type(method);
#if defined(USE_CRYPTO_OPENSSL)
    if (cipher == NULL) {
        LOGE("Cipher %s not found in OpenSSL library", ciphername);
        FATAL("Cannot initialize cipher");
    }
    EVP_CIPHER_CTX_init(evp);
    if (!EVP_CipherInit_ex(evp, cipher, NULL, NULL, NULL, enc)) {
        LOGE("Cannot initialize cipher %s", ciphername);
        exit(EXIT_FAILURE);
    }
    if (!EVP_CIPHER_CTX_set_key_length(evp, enc_key_len)) {
        EVP_CIPHER_CTX_cleanup(evp);
        LOGE("Invalid key length: %d", enc_key_len);
        exit(EXIT_FAILURE);
    }
    if (method > RC4_MD5) {
        EVP_CIPHER_CTX_set_padding(evp, 1);
    }
#elif defined(USE_CRYPTO_POLARSSL)
    if (cipher == NULL) {
        LOGE("Cipher %s not found in PolarSSL library", ciphername);
        FATAL("Cannot initialize PolarSSL cipher");
    }
    if (cipher_init_ctx(evp, cipher) != 0) {
        FATAL("Cannot initialize PolarSSL cipher context");
    }
#elif defined(USE_CRYPTO_MBEDTLS)
    // XXX: mbedtls_cipher_setup future change
    // NOTE:  Currently also clears structure. In future versions you will be required to call
    //        mbedtls_cipher_init() on the structure first.
    //        void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx );
    if (cipher == NULL) {
        LOGE("Cipher %s not found in mbed TLS library", ciphername);
        FATAL("Cannot initialize mbed TLS cipher");
    }
    mbedtls_cipher_init(evp);
    if (mbedtls_cipher_setup(evp, cipher) != 0) {
        FATAL("Cannot initialize mbed TLS cipher context");
    }
#endif
}
Exemple #28
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");
}
Exemple #29
0
static void test1(const EVP_CIPHER *c,const unsigned char *key,int kn,
		  const unsigned char *iv,int in,
		  const unsigned char *plaintext,int pn,
		  const unsigned char *ciphertext,int cn,
		  int encdec)
    {
    EVP_CIPHER_CTX ctx;
    unsigned char out[4096];
    int outl,outl2;

    printf("Testing cipher %s%s\n",EVP_CIPHER_name(c),
	   (encdec == 1 ? "(encrypt)" : (encdec == 0 ? "(decrypt)" : "(encrypt/decrypt)")));
    hexdump(stdout,"Key",key,kn);
    if(in)
	hexdump(stdout,"IV",iv,in);
    hexdump(stdout,"Plaintext",plaintext,pn);
    hexdump(stdout,"Ciphertext",ciphertext,cn);
    
    if(kn != c->key_len)
	{
	fprintf(stderr,"Key length doesn't match, got %d expected %d\n",kn,
		c->key_len);
	test1_exit(5);
	}
    EVP_CIPHER_CTX_init(&ctx);
    if (encdec != 0)
        {
	if(!EVP_EncryptInit_ex(&ctx,c,NULL,key,iv))
	    {
	    fprintf(stderr,"EncryptInit failed\n");
	    ERR_print_errors_fp(stderr);
	    test1_exit(10);
	    }
	EVP_CIPHER_CTX_set_padding(&ctx,0);

	if(!EVP_EncryptUpdate(&ctx,out,&outl,plaintext,pn))
	    {
	    fprintf(stderr,"Encrypt failed\n");
	    ERR_print_errors_fp(stderr);
	    test1_exit(6);
	    }
	if(!EVP_EncryptFinal_ex(&ctx,out+outl,&outl2))
	    {
	    fprintf(stderr,"EncryptFinal failed\n");
	    ERR_print_errors_fp(stderr);
	    test1_exit(7);
	    }

	if(outl+outl2 != cn)
	    {
	    fprintf(stderr,"Ciphertext length mismatch got %d expected %d\n",
		    outl+outl2,cn);
	    test1_exit(8);
	    }

	if(memcmp(out,ciphertext,cn))
	    {
	    fprintf(stderr,"Ciphertext mismatch\n");
	    hexdump(stderr,"Got",out,cn);
	    hexdump(stderr,"Expected",ciphertext,cn);
	    test1_exit(9);
	    }
	}

    if (encdec <= 0)
        {
	if(!EVP_DecryptInit_ex(&ctx,c,NULL,key,iv))
	    {
	    fprintf(stderr,"DecryptInit failed\n");
	    ERR_print_errors_fp(stderr);
	    test1_exit(11);
	    }
	EVP_CIPHER_CTX_set_padding(&ctx,0);

	if(!EVP_DecryptUpdate(&ctx,out,&outl,ciphertext,cn))
	    {
	    fprintf(stderr,"Decrypt failed\n");
	    ERR_print_errors_fp(stderr);
	    test1_exit(6);
	    }
	if(!EVP_DecryptFinal_ex(&ctx,out+outl,&outl2))
	    {
	    fprintf(stderr,"DecryptFinal failed\n");
	    ERR_print_errors_fp(stderr);
	    test1_exit(7);
	    }

	if(outl+outl2 != cn)
	    {
	    fprintf(stderr,"Plaintext length mismatch got %d expected %d\n",
		    outl+outl2,cn);
	    test1_exit(8);
	    }

	if(memcmp(out,plaintext,cn))
	    {
	    fprintf(stderr,"Plaintext mismatch\n");
	    hexdump(stderr,"Got",out,cn);
	    hexdump(stderr,"Expected",plaintext,cn);
	    test1_exit(9);
	    }
	}

    EVP_CIPHER_CTX_cleanup(&ctx);

    printf("\n");
    }
Exemple #30
0
BUF_MEM *
retail_mac_des(const BUF_MEM * key, const BUF_MEM * in)
{
    /* ISO 9797-1 algorithm 3 retail mac without any padding */
    BUF_MEM * c_tmp = NULL, *d_tmp = NULL, *mac = NULL, *block = NULL;
    EVP_CIPHER_CTX * ctx = NULL;
    size_t len;

    check(key, "Invalid arguments");

    /* Flawfinder: ignore */
    len = EVP_CIPHER_block_size(EVP_des_cbc());
    check(key->length >= 2*len, "Key too short");

    ctx = EVP_CIPHER_CTX_new();
    if (!ctx)
        goto err;
    EVP_CIPHER_CTX_init(ctx);
    /* Flawfinder: ignore */
    if (!EVP_CipherInit_ex(ctx, EVP_des_cbc(), NULL,
            (unsigned char *) key->data, NULL, 1) ||
            !EVP_CIPHER_CTX_set_padding(ctx, 0))
        goto err;

    /* get last block of des_cbc encrypted input */
    /* Flawfinder: ignore */
    c_tmp = cipher(ctx, EVP_des_cbc(), NULL, NULL, NULL, 1, in);
    if (!c_tmp)
        goto err;
    block = BUF_MEM_create_init(c_tmp->data + c_tmp->length - len, len);

    /* decrypt last block with the rest of the key */
    /* IV is always NULL */
    /* Flawfinder: ignore */
    if (!block || !EVP_CipherInit_ex(ctx, EVP_des_cbc(), NULL,
            (unsigned char *) key->data + len, NULL, 0) ||
            !EVP_CIPHER_CTX_set_padding(ctx, 0))
        goto err;
    /* Flawfinder: ignore */
    d_tmp = cipher(ctx, EVP_des_cbc(), NULL, NULL, NULL, 0, block);

    /* encrypt last block with the first key */
    /* IV is always NULL */
    /* Flawfinder: ignore */
    if (!d_tmp || !EVP_CipherInit_ex(ctx, EVP_des_cbc(), NULL,
            (unsigned char *) key->data, NULL, 1) ||
            !EVP_CIPHER_CTX_set_padding(ctx, 0))
        goto err;
    /* Flawfinder: ignore */
    mac = cipher(ctx, EVP_des_cbc(), NULL, NULL, NULL, 1, d_tmp);

    BUF_MEM_free(block);
    BUF_MEM_free(c_tmp);
    BUF_MEM_free(d_tmp);
    EVP_CIPHER_CTX_free(ctx);

    return mac;

err:
    if (block)
        BUF_MEM_free(block);
    if (c_tmp)
        BUF_MEM_free(c_tmp);
    if (d_tmp)
        BUF_MEM_free(d_tmp);
    if (ctx)
        EVP_CIPHER_CTX_free(ctx);

    return NULL;
}