Пример #1
0
void
cipher_init(CipherContext *cc, Cipher *cipher,
    const u_char *key, u_int keylen, const u_char *iv, u_int ivlen,
    int encrypt)
{
	static int dowarn = 1;
#ifdef SSH_OLD_EVP
	EVP_CIPHER *type;
#else
	const EVP_CIPHER *type;
#endif
	int klen;

	if (cipher->number == SSH_CIPHER_DES) {
		if (dowarn) {
			error("Warning: use of DES is strongly discouraged "
			    "due to cryptographic weaknesses");
			dowarn = 0;
		}
		if (keylen > 8)
			keylen = 8;
	}
	cc->plaintext = (cipher->number == SSH_CIPHER_NONE);

	if (keylen < cipher->key_len)
		fatal("cipher_init: key length %d is insufficient for %s.",
		    keylen, cipher->name);
	if (iv != NULL && ivlen < cipher->block_size)
		fatal("cipher_init: iv length %d is insufficient for %s.",
		    ivlen, cipher->name);
	cc->cipher = cipher;

	type = (*cipher->evptype)();

	EVP_CIPHER_CTX_init(&cc->evp);
#ifdef SSH_OLD_EVP
	if (type->key_len > 0 && type->key_len != keylen) {
		debug("cipher_init: set keylen (%d -> %d)",
		    type->key_len, keylen);
		type->key_len = keylen;
	}
	EVP_CipherInit(&cc->evp, type, (u_char *)key, (u_char *)iv,
	    (encrypt == CIPHER_ENCRYPT));
#else
	if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv,
	    (encrypt == CIPHER_ENCRYPT)) == 0)
		fatal("cipher_init: EVP_CipherInit failed for %s",
		    cipher->name);
	klen = EVP_CIPHER_CTX_key_length(&cc->evp);
	if (klen > 0 && keylen != klen) {
		debug("cipher_init: set keylen (%d -> %d)", klen, keylen);
		if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0)
			fatal("cipher_init: set keylen failed (%d -> %d)",
			    klen, keylen);
	}
	if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0)
		fatal("cipher_init: EVP_CipherInit: set key failed for %s",
		    cipher->name);
#endif
}
Пример #2
0
void
cipher_init(CipherContext *cc, Cipher *cipher,
    const u_char *key, u_int keylen, const u_char *iv, u_int ivlen,
    int do_encrypt)
{
	static int dowarn = 1;
	const EVP_CIPHER *type;
	int klen;
	u_char *junk, *discard;

	if (cipher->number == SSH_CIPHER_DES) {
		if (dowarn) {
			error("Warning: use of DES is strongly discouraged "
			    "due to cryptographic weaknesses");
			dowarn = 0;
		}
		if (keylen > 8)
			keylen = 8;
	}
	cc->plaintext = (cipher->number == SSH_CIPHER_NONE);

	if (keylen < cipher->key_len)
		fatal("cipher_init: key length %d is insufficient for %s.",
		    keylen, cipher->name);
	if (iv != NULL && ivlen < cipher->block_size)
		fatal("cipher_init: iv length %d is insufficient for %s.",
		    ivlen, cipher->name);
	cc->cipher = cipher;

	type = (*cipher->evptype)();

	EVP_CIPHER_CTX_init(&cc->evp);
	if (EVP_CipherInit(&cc->evp, type, NULL, __UNCONST(iv),
	    (do_encrypt == CIPHER_ENCRYPT)) == 0)
		fatal("cipher_init: EVP_CipherInit failed for %s",
		    cipher->name);
	klen = EVP_CIPHER_CTX_key_length(&cc->evp);
	if (klen > 0 && keylen != (u_int)klen) {
		debug2("cipher_init: set keylen (%d -> %d)", klen, keylen);
		if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0)
			fatal("cipher_init: set keylen failed (%d -> %d)",
			    klen, keylen);
	}
	if (EVP_CipherInit(&cc->evp, NULL, __UNCONST(key), NULL, -1) == 0)
		fatal("cipher_init: EVP_CipherInit: set key failed for %s",
		    cipher->name);

	if (cipher->discard_len > 0) {
		junk = xmalloc(cipher->discard_len);
		discard = xmalloc(cipher->discard_len);
		if (EVP_Cipher(&cc->evp, discard, junk,
		    cipher->discard_len) == 0)
			fatal("evp_crypt: EVP_Cipher failed during discard");
		memset(discard, 0, cipher->discard_len);
		xfree(junk);
		xfree(discard);
	}
}
Пример #3
0
int
_libssh2_cipher_init(_libssh2_cipher_ctx * h,
                     _libssh2_cipher_type(algo),
                     unsigned char *iv, unsigned char *secret, int encrypt)
{
#ifdef HAVE_OPAQUE_STRUCTS
    *h = EVP_CIPHER_CTX_new();
    return !EVP_CipherInit(*h, algo(), secret, iv, encrypt);
#else
    EVP_CIPHER_CTX_init(h);
    return !EVP_CipherInit(h, algo(), secret, iv, encrypt);
#endif
}
Пример #4
0
/*
 * this will adjust ndo_packetp and ndo_snapend to new buffer!
 */
