Example #1
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);
}
static int
do_cipher(EVP_CIPHER_CTX *cipher_ctx, const u8 *in, size_t in_len,
		u8 **out, size_t *out_len)
{
	const u8 *end;
	u8	*p;
	size_t	bl, done, left, total;

	*out = p = (u8 *) malloc(in_len + EVP_CIPHER_CTX_key_length(cipher_ctx));
	*out_len = total = 0;

	bl = EVP_CIPHER_CTX_block_size(cipher_ctx);
	end = in + in_len;
	while (in < end) {
		if ((left = end - in) > bl)
			left = bl;
		if (!EVP_CipherUpdate(cipher_ctx,
					p + total, (int *) &done,
					(u8 *) in, (int)left))
			goto fail;
		total += done;
		in += left;
	}
	if (1 || total < in_len) {
		if (!EVP_CipherFinal(cipher_ctx, p + total, (int *) &done))
			goto fail;
		total += done;
	}
	*out_len = total;
	return 0;

fail:	free(p);
	return SC_ERROR_INTERNAL;
}
Example #3
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);
}
Example #4
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;
}
Example #5
0
SEXP PKI_encrypt(SEXP what, SEXP sKey, SEXP sCipher) {
    SEXP res;
    EVP_PKEY *key;
    RSA *rsa;
    int len;
    if (TYPEOF(what) != RAWSXP)
	Rf_error("invalid payload to sign - must be a raw vector");
    if (!inherits(sKey, "public.key") && !inherits(sKey, "private.key")) {
	int transient_cipher = 0;
	EVP_CIPHER_CTX *ctx = get_cipher(sKey, sCipher, 1, &transient_cipher);
	int block_len = EVP_CIPHER_CTX_block_size(ctx);
	int padding = LENGTH(what) % block_len;
	/* Note: padding is always required, so if the last block is full, there
	   must be an extra block added at the end */
	padding = block_len - padding;
	/* FIXME: ctx will leak on alloc errors for transient ciphers - wrap them first */
	res = allocVector(RAWSXP, len = (LENGTH(what) + padding));
	if (!EVP_CipherUpdate(ctx, RAW(res), &len, RAW(what), LENGTH(what))) {
	    if (transient_cipher) {
		EVP_CIPHER_CTX_cleanup(ctx);
		free(ctx);
	    }
	    Rf_error("%s", ERR_error_string(ERR_get_error(), NULL));
	}
	if (len < LENGTH(res))
	    EVP_CipherFinal(ctx, RAW(res) + len, &len);
	if (transient_cipher) {
	    EVP_CIPHER_CTX_cleanup(ctx);
	    free(ctx);
	}
	return res;
    }

    key = (EVP_PKEY*) R_ExternalPtrAddr(sKey);
    if (!key)
	Rf_error("NULL key");
    if (EVP_PKEY_type(key->type) != EVP_PKEY_RSA)
	Rf_error("Sorry only RSA keys are supported at this point");
    rsa = EVP_PKEY_get1_RSA(key);
    if (!rsa)
	Rf_error("%s", ERR_error_string(ERR_get_error(), NULL));
    len = RSA_public_encrypt(LENGTH(what), RAW(what), (unsigned char*) buf, rsa, RSA_PKCS1_PADDING);
    if (len < 0)
	Rf_error("%s", ERR_error_string(ERR_get_error(), NULL));
    res = allocVector(RAWSXP, len);
    memcpy(RAW(res), buf, len);
    return res;
}
Example #6
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; 
}
Example #7
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;
}
Example #8
0
SEXP PKI_decrypt(SEXP what, SEXP sKey, SEXP sCipher) {
    SEXP res;
    EVP_PKEY *key;
    RSA *rsa;
    int len;
    if (TYPEOF(what) != RAWSXP)
	Rf_error("invalid payload to sign - must be a raw vector");
    PKI_init();
    if (!inherits(sKey, "private.key")) {
	int transient_cipher = 0, fin = 0;
	EVP_CIPHER_CTX *ctx = get_cipher(sKey, sCipher, 0, &transient_cipher);
	/* FIXME: ctx will leak on alloc errors for transient ciphers - wrap them first */
	res = allocVector(RAWSXP, len = LENGTH(what));
	if (!EVP_CipherUpdate(ctx, RAW(res), &len, RAW(what), LENGTH(what))) {
	    if (transient_cipher) {
		EVP_CIPHER_CTX_cleanup(ctx);
		free(ctx);
	    }
	    Rf_error("%s", ERR_error_string(ERR_get_error(), NULL));
	}
	if (EVP_CipherFinal(ctx, RAW(res) + len, &fin))
	    len += fin;
	if (len < LENGTH(res))
	    SETLENGTH(res, len);
	if (transient_cipher) {
	    EVP_CIPHER_CTX_cleanup(ctx);
	    free(ctx);
	}
	return res;
    }
    key = (EVP_PKEY*) R_ExternalPtrAddr(sKey);
    if (!key)
	Rf_error("NULL key");
    if (EVP_PKEY_type(key->type) != EVP_PKEY_RSA)
	Rf_error("Sorry only RSA keys are supported at this point");
    rsa = EVP_PKEY_get1_RSA(key);
    if (!rsa)
	Rf_error("%s", ERR_error_string(ERR_get_error(), NULL));
    len = RSA_private_decrypt(LENGTH(what), RAW(what), (unsigned char*) buf, rsa, RSA_PKCS1_PADDING);
    if (len < 0)
	Rf_error("%s", ERR_error_string(ERR_get_error(), NULL));
    res = allocVector(RAWSXP, len);
    memcpy(RAW(res), buf, len);
    return res;
}
Example #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;
}
Example #10
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;
}
Example #11
0
File: ssl.c Project: UIKit0/picogui
/* 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);
}
Example #12
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;
}
Example #13
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;
}
Example #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;
}
Example #15
0
    len -= skip;
    if (len == 0)
        return 0;
    int outlen = static_cast<int>(len) + m_blocksize;
    SSL_CHECK(EVP_CipherUpdate(&m_ctx,
        (unsigned char *)dst.writeBuffer(len + m_blocksize, true).iov_base, &outlen,
        (unsigned char *)src.readBuffer(len + skip, true).iov_base + skip, static_cast<int>(len)));
    dst.produce(outlen);
    return outlen;
}

// finalizes the cipher and writes the last few bytes to dst
size_t CryptoStream::final(Buffer &dst)
{
    int outlen = m_blocksize;
    SSL_CHECK(EVP_CipherFinal(&m_ctx,
        (unsigned char *)dst.writeBuffer(m_blocksize, true).iov_base, &outlen));
    dst.produce(outlen);
    return outlen;
}

// writes and consumes entire buffer
void CryptoStream::write_buffer(Buffer &buffer)
{
    size_t to_write = buffer.readAvailable();
    while(to_write > 0) {
        size_t written = parent()->write(buffer, to_write);
        buffer.consume(written);
        to_write -= written;
    }
}
Example #16
0
int
cipher_ctx_final (EVP_CIPHER_CTX *ctx, uint8_t *dst, int *dst_len)
{
  return EVP_CipherFinal (ctx, dst, dst_len);
}
Example #17
0
char *SSL_encode(Boolean isdecrypt, char *ciphername,
                 const char *data, uint4 inlen,uint4 &outlen, //data to decrypt, length of that data, and pointer to descypted data length
                 const char *keystr, int4 keystrlen, Boolean ispassword, uint2 keylen,
                 const char *saltstr,  uint2 saltlen, const char *ivstr, uint2 ivlen)
{ //password or key, optional key length
	if (!InitSSLCrypt())
		return NULL;
#ifdef MCSSL

	// MW-2011-05-24: [[ Bug 9536 ]] The key length is a function of 'keylen' and for some ciphers
	//   can be larger than 32 bytes. For now, increase the buffer to 256 bytes given a maximum
	//   theoretical key length of 2048.
	uint1 iv[EVP_MAX_IV_LENGTH], key[256];
	if (keylen > 2048)
		return NULL;

	const EVP_CIPHER *cipher=EVP_get_cipherbyname(ciphername);

	uint1 operation = isdecrypt ? 0: 1;

	//get cipher object
	if (!cipher)
	{
		outlen = 789;
		return NULL;
	}

	static const char magic[]="Salted__";

	int4 res = 0;

	//set up cipher context
	EVP_CIPHER_CTX ctx;
	EVP_CIPHER_CTX_init(&ctx);
	//init context with cipher and specify operation
	if (EVP_CipherInit(&ctx, cipher,NULL, NULL, operation) == 0)
		return NULL;

	//try setting keylength if specified. This will fail for some ciphers.
	if (keylen && EVP_CIPHER_CTX_set_key_length(&ctx, keylen/8) == 0)
		return NULL;
	//get new keylength in bytes
	int4 curkeylength = EVP_CIPHER_CTX_key_length(&ctx);
	//zero key and iv
	memset(key,0,EVP_MAX_KEY_LENGTH);
	memset(iv,0,EVP_MAX_IV_LENGTH);
	//if password combine with salt value to generate key

	unsigned char saltbuf[PKCS5_SALT_LEN];
	memset(saltbuf,0,sizeof(saltbuf));

	char *tend = (char *)data + inlen;

	// MW-2004-12-02: Fix bug 2411 - a NULL salt should result in a random one being
	//    generated, if saltstr is NULL and saltlen is zero then the salt should
	//    be taken as being the empty string.
	if (ispassword)
	{
		if (saltstr == NULL)
			RAND_bytes(saltbuf, sizeof(saltbuf));
		else
			memcpy(saltbuf,saltstr,MCU_min(saltlen,PKCS5_SALT_LEN));

		// MW-2004-12-02: We should only do this if we are decrypting
		if (isdecrypt && inlen > sizeof(magic) && memcmp(data,magic,sizeof(magic)-1) == 0)
		{
			data += sizeof(magic) - 1;

			if (saltstr == NULL || saltlen == 0)
				memcpy(saltbuf,data,sizeof(saltbuf));

			data += sizeof(saltbuf);
		}

		curkeylength =	EVP_BytesToKey(cipher,EVP_md5(),(const unsigned char *)saltbuf,(unsigned char *)keystr,
		                              keystrlen,1,key,iv);
	}
	else
	{//otherwise copy to key
		if (keystrlen != curkeylength)
		{ //sanity check then passed wrong size for key
			outlen = 790;
			return NULL;
		}
		else
			memcpy(key,keystr,curkeylength);
	}

	if (ivstr != NULL && ivlen > 0)
	{
		memset(iv,0,EVP_MAX_IV_LENGTH);
		memcpy(iv,ivstr,MCU_min(ivlen,EVP_MAX_IV_LENGTH));
	}

	if (EVP_CipherInit(&ctx, NULL, key, iv, operation) == 0)
		return NULL;
	int4 tmp, ol;
	ol = 0;

	//allocate memory to hold encrypted/decrypted data + an extra block + null terminator for block ciphers.
	unsigned char *outdata = (unsigned char *)malloc(inlen + EVP_CIPHER_CTX_block_size(&ctx) + 1 + sizeof(magic) + sizeof(saltbuf));
	//do encryption/decryption
	if (outdata == NULL)
	{
		outlen = 791;
		return NULL;
	}

	// MW-2004-12-02: Only prepend the salt if we generated the key (i.e. password mode)
	if (!isdecrypt && ispassword)
	{
		memcpy(&outdata[ol],magic,sizeof(magic)-1);
		ol += sizeof(magic)-1;
		memcpy(&outdata[ol],saltbuf,sizeof(saltbuf));
		ol += sizeof(saltbuf);
	}


	// MW-2007-02-13: [[Bug 4258]] - SSL now fails an assertion if datalen == 0
	if (tend - data > 0)
	{
		if (EVP_CipherUpdate(&ctx,&outdata[ol],&tmp,(unsigned char *)data,tend-data) == 0)
		{
			delete outdata;
			return NULL;
		}
		ol += tmp;
	}

	//for padding
	if (EVP_CipherFinal(&ctx,&outdata[ol],&tmp) == 0)
	{
		delete outdata;
		return NULL;
	}
	outlen = ol + tmp;

	//cleam up context and return data
	EVP_CIPHER_CTX_cleanup(&ctx);
	outdata[outlen] = 0; //null terminate data

	return (char *)outdata;
#else
	return NULL;
#endif
}
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);
	}
}
Example #19
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;
}
Example #20
0
OsStatus OsEncryption::crypto(Direction direction)
{
    OsStatus retval = init(direction);

#if defined(OSENCRYPTION)
    if (retval == OS_SUCCESS)
    {
        if (sIgnoreEncryption)
        {
            memcpy(mResults, mData, mDataLen);
            mResultsLen = mDataLen;
        }
        else
        {
            retval = OS_FAILED;
            unsigned char *in = mData;
            int inLen = mDataLen;
            unsigned char *out = mResults;
            int outLen = 0;

            if (mHeaderLen > 0)
            {
                if (direction == ENCRYPT)
                {
                    // copy in header
                    memcpy(out, mHeader, mHeaderLen);
                    out += mHeaderLen;
                    outLen += mHeaderLen;
                }
                else
                {
                    // ignore header
                    in += mHeaderLen;
                    inLen -= mHeaderLen;
                }
            }

            int outLenPart1 = 0;
            if (EVP_CipherUpdate(&(mContext), out, &outLenPart1, in, inLen))
            {
                out += outLenPart1;
                int outLenPart2 = 0;
                if (EVP_CipherFinal(&(mContext), out, &outLenPart2))
                {
                    outLen += outLenPart1 + outLenPart2;
                    retval = OS_SUCCESS;
                    mResults[outLen] = 0;
                    mResultsLen = outLen;
                }
            }
        }
    }

    if (retval != OS_SUCCESS)
    {
        openSslError();
        release();
    }

#endif
   return retval;
}
Example #21
0
static LUA_FUNCTION(openssl_evp_cipher)
{
  const EVP_CIPHER* cipher = NULL;
  if (lua_istable(L, 1))
  {
    if (lua_getmetatable(L, 1) && lua_equal(L, 1, -1))
    {
      lua_pop(L, 1);
      lua_remove(L, 1);
    }
    else
      luaL_error(L, "call function with invalid state");
  }

  cipher = get_cipher(L, 1, NULL);

  if (cipher)
  {
    int enc = lua_toboolean(L, 2);
    size_t input_len = 0;
    const char *input = luaL_checklstring(L, 3, &input_len);
    size_t key_len = 0;
    const char *key = luaL_checklstring(L, 4, &key_len);
    size_t iv_len = 0;
    const char *iv = luaL_optlstring(L, 5, NULL, &iv_len); /* can be NULL */

    int pad = lua_isnone(L, 6) ? 1 : lua_toboolean(L, 6);
    ENGINE *e = lua_isnoneornil(L, 7) ? NULL : CHECK_OBJECT(7, ENGINE, "openssl.engine");

    EVP_CIPHER_CTX *c = EVP_CIPHER_CTX_new();

    int output_len = 0;
    int len = 0;

    char evp_key[EVP_MAX_KEY_LENGTH] = {0};
    char evp_iv[EVP_MAX_IV_LENGTH] = {0};

    int ret;

    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);
    }

    EVP_CIPHER_CTX_init(c);
    ret = EVP_CipherInit_ex(c, cipher, e, (const byte*)evp_key, iv_len > 0 ? (const byte*)evp_iv : NULL, enc);
    if (ret == 1)
    {
      ret = EVP_CIPHER_CTX_set_padding(c, pad);
      if (ret == 1)
      {
        char *buffer;
        len = input_len + EVP_MAX_BLOCK_LENGTH;
        buffer = OPENSSL_malloc(len);
        ret = EVP_CipherUpdate(c, (byte*)buffer, &len, (const byte*)input, input_len);
        if (ret == 1)
        {
          output_len += len;
          len = input_len + EVP_MAX_BLOCK_LENGTH - len;
          ret = EVP_CipherFinal(c, (byte*)buffer + output_len, &len);
          if (ret == 1)
          {
            output_len += len;
            lua_pushlstring(L, buffer, output_len);
          }
        }
        OPENSSL_free(buffer);
      }
    }
    EVP_CIPHER_CTX_cleanup(c);
    EVP_CIPHER_CTX_free(c);
    return (ret == 1) ? ret : openssl_pushresult(L, ret);
  }
  else
    luaL_argerror(L, 1, "invvalid cipher algorithm or openssl.evp_cipher object");

  return 0;
}
Example #22
0
U8_EXPORT ssize_t u8_cryptic
(int do_encrypt,const char *cname,
 const unsigned char *key,int keylen,
 const unsigned char *iv,int ivlen,
 u8_block_reader reader,u8_block_writer writer,
 void *readstate,void *writestate,
 u8_context caller)
{
  if (strncasecmp(cname,"rsa",3)==0) {
    ENGINE *eng=ENGINE_get_default_RSA();
    EVP_PKEY _pkey, *pkey; EVP_PKEY_CTX *ctx; 
    int pubkeyin=(strncasecmp(cname,"rsapub",6)==0);
    const unsigned char *scankey=key;
    struct U8_BYTEBUF bb;
    int retval=-1;
    if (pubkeyin) pkey=d2i_PUBKEY(NULL,&scankey,keylen);
    else pkey=d2i_PrivateKey((EVP_PKEY_RSA),NULL,&scankey,keylen);
    if (!(pkey)) ctx=NULL;
    else {
#if (OPENSSL_VERSION_NUMBER>=0x1000204fL)
      ctx=EVP_PKEY_CTX_new(pkey,eng);
#else
      ctx=EVP_PKEY_CTX_new(pkey,NULL);
#endif
    }
    if (ctx) {
      memset(&bb,0,sizeof(bb));
      bb.u8_direction=u8_output_buffer;
      bb.u8_buf=bb.u8_ptr=(u8_byte *)u8_malloc(1024);
      bb.u8_lim=(u8_byte *)(bb.u8_buf+1024);
      bb.u8_growbuf=1;
      fill_bytebuf(&bb,reader,readstate);}
    if (!(ctx)) {}
    else if ((pubkeyin)?
	     ((do_encrypt)?((retval=EVP_PKEY_encrypt_init(ctx))<0):
	      ((retval=EVP_PKEY_verify_recover_init(ctx))<0)):
	     ((do_encrypt)?((retval=EVP_PKEY_sign_init(ctx))<0):
	      ((retval=EVP_PKEY_decrypt_init(ctx))<0))) {}
    else {
      unsigned char *in=bb.u8_buf; size_t inlen=bb.u8_ptr-bb.u8_buf;
      unsigned char *out=NULL; size_t outlen;
      if (pubkeyin) {
	if (do_encrypt) retval=EVP_PKEY_encrypt(ctx,NULL,&outlen,in,inlen);
	else retval=EVP_PKEY_verify_recover(ctx,NULL,&outlen,in,inlen);}
      else if (do_encrypt) retval=EVP_PKEY_sign(ctx,NULL,&outlen,in,inlen);
      else retval=EVP_PKEY_decrypt(ctx,NULL,&outlen,in,inlen);
      if (retval<0) {}
      else if ((out=u8_malloc(outlen))==NULL) {}
      else if (pubkeyin) {
	if (do_encrypt) retval=EVP_PKEY_encrypt(ctx,out,&outlen,in,inlen);
	else retval=EVP_PKEY_verify_recover(ctx,out,&outlen,in,inlen);}
      else if (do_encrypt) retval=EVP_PKEY_sign(ctx,out,&outlen,in,inlen);
      else retval=EVP_PKEY_decrypt(ctx,out,&outlen,in,inlen);
      if (retval<0) {}
      else retval=writer(out,outlen,writestate);
      if (out) u8_free(out);}
    u8_free(bb.u8_buf);
    if (retval<0) {
      unsigned long err=ERR_get_error(); char buf[512];
      buf[0]='\0'; ERR_error_string_n(err,buf,512);
      u8_seterr(u8_InternalCryptoError,OPENSSL_CRYPTIC,u8_fromlibc((char *)buf));
      ERR_clear_error();}
    if (ctx) EVP_PKEY_CTX_free(ctx);
    if (pkey)  EVP_PKEY_free(pkey);
    return retval;}
  else {
    EVP_CIPHER_CTX ctx;
    int inlen, outlen, retval=0;
    ssize_t totalout=0, totalin=0;
    unsigned char inbuf[1024], outbuf[1024+EVP_MAX_BLOCK_LENGTH];
    const EVP_CIPHER *cipher=((cname)?(EVP_get_cipherbyname(cname)):
			      (EVP_aes_128_cbc()));

    if (cipher) {
      int needkeylen=EVP_CIPHER_key_length(cipher);
      int needivlen=EVP_CIPHER_iv_length(cipher);
      int blocksize=EVP_CIPHER_block_size(cipher);
      if (blocksize>1024) blocksize=1024;
      u8_log(CRYPTO_LOGLEVEL,OPENSSL_CRYPTIC,
	     " %s cipher=%s, keylen=%d/%d, ivlen=%d/%d, blocksize=%d\n",
	     ((do_encrypt)?("encrypt"):("decrypt")),
	     cname,keylen,needkeylen,ivlen,needivlen,blocksize);

      if ((needivlen)&&(ivlen)&&(ivlen!=needivlen))
	return u8_reterr(u8_BadCryptoIV,
			 ((caller)?(caller):(OPENSSL_CRYPTIC)),
			 u8_mkstring("%d!=%d(%s)",ivlen,needivlen,cname));

      memset(&ctx,0,sizeof(ctx));

      EVP_CIPHER_CTX_init(&ctx);

      retval=EVP_CipherInit(&ctx, cipher, NULL, NULL, do_encrypt);
      if (retval==0)
	return u8_reterr(u8_CipherInit_Failed,
			 ((caller)?(caller):(OPENSSL_CRYPTIC)),
			 u8_strdup(cname));

      retval=EVP_CIPHER_CTX_set_key_length(&ctx,keylen);
      if (retval==0)
	return u8_reterr(u8_BadCryptoKey,
			 ((caller)?(caller):(OPENSSL_CRYPTIC)),
			 u8_mkstring("%d!=%d(%s)",keylen,needkeylen,cname));

      if ((needivlen)&&(ivlen!=needivlen))
	return u8_reterr(u8_BadCryptoIV,
			 ((caller)?(caller):(OPENSSL_CRYPTIC)),
			 u8_mkstring("%d!=%d(%s)",ivlen,needivlen,cname));

      retval=EVP_CipherInit(&ctx, cipher, key, iv, do_encrypt);
      if (retval==0)
	return u8_reterr(u8_CipherInit_Failed,
			 ((caller)?(caller):(OPENSSL_CRYPTIC)),
			 u8_strdup(cname));

      while (1) {
	inlen = reader(inbuf,blocksize,readstate);
	if (inlen <= 0) {
	  u8_log(CRYPTO_LOGLEVEL,OPENSSL_CRYPTIC,
		 "Finished %s(%s) with %ld in, %ld out",
		 ((do_encrypt)?("encrypt"):("decrypt")),
		 cname,totalin,totalout);
	  break;}
	else totalin=totalin+inlen;
	if (!(EVP_CipherUpdate(&ctx,outbuf,&outlen,inbuf,inlen))) {
	  char *details=u8_malloc(256);
	  unsigned long err=ERR_get_error();
	  ERR_error_string_n(err,details,256);
	  EVP_CIPHER_CTX_cleanup(&ctx);
	  return u8_reterr(u8_InternalCryptoError,
			   ((caller)?(caller):((u8_context)"u8_cryptic")),
			   details);}
	else {
	  u8_log(CRYPTO_LOGLEVEL,OPENSSL_CRYPTIC,
		 "%s(%s) consumed %d/%ld bytes, emitted %d/%ld bytes"
		 " in=<%v>\n out=<%v>",
		 ((do_encrypt)?("encrypt"):("decrypt")),cname,
		 inlen,totalin,outlen,totalout+outlen,
		 inbuf,inlen,outbuf,outlen);
	  writer(outbuf,outlen,writestate);
	  totalout=totalout+outlen;}}
      if (!(EVP_CipherFinal(&ctx,outbuf,&outlen))) {
	char *details=u8_malloc(256);
	unsigned long err=ERR_get_error();
	ERR_error_string_n(err,details,256);
	EVP_CIPHER_CTX_cleanup(&ctx);
	return u8_reterr(u8_InternalCryptoError,
			 ((caller)?(caller):(OPENSSL_CRYPTIC)),
			 details);}
      else {
	writer(outbuf,outlen,writestate);
	u8_log(CRYPTO_LOGLEVEL,OPENSSL_CRYPTIC,
	       "%s(%s) done after consuming %ld/%ld bytes, emitting %ld/%ld bytes"
	       "\n final out=<%v>",
	       ((do_encrypt)?("encrypt"):("decrypt")),cname,
	       inlen,totalin,outlen,totalout+outlen,
	       outbuf,outlen);
	EVP_CIPHER_CTX_cleanup(&ctx);
	totalout=totalout+outlen;
	return totalout;}}
    else {
      char *details=u8_malloc(256);
      unsigned long err=ERR_get_error();
      ERR_error_string_n(err,details,256);
      return u8_reterr("Unknown cipher",
		       ((caller)?(caller):((u8_context)"u8_cryptic")),
		       details);}
  }
}
Example #23
0
static long ber_ctrl(BIO *b, int cmd, long num, char *ptr)
	{
	BIO *dbio;
	BIO_ENC_CTX *ctx,*dctx;
	long ret=1;
	int i;

	ctx=(BIO_ENC_CTX *)b->ptr;

	switch (cmd)
		{
	case BIO_CTRL_RESET:
		ctx->ok=1;
		ctx->finished=0;
		EVP_CipherInit(&(ctx->cipher),NULL,NULL,NULL,
			ctx->cipher.berrypt);
		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
		break;
	case BIO_CTRL_EOF:	/* More to read */
		if (ctx->cont <= 0)
			ret=1;
		else
			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
		break;
	case BIO_CTRL_WPENDING:
		ret=ctx->buf_len-ctx->buf_off;
		if (ret <= 0)
			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
		break;
	case BIO_CTRL_PENDING: /* More to read in buffer */
		ret=ctx->buf_len-ctx->buf_off;
		if (ret <= 0)
			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
		break;
	case BIO_CTRL_FLUSH:
		/* do a final write */
again:
		while (ctx->buf_len != ctx->buf_off)
			{
			i=ber_write(b,NULL,0);
			if (i < 0)
				{
				ret=i;
				break;
				}
			}

		if (!ctx->finished)
			{
			ctx->finished=1;
			ctx->buf_off=0;
			ret=EVP_CipherFinal(&(ctx->cipher),
				(unsigned char *)ctx->buf,
				&(ctx->buf_len));
			ctx->ok=(int)ret;
			if (ret <= 0) break;

			/* push out the bytes */
			goto again;
			}
		
		/* Finally flush the underlying BIO */
		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
		break;
	case BIO_C_GET_CIPHER_STATUS:
		ret=(long)ctx->ok;
		break;
	case BIO_C_DO_STATE_MACHINE:
		BIO_clear_retry_flags(b);
		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
		BIO_copy_next_retry(b);
		break;

	case BIO_CTRL_DUP:
		dbio=(BIO *)ptr;
		dctx=(BIO_ENC_CTX *)dbio->ptr;
		memcpy(&(dctx->cipher),&(ctx->cipher),sizeof(ctx->cipher));
		dbio->init=1;
		break;
	default:
		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
		break;
		}
	return(ret);
	}