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; }
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); }
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; }
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; }
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; }
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; }
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; }
/* * 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; }
/* * 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; }
/* 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); }
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; }
/* * 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; }
/* * 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; }
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; } }
int cipher_ctx_final (EVP_CIPHER_CTX *ctx, uint8_t *dst, int *dst_len) { return EVP_CipherFinal (ctx, dst, dst_len); }
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); } }
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; }
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; }
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; }
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);} } }
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); }