int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo,
				      int initiator,
				      u_char spii[8], u_char spir[8],
				      __capability u_char *buf,
				      packetbody_t end)
{
	struct sa_list *sa;
	__capability const u_char *iv;
	int len;
	EVP_CIPHER_CTX ctx;

	/* initiator arg is any non-zero value */
	if(initiator) initiator=1;
				       
	/* see if we can find the SA, and if so, decode it */
	for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) {
		if (sa->spi == 0
		    && initiator == sa->initiator
		    && memcmp(spii, sa->spii, 8) == 0
		    && memcmp(spir, sa->spir, 8) == 0)
			break;
	}

	if(sa == NULL) return 0;
	if(sa->evp == NULL) return 0;

	/*
	 * remove authenticator, and see if we still have something to
	 * work with
	 */
	end = end - sa->authlen;
	iv  = buf;
	buf = buf + sa->ivlen;
	len = end-buf;

	if(end <= buf) return 0;

	memset(&ctx, 0, sizeof(ctx));
	if (EVP_CipherInit(&ctx, sa->evp, sa->secret, NULL, 0) < 0)
		(*ndo->ndo_warning)(ndo, "espkey init failed");
	EVP_CipherInit(&ctx, NULL, NULL, iv, 0);
	EVP_Cipher(&ctx, buf, buf, len);
	EVP_CIPHER_CTX_cleanup(&ctx);

	/* XXX-BD: should create new capability on CHERI */
	ndo->ndo_packetp = buf;
	ndo->ndo_snapend = end;

	return 1;
	
}
Пример #5
0
int
tls_process_record_data(struct SSLConnection *conn, const opaque *fragment,
                        const int len, uint8_t **out, uint32_t *outl)
{
    EVP_CIPHER_CTX *evp;
    uint8_t pad;
    size_t flen = len;

    tls_debug_print_hex("Ciphertext", fragment, len);

    if (conn->direction == 0) {
        evp = &conn->client_cipher_ctx;
    } else {
        evp = &conn->server_cipher_ctx;
    }

    // TLS 1.1 and later extract explicit IV
    if (conn->version >= 2 && len > 16) {
        if (conn->direction == 0) {
            EVP_CipherInit(evp, conn->ciph,
                           conn->key_material.client_write_key,
                           fragment, 0);
        } else {
            EVP_CipherInit(evp, conn->ciph,
                           conn->key_material.server_write_key,
                           fragment, 0);
        }
        flen -= 16;
        fragment += 16;
    }

    size_t dlen = len;
    uint8_t *decoded = sng_malloc(dlen);
    EVP_Cipher(evp, decoded, (unsigned char *) fragment, flen);
    tls_debug_print_hex("Plaintext", decoded, flen);

    // Get padding counter and remove from data
    pad = decoded[flen - 1];
    dlen = flen - (pad + 1);
    tls_debug_print_hex("Mac", decoded + (dlen - 20), 20);

    if ((int32_t)dlen > 0 && dlen <= *outl) {
        memcpy(*out, decoded, dlen);
        *outl = dlen - 20 /* Trailing MAC */;
    }

    // Clenaup decoded memory
    sng_free(decoded);
    return *outl;
}
Пример #6
0
static size_t csf_write_page(CSF_CTX *ctx, int pgno, void *data, size_t data_sz) {
  off_t start_offset = HDR_SZ + (pgno * ctx->page_sz);
  off_t cur_offset =  lseek(*ctx->fh, 0L, SEEK_CUR);
  int to_write = ctx->page_sz;
  size_t write_sz = 0;
  CSF_PAGE_HEADER header;

  assert(data_sz <= ctx->data_sz);

  header.data_sz = data_sz;

  if(cur_offset != start_offset) { /* if not in proper position for page, seek there */
    cur_offset = lseek(*ctx->fh, start_offset, SEEK_SET);
  }
  
  RAND_pseudo_bytes(ctx->page_buffer, ctx->iv_sz);

  memcpy(ctx->scratch_buffer, &header, sizeof(header));
  memcpy(ctx->scratch_buffer + ctx->page_header_sz, data, data_sz);

  /* normally this would encrypt here */
  if(ctx->encrypted) {
    EVP_CIPHER_CTX ectx;
    void *out_ptr =  ctx->page_buffer + ctx->iv_sz;
    int out_sz, cipher_sz = 0;

    EVP_CipherInit(&ectx, CIPHER, NULL, NULL, 1);
    EVP_CIPHER_CTX_set_padding(&ectx, 0);
    EVP_CipherInit(&ectx, NULL, ctx->key_data, ctx->page_buffer, 1);
    EVP_CipherUpdate(&ectx, out_ptr + cipher_sz, &out_sz, ctx->scratch_buffer, ctx->page_header_sz + ctx->data_sz);
    cipher_sz += out_sz;
    EVP_CipherFinal(&ectx, out_ptr + cipher_sz, &out_sz);
    cipher_sz += out_sz;
    EVP_CIPHER_CTX_cleanup(&ectx);
    assert(cipher_sz == (ctx->page_header_sz + ctx->data_sz));
  } else {
    memcpy(ctx->page_buffer + ctx->iv_sz, ctx->scratch_buffer, ctx->page_header_sz + ctx->data_sz);
  }

  for(;write_sz < to_write;) { /* FIXME - error handling */ 
    size_t bytes_write = write(*ctx->fh, ctx->page_buffer + write_sz, to_write - write_sz);
    write_sz += bytes_write;
  }  
  
  TRACE6("csf_write_page(%d,%d,x,%d), cur_offset=%d, write_sz= %d\n", *ctx->fh, pgno, data_sz, cur_offset, write_sz);

  return data_sz;
}
Пример #7
0
int
ssh_EVP_CipherInit(EVP_CIPHER_CTX *evp, const EVP_CIPHER *type,
    unsigned char *key, unsigned char *iv, int enc)
{
	EVP_CipherInit(evp, type, key, iv, enc);
	return 1;
}
Пример #8
0
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) {
  EVP_CIPHER_CTX ectx;
  int tmp_csz, csz;
 
  EVP_CipherInit(&ectx, ((openssl_ctx *)ctx)->evp_cipher, NULL, NULL, mode);
  EVP_CIPHER_CTX_set_padding(&ectx, 0); // no padding
  EVP_CipherInit(&ectx, NULL, key, iv, mode);
  EVP_CipherUpdate(&ectx, out, &tmp_csz, in, in_sz);
  csz = tmp_csz;  
  out += tmp_csz;
  EVP_CipherFinal(&ectx, out, &tmp_csz);
  csz += tmp_csz;
  EVP_CIPHER_CTX_cleanup(&ectx);
  assert(in_sz == csz);
  return SQLITE_OK; 
}
Пример #9
0
void
cipher_ctx_init(EVP_CIPHER_CTX *ctx, const uint8_t *key, int key_len,
                const EVP_CIPHER *kt, int enc)
{
    ASSERT(NULL != kt && NULL != ctx);

    EVP_CIPHER_CTX_init(ctx);
    if (!EVP_CipherInit(ctx, kt, NULL, NULL, enc))
    {
        crypto_msg(M_FATAL, "EVP cipher init #1");
    }
#ifdef HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH
    if (!EVP_CIPHER_CTX_set_key_length(ctx, key_len))
    {
        crypto_msg(M_FATAL, "EVP set key size");
    }
#endif
    if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, enc))
    {
        crypto_msg(M_FATAL, "EVP cipher init #2");
    }

    /* make sure we used a big enough key */
    ASSERT(EVP_CIPHER_CTX_key_length(ctx) <= key_len);
}
Пример #10
0
void encryptfile(FILE * fpin,FILE* fpout,unsigned char* key, unsigned char* iv)
{
	//Using openssl EVP to encrypt a file

	
	const unsigned bufsize = 4096;
	unsigned char* read_buf = malloc(bufsize);
	unsigned char* cipher_buf ;
	unsigned blocksize;
	int out_len;

	EVP_CIPHER_CTX ctx;

	EVP_CipherInit(&ctx,EVP_aes_256_cbc(),key,iv,1);
	blocksize = EVP_CIPHER_CTX_block_size(&ctx);
	cipher_buf = malloc(bufsize+blocksize);

	// read file and write encrypted file until eof
	while(1)
	{
		int bytes_read = fread(read_buf,sizeof(unsigned char),bufsize,fpin);
		EVP_CipherUpdate(&ctx,cipher_buf,&out_len,read_buf, bytes_read);
		fwrite(cipher_buf,sizeof(unsigned char),out_len,fpout);
		if(bytes_read < bufsize)
		{
			break;//EOF
		}
	}

	EVP_CipherFinal(&ctx,cipher_buf,&out_len);
	fwrite(cipher_buf,sizeof(unsigned char),out_len,fpout);

	free(cipher_buf);
	free(read_buf);
}
Пример #11
0
int
_libssh2_cipher_init(_libssh2_cipher_ctx * h,
                     _libssh2_cipher_type(algo),
                     unsigned char *iv, unsigned char *secret, int encrypt)
{
    EVP_CIPHER_CTX_init(h);
    return !EVP_CipherInit(h, algo(), secret, iv, encrypt);
}
Пример #12
0
static size_t csf_read_page(CSF_CTX *ctx, int pgno, void *data) {
  off_t start_offset = HDR_SZ + (pgno * ctx->page_sz);
  off_t cur_offset =  lseek(*ctx->fh, 0L, SEEK_CUR);
  int to_read = ctx->page_sz;
  size_t read_sz = 0;
  CSF_PAGE_HEADER header;

  if(cur_offset != start_offset) { /* if not in proper position for page, seek there */
    cur_offset = lseek(*ctx->fh, start_offset, SEEK_SET);
  }
 
  /* FIXME - error handling */
  for(;read_sz < to_read;) {
    size_t bytes_read = read(*ctx->fh, ctx->page_buffer + read_sz, to_read - read_sz);
    read_sz += bytes_read;
    if(bytes_read < 0) {
      return 0;
    }
  }  

  if(ctx->encrypted) {
    EVP_CIPHER_CTX ectx;
    void *out_ptr =  ctx->scratch_buffer;
    int out_sz, cipher_sz = 0;

    EVP_CipherInit(&ectx, CIPHER, NULL, NULL, 0);
    EVP_CIPHER_CTX_set_padding(&ectx, 0);
    EVP_CipherInit(&ectx, NULL, ctx->key_data, ctx->page_buffer, 0);
    EVP_CipherUpdate(&ectx, out_ptr + cipher_sz, &out_sz, ctx->page_buffer + ctx->iv_sz, ctx->page_header_sz + ctx->data_sz);
    cipher_sz += out_sz;
    EVP_CipherFinal(&ectx, out_ptr + cipher_sz, &out_sz);
    cipher_sz += out_sz;
    EVP_CIPHER_CTX_cleanup(&ectx);
    assert(cipher_sz == (ctx->page_header_sz + ctx->data_sz));
  } else {
    memcpy(ctx->scratch_buffer, ctx->page_buffer + ctx->iv_sz, ctx->page_header_sz + ctx->data_sz);
  }

  memcpy(&header, ctx->scratch_buffer, sizeof(header));
  memcpy(data, ctx->scratch_buffer + ctx->page_header_sz, header.data_sz);

  TRACE6("csf_read_page(%d,%d,x), cur_offset=%d, read_sz=%d, return=%d\n", *ctx->fh, pgno, cur_offset, read_sz, data_sz);

  return header.data_sz;
}
Пример #13
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;
}
Пример #14
0
static int
ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
    int enc)
{
	struct ssh1_3des_ctx *c;
	u_char *k1, *k2, *k3;

	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
		if ((c = calloc(1, sizeof(*c))) == NULL)
			return 0;
		EVP_CIPHER_CTX_set_app_data(ctx, c);
	}
	if (key == NULL)
		return 1;
	if (enc == -1)
		enc = ctx->encrypt;
	k1 = k2 = k3 = __UNCONST(key);
	k2 += 8;
	if (EVP_CIPHER_CTX_key_length(ctx) >= 16+8) {
		if (enc)
			k3 += 16;
		else
			k1 += 16;
	}
	EVP_CIPHER_CTX_init(&c->k1);
	EVP_CIPHER_CTX_init(&c->k2);
	EVP_CIPHER_CTX_init(&c->k3);
	if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 ||
	    EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 ||
	    EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) {
		explicit_bzero(c, sizeof(*c));
		free(c);
		EVP_CIPHER_CTX_set_app_data(ctx, NULL);
		return 0;
	}
	return 1;
}
Пример #15
0
static int
ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
    int enc)
{
	struct ssh1_3des_ctx *c;
	u_char *k1, *k2, *k3;

	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
		c = xmalloc(sizeof(*c));
		EVP_CIPHER_CTX_set_app_data(ctx, c);
	}
	if (key == NULL)
		return (1);
	if (enc == -1)
		enc = ctx->encrypt;
	k1 = k2 = k3 = (u_char *) key;
	k2 += 8;
	if (EVP_CIPHER_CTX_key_length(ctx) >= 16+8) {
		if (enc)
			k3 += 16;
		else
			k1 += 16;
	}
	EVP_CIPHER_CTX_init(&c->k1);
	EVP_CIPHER_CTX_init(&c->k2);
	EVP_CIPHER_CTX_init(&c->k3);
	if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 ||
	    EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 ||
	    EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) {
		memset(c, 0, sizeof(*c));
		xfree(c);
		EVP_CIPHER_CTX_set_app_data(ctx, NULL);
		return (0);
	}
	return (1);
}
Пример #16
0
void openssl_evp_comcrypt()
{
	EVP_CIPHER_CTX ctx;
	int i, len1 = 0, len2 = 0, len3 = 0;
	unsigned char outs[MAX1_LEN], des[MAX1_LEN];
	unsigned char msg[MAX1_LEN] = "openssl common encrypt test";
	unsigned char iv[EVP_MAX_KEY_LENGTH], key[EVP_MAX_KEY_LENGTH];

	for (i = 0; i < 24; i++)
		key[i] = i;
	for (i = 0; i < 8; i++)
		iv[i] = i;
	memset(des, 0, sizeof(des));
	memset(outs, 0, sizeof(outs));

	EVP_CIPHER_CTX_init(&ctx);
	EVP_CipherInit(&ctx, EVP_des_ede3_cbc(), key, iv, 1);
	EVP_CipherUpdate(&ctx, outs, &len1, msg, strlen((char *)msg));
	EVP_CipherFinal(&ctx, outs + len1, &len3);
	len1 += len3;
	printf("\nEVP_COMEncry (%s) = ", msg);
	for (i = 0; i < len1; i++)
		printf("0x%.02x ", outs[i]);
	EVP_CIPHER_CTX_cleanup(&ctx);
	
	EVP_CIPHER_CTX_init(&ctx);
	EVP_CipherInit(&ctx, EVP_des_ede3_cbc(), key, iv, 0);
	EVP_CipherUpdate(&ctx, des, &len2, outs, len1);
	EVP_CipherFinal(&ctx, des + len2, &len3);
	len2 += len3;
	printf("\nEVP_COMDecry (");
	for (i = 0; i < len1; i++)
		printf("0x%.02x ", outs[i]);
	printf(") = %s\n", des);
	EVP_CIPHER_CTX_cleanup(&ctx);
}
Пример #17
0
/*
 * AES libcrypto
 */
