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 }
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); } }
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 }
/* * 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; }
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; }
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; }
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; }
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; }
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); }
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); }
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); }
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; }
/* * 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; }
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; }
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); }
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); }
/* * 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; }
/* * 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; }
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); }
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); }
/* * 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; }
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; } }
int cipher_ctx_reset (EVP_CIPHER_CTX *ctx, uint8_t *iv_buf) { return EVP_CipherInit (ctx, NULL, NULL, iv_buf, -1); }
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; }
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; }