static int sb_aes_init(struct sb_image_ctx *ictx, uint8_t *iv, int enc)
{
	EVP_CIPHER_CTX *ctx = &ictx->cipher_ctx;
	int ret;

	/* If there is no init vector, init vector is all zeroes. */
	if (!iv)
		iv = ictx->image_key;

	EVP_CIPHER_CTX_init(ctx);
	ret = EVP_CipherInit(ctx, EVP_aes_128_cbc(), ictx->image_key, iv, enc);
	if (ret == 1)
		EVP_CIPHER_CTX_set_padding(ctx, 0);
	return ret;
}
Пример #18
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;
}
Пример #19
0
void BIO_set_cipher(BIO *b, EVP_CIPHER *c, unsigned char *k, unsigned char *i,
	     int e)
	{
	BIO_ENC_CTX *ctx;

	if (b == NULL) return;

	if ((b->callback != NULL) &&
		(b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,0L) <= 0))
		return;

	b->init=1;
	ctx=(BIO_ENC_CTX *)b->ptr;
	EVP_CipherInit(&(ctx->cipher),c,k,i,e);
	
	if (b->callback != NULL)
		b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,1L);
	}
Пример #20
0
static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
{
    long num=0;
    int i=0,l;
    int key_bits;
    unsigned char iv[EVP_MAX_IV_LENGTH];

    if (type != NULL)
    {
        l=EVP_CIPHER_CTX_iv_length(c);
        i=ASN1_TYPE_get_int_octetstring(type,&num,iv,l);
        if (i != l)
            return(-1);
        key_bits =rc2_magic_to_meth((int)num);
        if (!key_bits)
            return(-1);
        if(i > 0) EVP_CipherInit(c, NULL, NULL, iv, -1);
        EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_RC2_KEY_BITS, key_bits, NULL);
        EVP_CIPHER_CTX_set_key_length(c, key_bits / 8);
    }
    return(i);
}
Пример #21
0
/*
 * Recieves AES-CBC-128 bit encrypted file from sender and decrypts the file
 * and saves it to the file specified in the arguments
 * SSL *conn                -> The SSL connection for the sender's node
 * const unsigned char *key -> The already instantiated AES Key for decryption
 * const char *fname        -> The name of the file to be stored
 * returns the total amount of bytes read and decrypted
 */
ssize_t crypto_recv_file(SSL *conn, const unsigned char *key, const char *fname)
{
    int len, ciph_len, first = 0;
    size_t total = 0;
    unsigned char plaintxt[BUFFSIZE];
    unsigned char ciphtxt[BUFFSIZE];
    unsigned char iv[IV_LEN];
    EVP_CIPHER_CTX cntx;
    FILE *file;
    if((file = fopen(fname, "wb")) == nullptr) {
        return FILE_NOT_FOUND;
    }
    while ((len = (int)ssl_recv(conn,(char *)ciphtxt, sizeof(ciphtxt))-1) > 0) {
        if(!first) {
            memcpy(iv, ciphtxt+1, sizeof(iv));
            EVP_CipherInit(&cntx, EVP_aes_128_cbc(), key, iv, DECRYPT);
        }
        EVP_CipherUpdate(&cntx, plaintxt, &ciph_len, ciphtxt+1, len);
        total += fwrite(plaintxt+(first?0:16), 1,
                        (size_t)ciph_len-(first?0:16), file);

        /* Last transmission of the file */
        if(len < BUFFSIZE-1) break;
        first++;
    }
    if (len < 0) goto err;
    EVP_CipherFinal(&cntx, plaintxt, &ciph_len);
    total+=fwrite(plaintxt, 1, (size_t)ciph_len, file);
    EVP_CIPHER_CTX_cleanup(&cntx);
    WAITFORACK(conn);
    fclose(file);
    return total;

    err:
    perror("GOTHERE");
    EVP_CIPHER_CTX_cleanup(&cntx);
    die_with_err("send() failed");
    return 1;
}
Пример #22
0
/* FIXME */
static int
_SSL_do_cipher(char *buf, int buf_len, char *key, int operation, char **pt)
{
	EVP_CIPHER_CTX ectx;
        unsigned char iv[EVP_MAX_IV_LENGTH];
	char ebuf[MAXBLK];
	int ebuflen;
	int n;
	int i;


	memset(iv, 0, EVP_MAX_IV_LENGTH);
	EVP_CipherInit(&ectx, ALG, key, iv, operation);

	*pt = mmalloc(buf_len + EVP_CIPHER_CTX_block_size(&ectx));	/* + PAD */

	i = 0;
	while (buf_len - i > 0) {
		n = (buf_len - i < MAXBLK) ? buf_len - i : MAXBLK;
		EVP_CipherUpdate(&ectx, ebuf, &ebuflen, buf + i, n);
		printf("EVP_CipherUpdate[%d] ebl %d i %d T %d (%d)\n", operation, ebuflen, i, buf_len, n);

		if (!ebuflen)	/* last block needs padding */
			break;

		memcpy(*pt + i, ebuf, ebuflen);
		i += ebuflen;
break;
	}
	/* append/check CRC block */
        if (!EVP_CipherFinal(&ectx, ebuf, &ebuflen))
		fprintf(stderr, "_SSL_do_cipher :: EVP_CipherFinal failed\n");
	memcpy(*pt + i, ebuf, ebuflen);
	i += ebuflen;
	printf("EVP_CipherFinal %d (%d)\n", ebuflen, i);

	return (i);
}
Пример #23
0
int EVP_cipher(const char *passw, int cbpass, char *strin, int cbstr, int op, const char *cipher)
{
	const EVP_CIPHER * enc;
	if (cipher && *cipher) {
		if (!myEvpMap.Find(cipher,enc))
			return CIPHER_INVALID;
	} else 
		enc = EVP_des_ede_cbc();

	unsigned char key[EVP_MAX_KEY_LENGTH];
	unsigned char iv[EVP_MAX_IV_LENGTH];
	EVP_CIPHER_CTX ctx;

	EVP_BytesToKey(enc,EVP_md5(),NULL,(unsigned char *)passw,cbpass,1,key,iv);
	EVP_CIPHER_CTX_init(&ctx);
	EVP_CipherInit(&ctx,enc,key,iv,op);
	
	unsigned char out[CIPHER_BLOCK+EVP_MAX_IV_LENGTH];
	int outl;

	unsigned char *in = (unsigned char *) strin;
	unsigned char *endp = in + cbstr - CIPHER_BLOCK;
	unsigned char *outp = in;

	while (in < endp)	{
		EVP_CipherUpdate(&ctx,out,&outl,in,CIPHER_BLOCK);
		memcpy(outp, out, outl); outp += outl;
		in += CIPHER_BLOCK;
	}
	EVP_CipherUpdate(&ctx,out,&outl,in,endp+CIPHER_BLOCK-in);
	memcpy(outp, out, outl); outp += outl;

	EVP_CipherFinal(&ctx,out,&outl);
	memcpy(outp, out, outl); outp += outl;

	EVP_CIPHER_CTX_cleanup(&ctx);
	return (char *)outp-strin;
}
Пример #24
0
/*
 * Sends AES-CBC-128 bit encrypted file to the receiver
 * SSL *conn                -> The SSL connection of the recipient
 * const char *fname        -> The name of the file to send
 * const unsigned char *key -> The already instantiated AES Key for decryption
 * const unsigned char *iv  -> The initialization vector for CBC that was
 *                             received from the sender
 * returns the total amount of bytes sent and encrypted
 */
ssize_t crypto_send_file(SSL *conn, const char *fname, const unsigned char *key,
                         const unsigned char *iv)
{
    int len, ciph_len=0, first=0;
    ssize_t total = 0;
    unsigned char plaintxt[BUFFSIZE];
    unsigned char ciphtxt[BUFFSIZE];
    FILE *file;
    if((file = fopen(fname, "rb")) == nullptr) return FILE_NOT_FOUND;

    EVP_CIPHER_CTX cntx;
    EVP_CipherInit(&cntx, EVP_aes_128_cbc(), key, iv, ENCRYPT);
    memcpy(plaintxt, iv, IV_LEN);
    while ((len = (int)fread(plaintxt+(first?0:16), sizeof(char),
                             sizeof(ciphtxt)-(first?0:16)-1, file)) > 0) {
        EVP_CipherUpdate(&cntx, ciphtxt+1,&ciph_len,plaintxt,len+(first?0:16));
        ssl_send(conn, (char *)ciphtxt, (size_t)ciph_len+1);
        /* Last transmission of the file */
        if(len < BUFFSIZE-1) {
            if(!first && len < BUFFSIZE-16-1) break;
        }
        first++;
    }
    ERRCHK(len, ==, -1, "send() failed");
    EVP_CipherFinal(&cntx, ciphtxt+1, &ciph_len);
    ssl_send(conn, (char *)ciphtxt, (size_t)ciph_len+1);
    SENDFIN(conn);
    ERRCHK(len, ==, -1, "send() failed");
    EVP_CIPHER_CTX_cleanup(&cntx);
    fclose(file);
    return total;

    seterrhandle(err);
    EVP_CIPHER_CTX_cleanup(&cntx);
    die_with_err(errmsg);
    return 1;
}
Пример #25
0
static EVP_CIPHER_CTX *get_cipher(SEXP sKey, SEXP sCipher, int enc, int *transient) {
    EVP_CIPHER_CTX *ctx;
    PKI_init();
    if (inherits(sKey, "symmeric.cipher")) {
	if (transient) transient[0] = 0;
	return (EVP_CIPHER_CTX*) R_ExternalPtrAddr(sCipher);
    }	
    if (TYPEOF(sKey) != RAWSXP && (TYPEOF(sKey) != STRSXP || LENGTH(sKey) < 1))
	Rf_error("invalid key object");
    else {
	const char *cipher, *c_key;
	int key_len;
	const EVP_CIPHER *type;
	if (TYPEOF(sCipher) != STRSXP || LENGTH(sCipher) != 1)
	    Rf_error("non-RSA key and no cipher is specified");
	cipher = CHAR(STRING_ELT(sCipher, 0));
	if (strlen(cipher) > sizeof(cipher_name) - 1)
	    Rf_error("invalid cipher name");
	{
	    char *c = cipher_name;
	    while (*cipher) {
		if ((*cipher >= 'a' && *cipher <= 'z') || (*cipher >= '0' && *cipher <= '9'))
		    *(c++) = *cipher;
		else if (*cipher >= 'A' && *cipher <= 'Z')
		    *(c++) = *cipher + 32;
		cipher++;
	    }
	    *c = 0;
	    cipher = (const char*) cipher_name;
	}
	if (!strcmp(cipher, "aes128") || !strcmp(cipher, "aes128cbc"))
	    type = EVP_aes_128_cbc();
	else if (!strcmp(cipher, "aes128ecb"))
	    type = EVP_aes_128_ecb();
	else if (!strcmp(cipher, "aes128ofb"))
	    type = EVP_aes_128_ofb();
	else if (!strcmp(cipher, "aes256") || !strcmp(cipher, "aes256cbc"))
	    type = EVP_aes_256_cbc();
	else if (!strcmp(cipher, "aes256ecb"))
	    type = EVP_aes_256_ecb();
	else if (!strcmp(cipher, "aes256ofb"))
	    type = EVP_aes_256_ofb();
	else if (!strcmp(cipher, "blowfish") || !strcmp(cipher, "bfcbc"))
	    type = EVP_bf_cbc();
	else if (!strcmp(cipher, "bfecb"))
	    type = EVP_bf_ecb();
	else if (!strcmp(cipher, "bfofb"))
	    type = EVP_bf_ofb();
	else if (!strcmp(cipher, "bfcfb"))
	    type = EVP_bf_cfb();
	else Rf_error("unknown cipher `%s'", CHAR(STRING_ELT(sCipher, 0)));
	if (TYPEOF(sKey) == STRSXP) {
	    c_key = CHAR(STRING_ELT(sKey, 0));
	    key_len = strlen(c_key);
	} else {
	    c_key = (const char*) RAW(sKey);
	    key_len = LENGTH(sKey);
	}
	if (key_len < EVP_CIPHER_key_length(type))
	    Rf_error("key is too short (%d bytes) for the cipher - need %d bytes", key_len, EVP_CIPHER_key_length(type));
	ctx = (EVP_CIPHER_CTX*) malloc(sizeof(*ctx));
	if (!ctx)
	    Rf_error("cannot allocate memory for cipher");
	if (!EVP_CipherInit(ctx, type, (unsigned char*) c_key, 0, enc)) {
	    free(ctx);
	    Rf_error("%s", ERR_error_string(ERR_get_error(), NULL));
	}
	if (transient) transient[0] = 1;
	return ctx;
    }
}
Пример #26
0
int
cipher_ctx_reset (EVP_CIPHER_CTX *ctx, uint8_t *iv_buf)
{
  return EVP_CipherInit (ctx, NULL, NULL, iv_buf, -1);
}
Пример #27
0
int
cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher,
    const u_char *key, u_int keylen, const u_char *iv, u_int ivlen,
    int do_encrypt)
{
	struct sshcipher_ctx *cc = NULL;
	int ret = SSH_ERR_INTERNAL_ERROR;
#ifdef WITH_OPENSSL
	const EVP_CIPHER *type;
	int klen;
	u_char *junk, *discard;
#endif

	*ccp = NULL;
	if ((cc = calloc(sizeof(*cc), 1)) == NULL)
		return SSH_ERR_ALLOC_FAIL;

	if (cipher->number == SSH_CIPHER_DES) {
		if (keylen > 8)
			keylen = 8;
	}

	cc->plaintext = (cipher->number == SSH_CIPHER_NONE);
	cc->encrypt = do_encrypt;

	if (keylen < cipher->key_len ||
	    (iv != NULL && ivlen < cipher_ivlen(cipher))) {
		ret = SSH_ERR_INVALID_ARGUMENT;
		goto out;
	}

	cc->cipher = cipher;
	if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
		ret = chachapoly_init(&cc->cp_ctx, key, keylen);
		goto out;
	}
#ifndef WITH_OPENSSL
	if ((cc->cipher->flags & CFLAG_AESCTR) != 0) {
		aesctr_keysetup(&cc->ac_ctx, key, 8 * keylen, 8 * ivlen);
		aesctr_ivsetup(&cc->ac_ctx, iv);
		ret = 0;
		goto out;
	}
	if ((cc->cipher->flags & CFLAG_NONE) != 0) {
		ret = 0;
		goto out;
	}
	ret = SSH_ERR_INVALID_ARGUMENT;
	goto out;
#else /* WITH_OPENSSL */
	type = (*cipher->evptype)();
	if ((cc->evp = EVP_CIPHER_CTX_new()) == NULL) {
		ret = SSH_ERR_ALLOC_FAIL;
		goto out;
	}
	if (EVP_CipherInit(cc->evp, type, NULL, (const u_char *)iv,
	    (do_encrypt == CIPHER_ENCRYPT)) == 0) {
		ret = SSH_ERR_LIBCRYPTO_ERROR;
		goto out;
	}
	if (cipher_authlen(cipher) &&
	    !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_IV_FIXED,
	    -1, __UNCONST(iv))) {
		ret = SSH_ERR_LIBCRYPTO_ERROR;
		goto out;
	}
	klen = EVP_CIPHER_CTX_key_length(cc->evp);
	if (klen > 0 && keylen != (u_int)klen) {
		if (EVP_CIPHER_CTX_set_key_length(cc->evp, keylen) == 0) {
			ret = SSH_ERR_LIBCRYPTO_ERROR;
			goto out;
		}
	}
	if (EVP_CipherInit(cc->evp, NULL, __UNCONST(key), NULL, -1) == 0) {
		ret = SSH_ERR_LIBCRYPTO_ERROR;
		goto out;
	}

	if (cipher->discard_len > 0) {
		if ((junk = malloc(cipher->discard_len)) == NULL ||
		    (discard = malloc(cipher->discard_len)) == NULL) {
			free(junk);
			ret = SSH_ERR_ALLOC_FAIL;
			goto out;
		}
		ret = EVP_Cipher(cc->evp, discard, junk, cipher->discard_len);
		explicit_bzero(discard, cipher->discard_len);
		free(junk);
		free(discard);
		if (ret != 1) {
			ret = SSH_ERR_LIBCRYPTO_ERROR;
			goto out;
		}
	}
	ret = 0;
#endif /* WITH_OPENSSL */
 out:
	if (ret == 0) {
		/* success */
		*ccp = cc;
	} else {
		if (cc != NULL) {
#ifdef WITH_OPENSSL
			if (cc->evp != NULL)
				EVP_CIPHER_CTX_free(cc->evp);
#endif /* WITH_OPENSSL */
			explicit_bzero(cc, sizeof(*cc));
			free(cc);
		}
	}
	return ret;
}
X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
				 unsigned char *salt, int saltlen)
{
	X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
	int alg_nid;
	EVP_CIPHER_CTX ctx;
	unsigned char iv[EVP_MAX_IV_LENGTH];
	PBKDF2PARAM *kdf = NULL;
	PBE2PARAM *pbe2 = NULL;
	ASN1_OCTET_STRING *osalt = NULL;
	ASN1_OBJECT *obj;

	alg_nid = EVP_CIPHER_type(cipher);
	if(alg_nid == NID_undef) {
		ASN1err(ASN1_F_PKCS5_PBE2_SET,
				ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
		goto err;
	}
	obj = OBJ_nid2obj(alg_nid);

	if(!(pbe2 = PBE2PARAM_new())) goto merr;

	/* Setup the AlgorithmIdentifier for the encryption scheme */
	scheme = pbe2->encryption;

	scheme->algorithm = obj;
	if(!(scheme->parameter = ASN1_TYPE_new())) goto merr;

	/* Create random IV */
	if (RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0)
		goto err;

	/* Dummy cipherinit to just setup the IV */
	EVP_CipherInit(&ctx, cipher, NULL, iv, 0);
	if(EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) {
		ASN1err(ASN1_F_PKCS5_PBE2_SET,
					ASN1_R_ERROR_SETTING_CIPHER_PARAMS);
		goto err;
	}
	EVP_CIPHER_CTX_cleanup(&ctx);

	if(!(kdf = PBKDF2PARAM_new())) goto merr;
	if(!(osalt = M_ASN1_OCTET_STRING_new())) goto merr;

	if (!saltlen) saltlen = PKCS5_SALT_LEN;
	if (!(osalt->data = OPENSSL_malloc (saltlen))) goto merr;
	osalt->length = saltlen;
	if (salt) memcpy (osalt->data, salt, saltlen);
	else if (RAND_pseudo_bytes (osalt->data, saltlen) < 0) goto merr;

	if(iter <= 0) iter = PKCS5_DEFAULT_ITER;
	if(!ASN1_INTEGER_set(kdf->iter, iter)) goto merr;

	/* Now include salt in kdf structure */
	kdf->salt->value.octet_string = osalt;
	kdf->salt->type = V_ASN1_OCTET_STRING;
	osalt = NULL;

	/* If its RC2 then we'd better setup the key length */

	if(alg_nid == NID_rc2_cbc) {
		if(!(kdf->keylength = M_ASN1_INTEGER_new())) goto merr;
		if(!ASN1_INTEGER_set (kdf->keylength,
				 EVP_CIPHER_key_length(cipher))) goto merr;
	}

	/* prf can stay NULL because we are using hmacWithSHA1 */

	/* Now setup the PBE2PARAM keyfunc structure */

	pbe2->keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2);

	/* Encode PBKDF2PARAM into parameter of pbe2 */

	if(!(pbe2->keyfunc->parameter = ASN1_TYPE_new())) goto merr;

	if(!ASN1_pack_string(kdf, (i2d_func_t)i2d_PBKDF2PARAM,
			 &pbe2->keyfunc->parameter->value.sequence)) goto merr;
	pbe2->keyfunc->parameter->type = V_ASN1_SEQUENCE;

	PBKDF2PARAM_free(kdf);
	kdf = NULL;

	/* Now set up top level AlgorithmIdentifier */

	if(!(ret = X509_ALGOR_new())) goto merr;
	if(!(ret->parameter = ASN1_TYPE_new())) goto merr;

	ret->algorithm = OBJ_nid2obj(NID_pbes2);

	/* Encode PBE2PARAM into parameter */

	if(!ASN1_pack_string(pbe2, (i2d_func_t)i2d_PBE2PARAM,
				 &ret->parameter->value.sequence)) goto merr;
	ret->parameter->type = V_ASN1_SEQUENCE;

	PBE2PARAM_free(pbe2);
	pbe2 = NULL;

	return ret;

	merr:
	ASN1err(ASN1_F_PKCS5_PBE2_SET,ERR_R_MALLOC_FAILURE);

	err:
	PBE2PARAM_free(pbe2);
	/* Note 'scheme' is freed as part of pbe2 */
	M_ASN1_OCTET_STRING_free(osalt);
	PBKDF2PARAM_free(kdf);
	X509_ALGOR_free(kalg);
	X509_ALGOR_free(ret);

	return NULL;

}
Пример #29
0
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);
	}
}
Пример #30
0
static int
do_cipher(ClipMachine *mp, int operation)
{
	const EVP_CIPHER *cipher = 0;
	const EVP_MD *digest = 0;
	char *cipher_name, *digest_name;
	char *key_str, *data, *iv_str, *data_ptr;
	int key_len=0, data_len=0, iv_len=0;
	EVP_CIPHER_CTX ectx;
	unsigned char iv[EVP_MAX_IV_LENGTH];
	unsigned char key[EVP_MAX_KEY_LENGTH];
	char ebuf[BLOCK_SIZE + 8];
	unsigned int ebuflen;
	char *obuf = 0;
	unsigned int olen = 0;
	int l;

	crypto_init();

	if (mp->argc<2)
		return EG_ARG;

	cipher_name = _clip_parc(mp, 3);
	if (!cipher_name)
		cipher_name = "des-ede3-cbc";

	digest_name = _clip_parc(mp, 4);
	if (!digest_name)
		digest_name  = "md5";

	data = _clip_parcl(mp, 1, &data_len);
	if (!data)
		return EG_ARG;

	key_str = _clip_parcl(mp, 2, &key_len);
	if (!key_str)
		return EG_ARG;

	memset(iv, 0, sizeof(iv));
	memset(key, 0, sizeof(key));

	iv_str = _clip_parcl(mp, 5, &iv_len);
	if (iv_str)
	{
		if (iv_len>sizeof(iv))
			iv_len = sizeof(iv);
		memcpy(iv, iv_str, iv_len);
	}

	cipher = EVP_get_cipherbyname(cipher_name);
	if (!cipher)
		return EG_ARG;

	digest = EVP_get_digestbyname(digest_name);
	if (!digest)
		return EG_ARG;


	EVP_BytesToKey(cipher, (EVP_MD*)digest, (const unsigned char *)"clip", (const unsigned char *)key_str, key_len, 1, key, iv);
	EVP_CipherInit(&ectx, cipher, key, iv, operation);

	for(l=0, data_ptr=data; l<data_len; )
	{
		int ll = data_len - l;

		if (ll > BLOCK_SIZE)
			ll = BLOCK_SIZE;

		ebuflen = sizeof(ebuf);
		EVP_CipherUpdate(&ectx, (unsigned char *)ebuf, (int *)&ebuflen, (unsigned char *)data_ptr, ll);

		obuf = (char*) realloc( obuf, olen + ebuflen);
		memcpy(obuf + olen, ebuf, ebuflen);
		olen += ebuflen;

		l += ll;
		data_ptr += ll;
	}

	EVP_CipherFinal(&ectx, (unsigned char *)ebuf, (int *)&ebuflen);

	obuf = (char*) realloc( obuf, olen + ebuflen + 1);
	memcpy(obuf + olen, ebuf, ebuflen);
	olen += ebuflen;
	obuf[olen] = 0;

	_clip_retcn_m(mp, obuf, olen);

	return 0;
}