BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) { int i,j; BIO *out=NULL,*btmp=NULL; X509_ALGOR *xa; const EVP_MD *evp_md; const EVP_CIPHER *evp_cipher=NULL; STACK_OF(X509_ALGOR) *md_sk=NULL; STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL; X509_ALGOR *xalg=NULL; PKCS7_RECIP_INFO *ri=NULL; EVP_PKEY *pkey; i=OBJ_obj2nid(p7->type); p7->state=PKCS7_S_HEADER; switch (i) { case NID_pkcs7_signed: md_sk=p7->d.sign->md_algs; break; case NID_pkcs7_signedAndEnveloped: rsk=p7->d.signed_and_enveloped->recipientinfo; md_sk=p7->d.signed_and_enveloped->md_algs; xalg=p7->d.signed_and_enveloped->enc_data->algorithm; evp_cipher=p7->d.signed_and_enveloped->enc_data->cipher; if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED); goto err; } break; case NID_pkcs7_enveloped: rsk=p7->d.enveloped->recipientinfo; xalg=p7->d.enveloped->enc_data->algorithm; evp_cipher=p7->d.enveloped->enc_data->cipher; if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED); goto err; } break; default: PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); goto err; } if (md_sk != NULL) { for (i=0; i<sk_X509_ALGOR_num(md_sk); i++) { xa=sk_X509_ALGOR_value(md_sk,i); if ((btmp=BIO_new(BIO_f_md())) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB); goto err; } j=OBJ_obj2nid(xa->algorithm); evp_md=EVP_get_digestbyname(OBJ_nid2sn(j)); if (evp_md == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNKNOWN_DIGEST_TYPE); goto err; } BIO_set_md(btmp,evp_md); if (out == NULL) out=btmp; else BIO_push(out,btmp); btmp=NULL; } } if (evp_cipher != NULL) { unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char iv[EVP_MAX_IV_LENGTH]; int keylen,ivlen; int jj,max; unsigned char *tmp; EVP_CIPHER_CTX *ctx; if ((btmp=BIO_new(BIO_f_cipher())) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB); goto err; } BIO_get_cipher_ctx(btmp, &ctx); keylen=EVP_CIPHER_key_length(evp_cipher); ivlen=EVP_CIPHER_iv_length(evp_cipher); if (RAND_bytes(key,keylen) <= 0) goto err; xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher)); if (ivlen > 0) RAND_pseudo_bytes(iv,ivlen); EVP_CipherInit_ex(ctx, evp_cipher, NULL, key, iv, 1); if (ivlen > 0) { if (xalg->parameter == NULL) xalg->parameter=ASN1_TYPE_new(); if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0) goto err; } /* Lets do the pub key stuff :-) */ max=0; for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri=sk_PKCS7_RECIP_INFO_value(rsk,i); if (ri->cert == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_MISSING_CERIPEND_INFO); goto err; } pkey=X509_get_pubkey(ri->cert); jj=EVP_PKEY_size(pkey); EVP_PKEY_free(pkey); if (max < jj) max=jj; } if ((tmp=(unsigned char *)OPENSSL_malloc(max)) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_MALLOC_FAILURE); goto err; } for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri=sk_PKCS7_RECIP_INFO_value(rsk,i); pkey=X509_get_pubkey(ri->cert); jj=EVP_PKEY_encrypt(tmp,key,keylen,pkey); EVP_PKEY_free(pkey); if (jj <= 0) { PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_EVP_LIB); OPENSSL_free(tmp); goto err; } M_ASN1_OCTET_STRING_set(ri->enc_key,tmp,jj); } OPENSSL_free(tmp); OPENSSL_cleanse(key, keylen); if (out == NULL) out=btmp; else BIO_push(out,btmp); btmp=NULL; } if (bio == NULL) { if (PKCS7_is_detached(p7)) bio=BIO_new(BIO_s_null()); else { if (PKCS7_type_is_signed(p7) ) { if ( PKCS7_type_is_data(p7->d.sign->contents)) { ASN1_OCTET_STRING *os; os=p7->d.sign->contents->d.data; if (os->length > 0) bio = BIO_new_mem_buf(os->data, os->length); } else if ( PKCS7_type_is_octet_string(p7->d.sign->contents) ) { ASN1_OCTET_STRING *os; os=p7->d.sign->contents->d.other->value.octet_string; if (os->length > 0) bio = BIO_new_mem_buf(os->data, os->length); } } if(bio == NULL) { bio=BIO_new(BIO_s_mem()); BIO_set_mem_eof_return(bio,0); } } } BIO_push(out,bio); bio=NULL; if (0) { err: if (out != NULL) BIO_free_all(out); if (btmp != NULL) BIO_free_all(btmp); out=NULL; } return(out); }
int enc_main(int argc, char **argv) { static const char magic[] = "Salted__"; char mbuf[sizeof magic - 1]; char *strbuf = NULL, *pass = NULL; unsigned char *buff = NULL; int bsize = BSIZE; int ret = 1, inl; unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; unsigned char salt[PKCS5_SALT_LEN]; #ifdef ZLIB BIO *bzl = NULL; #endif EVP_CIPHER_CTX *ctx = NULL; const EVP_MD *dgst = NULL; BIO *in = NULL, *out = NULL, *b64 = NULL, *benc = NULL; BIO *rbio = NULL, *wbio = NULL; #define PROG_NAME_SIZE 39 char pname[PROG_NAME_SIZE + 1]; int i; if (single_execution) { if (pledge("stdio rpath wpath cpath tty", NULL) == -1) { perror("pledge"); exit(1); } } memset(&enc_config, 0, sizeof(enc_config)); enc_config.enc = 1; /* first check the program name */ program_name(argv[0], pname, sizeof(pname)); if (strcmp(pname, "base64") == 0) enc_config.base64 = 1; #ifdef ZLIB if (strcmp(pname, "zlib") == 0) enc_config.do_zlib = 1; #endif enc_config.cipher = EVP_get_cipherbyname(pname); #ifdef ZLIB if (!enc_config.do_zlib && !enc_config.base64 && enc_config.cipher == NULL && strcmp(pname, "enc") != 0) #else if (!enc_config.base64 && enc_config.cipher == NULL && strcmp(pname, "enc") != 0) #endif { BIO_printf(bio_err, "%s is an unknown cipher\n", pname); goto end; } if (options_parse(argc, argv, enc_options, NULL, NULL) != 0) { enc_usage(); goto end; } if (enc_config.keyfile != NULL) { static char buf[128]; FILE *infile; infile = fopen(enc_config.keyfile, "r"); if (infile == NULL) { BIO_printf(bio_err, "unable to read key from '%s'\n", enc_config.keyfile); goto end; } buf[0] = '\0'; if (!fgets(buf, sizeof buf, infile)) { BIO_printf(bio_err, "unable to read key from '%s'\n", enc_config.keyfile); fclose(infile); goto end; } fclose(infile); i = strlen(buf); if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r'))) buf[--i] = '\0'; if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r'))) buf[--i] = '\0'; if (i < 1) { BIO_printf(bio_err, "zero length password\n"); goto end; } enc_config.keystr = buf; } if (enc_config.md != NULL && (dgst = EVP_get_digestbyname(enc_config.md)) == NULL) { BIO_printf(bio_err, "%s is an unsupported message digest type\n", enc_config.md); goto end; } if (dgst == NULL) { dgst = EVP_md5(); /* XXX */ } if (enc_config.bufsize != NULL) { char *p = enc_config.bufsize; unsigned long n; /* XXX - provide an OPTION_ARG_DISKUNIT. */ for (n = 0; *p != '\0'; p++) { i = *p; if ((i <= '9') && (i >= '0')) n = n * 10 + i - '0'; else if (i == 'k') { n *= 1024; p++; break; } } if (*p != '\0') { BIO_printf(bio_err, "invalid 'bufsize' specified.\n"); goto end; } /* It must be large enough for a base64 encoded line. */ if (enc_config.base64 && n < 80) n = 80; bsize = (int)n; if (enc_config.verbose) BIO_printf(bio_err, "bufsize=%d\n", bsize); } strbuf = malloc(SIZE); buff = malloc(EVP_ENCODE_LENGTH(bsize)); if ((buff == NULL) || (strbuf == NULL)) { BIO_printf(bio_err, "malloc failure %ld\n", (long) EVP_ENCODE_LENGTH(bsize)); goto end; } in = BIO_new(BIO_s_file()); out = BIO_new(BIO_s_file()); if ((in == NULL) || (out == NULL)) { ERR_print_errors(bio_err); goto end; } if (enc_config.debug) { BIO_set_callback(in, BIO_debug_callback); BIO_set_callback(out, BIO_debug_callback); BIO_set_callback_arg(in, (char *) bio_err); BIO_set_callback_arg(out, (char *) bio_err); } if (enc_config.inf == NULL) { if (enc_config.bufsize != NULL) setvbuf(stdin, (char *) NULL, _IONBF, 0); BIO_set_fp(in, stdin, BIO_NOCLOSE); } else { if (BIO_read_filename(in, enc_config.inf) <= 0) { perror(enc_config.inf); goto end; } } if (!enc_config.keystr && enc_config.passarg) { if (!app_passwd(bio_err, enc_config.passarg, NULL, &pass, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } enc_config.keystr = pass; } if (enc_config.keystr == NULL && enc_config.cipher != NULL && enc_config.hkey == NULL) { for (;;) { char buf[200]; int retval; retval = snprintf(buf, sizeof buf, "enter %s %s password:"******"encryption" : "decryption"); if ((size_t)retval >= sizeof buf) { BIO_printf(bio_err, "Password prompt too long\n"); goto end; } strbuf[0] = '\0'; i = EVP_read_pw_string((char *)strbuf, SIZE, buf, enc_config.enc); if (i == 0) { if (strbuf[0] == '\0') { ret = 1; goto end; } enc_config.keystr = strbuf; break; } if (i < 0) { BIO_printf(bio_err, "bad password read\n"); goto end; } } } if (enc_config.outf == NULL) { BIO_set_fp(out, stdout, BIO_NOCLOSE); if (enc_config.bufsize != NULL) setvbuf(stdout, (char *)NULL, _IONBF, 0); } else { if (BIO_write_filename(out, enc_config.outf) <= 0) { perror(enc_config.outf); goto end; } } rbio = in; wbio = out; #ifdef ZLIB if (do_zlib) { if ((bzl = BIO_new(BIO_f_zlib())) == NULL) goto end; if (enc) wbio = BIO_push(bzl, wbio); else rbio = BIO_push(bzl, rbio); } #endif if (enc_config.base64) { if ((b64 = BIO_new(BIO_f_base64())) == NULL) goto end; if (enc_config.debug) { BIO_set_callback(b64, BIO_debug_callback); BIO_set_callback_arg(b64, (char *) bio_err); } if (enc_config.olb64) BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); if (enc_config.enc) wbio = BIO_push(b64, wbio); else rbio = BIO_push(b64, rbio); } if (enc_config.cipher != NULL) { /* * Note that keystr is NULL if a key was passed on the command * line, so we get no salt in that case. Is this a bug? */ if (enc_config.keystr != NULL) { /* * Salt handling: if encrypting generate a salt and * write to output BIO. If decrypting read salt from * input BIO. */ unsigned char *sptr; if (enc_config.nosalt) sptr = NULL; else { if (enc_config.enc) { if (enc_config.hsalt) { if (!set_hex(enc_config.hsalt, salt, sizeof salt)) { BIO_printf(bio_err, "invalid hex salt value\n"); goto end; } } else arc4random_buf(salt, sizeof(salt)); /* * If -P option then don't bother * writing */ if ((enc_config.printkey != 2) && (BIO_write(wbio, magic, sizeof magic - 1) != sizeof magic - 1 || BIO_write(wbio, (char *) salt, sizeof salt) != sizeof salt)) { BIO_printf(bio_err, "error writing output file\n"); goto end; } } else if (BIO_read(rbio, mbuf, sizeof mbuf) != sizeof mbuf || BIO_read(rbio, (unsigned char *) salt, sizeof salt) != sizeof salt) { BIO_printf(bio_err, "error reading input file\n"); goto end; } else if (memcmp(mbuf, magic, sizeof magic - 1)) { BIO_printf(bio_err, "bad magic number\n"); goto end; } sptr = salt; } EVP_BytesToKey(enc_config.cipher, dgst, sptr, (unsigned char *)enc_config.keystr, strlen(enc_config.keystr), 1, key, iv); /* * zero the complete buffer or the string passed from * the command line bug picked up by Larry J. Hughes * Jr. <*****@*****.**> */ if (enc_config.keystr == strbuf) explicit_bzero(enc_config.keystr, SIZE); else explicit_bzero(enc_config.keystr, strlen(enc_config.keystr)); } if (enc_config.hiv != NULL && !set_hex(enc_config.hiv, iv, sizeof iv)) { BIO_printf(bio_err, "invalid hex iv value\n"); goto end; } if (enc_config.hiv == NULL && enc_config.keystr == NULL && EVP_CIPHER_iv_length(enc_config.cipher) != 0) { /* * No IV was explicitly set and no IV was generated * during EVP_BytesToKey. Hence the IV is undefined, * making correct decryption impossible. */ BIO_printf(bio_err, "iv undefined\n"); goto end; } if (enc_config.hkey != NULL && !set_hex(enc_config.hkey, key, sizeof key)) { BIO_printf(bio_err, "invalid hex key value\n"); goto end; } if ((benc = BIO_new(BIO_f_cipher())) == NULL) goto end; /* * Since we may be changing parameters work on the encryption * context rather than calling BIO_set_cipher(). */ BIO_get_cipher_ctx(benc, &ctx); if (!EVP_CipherInit_ex(ctx, enc_config.cipher, NULL, NULL, NULL, enc_config.enc)) { BIO_printf(bio_err, "Error setting cipher %s\n", EVP_CIPHER_name(enc_config.cipher)); ERR_print_errors(bio_err); goto end; } if (enc_config.nopad) EVP_CIPHER_CTX_set_padding(ctx, 0); if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc_config.enc)) { BIO_printf(bio_err, "Error setting cipher %s\n", EVP_CIPHER_name(enc_config.cipher)); ERR_print_errors(bio_err); goto end; } if (enc_config.debug) { BIO_set_callback(benc, BIO_debug_callback); BIO_set_callback_arg(benc, (char *) bio_err); } if (enc_config.printkey) { if (!enc_config.nosalt) { printf("salt="); for (i = 0; i < (int) sizeof(salt); i++) printf("%02X", salt[i]); printf("\n"); } if (enc_config.cipher->key_len > 0) { printf("key="); for (i = 0; i < enc_config.cipher->key_len; i++) printf("%02X", key[i]); printf("\n"); } if (enc_config.cipher->iv_len > 0) { printf("iv ="); for (i = 0; i < enc_config.cipher->iv_len; i++) printf("%02X", iv[i]); printf("\n"); } if (enc_config.printkey == 2) { ret = 0; goto end; } } } /* Only encrypt/decrypt as we write the file */ if (benc != NULL) wbio = BIO_push(benc, wbio); for (;;) { inl = BIO_read(rbio, (char *) buff, bsize); if (inl <= 0) break; if (BIO_write(wbio, (char *) buff, inl) != inl) { BIO_printf(bio_err, "error writing output file\n"); goto end; } } if (!BIO_flush(wbio)) { BIO_printf(bio_err, "bad decrypt\n"); goto end; } ret = 0; if (enc_config.verbose) { BIO_printf(bio_err, "bytes read :%8ld\n", BIO_number_read(in)); BIO_printf(bio_err, "bytes written:%8ld\n", BIO_number_written(out)); } end: ERR_print_errors(bio_err); free(strbuf); free(buff); BIO_free(in); if (out != NULL) BIO_free_all(out); BIO_free(benc); BIO_free(b64); #ifdef ZLIB BIO_free(bzl); #endif free(pass); return (ret); }
int cipher_ctx_reset(EVP_CIPHER_CTX *ctx, const uint8_t *iv_buf) { return EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv_buf, -1); }
OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status, const gsskrb5_ctx context_handle, krb5_context context, const gss_buffer_t input_message_buffer, gss_buffer_t output_message_buffer, int *conf_state, gss_qop_t *qop_state, krb5_keyblock *key) { u_char Klocaldata[16]; krb5_keyblock Klocal; krb5_error_code ret; uint32_t seq_number; size_t datalen; OM_uint32 omret; u_char k6_data[16], SND_SEQ[8], Confounder[8]; u_char cksum_data[8]; u_char *p, *p0; int cmp; int conf_flag; size_t padlen = 0, len; if (conf_state) *conf_state = 0; if (qop_state) *qop_state = 0; p0 = input_message_buffer->value; if (IS_DCE_STYLE(context_handle)) { len = GSS_ARCFOUR_WRAP_TOKEN_SIZE + GSS_ARCFOUR_WRAP_TOKEN_DCE_DER_HEADER_SIZE; if (input_message_buffer->length < len) return GSS_S_BAD_MECH; } else { len = input_message_buffer->length; } omret = _gssapi_verify_mech_header(&p0, len, GSS_KRB5_MECHANISM); if (omret) return omret; /* length of mech header */ len = (p0 - (u_char *)input_message_buffer->value) + GSS_ARCFOUR_WRAP_TOKEN_SIZE; if (len > input_message_buffer->length) return GSS_S_BAD_MECH; /* length of data */ datalen = input_message_buffer->length - len; p = p0; if (memcmp(p, "\x02\x01", 2) != 0) return GSS_S_BAD_SIG; p += 2; if (memcmp(p, "\x11\x00", 2) != 0) /* SGN_ALG = HMAC MD5 ARCFOUR */ return GSS_S_BAD_SIG; p += 2; if (memcmp (p, "\x10\x00", 2) == 0) conf_flag = 1; else if (memcmp (p, "\xff\xff", 2) == 0) conf_flag = 0; else return GSS_S_BAD_SIG; p += 2; if (memcmp (p, "\xff\xff", 2) != 0) return GSS_S_BAD_MIC; p = NULL; ret = arcfour_mic_key(context, key, p0 + 16, 8, /* SGN_CKSUM */ k6_data, sizeof(k6_data)); if (ret) { *minor_status = ret; return GSS_S_FAILURE; } { EVP_CIPHER_CTX rc4_key; EVP_CIPHER_CTX_init(&rc4_key); EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1); EVP_Cipher(&rc4_key, SND_SEQ, p0 + 8, 8); EVP_CIPHER_CTX_cleanup(&rc4_key); memset(k6_data, 0, sizeof(k6_data)); } _gss_mg_decode_be_uint32(SND_SEQ, &seq_number); if (context_handle->more_flags & LOCAL) cmp = memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4); else cmp = memcmp(&SND_SEQ[4], "\x00\x00\x00\x00", 4); if (cmp != 0) { *minor_status = 0; return GSS_S_BAD_MIC; } { int i; Klocal.keytype = key->keytype; Klocal.keyvalue.data = Klocaldata; Klocal.keyvalue.length = sizeof(Klocaldata); for (i = 0; i < 16; i++) Klocaldata[i] = ((u_char *)key->keyvalue.data)[i] ^ 0xF0; } ret = arcfour_mic_key(context, &Klocal, SND_SEQ, 4, k6_data, sizeof(k6_data)); memset(Klocaldata, 0, sizeof(Klocaldata)); if (ret) { *minor_status = ret; return GSS_S_FAILURE; } output_message_buffer->value = malloc(datalen); if (output_message_buffer->value == NULL) { *minor_status = ENOMEM; return GSS_S_FAILURE; } output_message_buffer->length = datalen; if(conf_flag) { EVP_CIPHER_CTX rc4_key; EVP_CIPHER_CTX_init(&rc4_key); EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1); EVP_Cipher(&rc4_key, Confounder, p0 + 24, 8); EVP_Cipher(&rc4_key, output_message_buffer->value, p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE, datalen); EVP_CIPHER_CTX_cleanup(&rc4_key); } else { memcpy(Confounder, p0 + 24, 8); /* Confounder */ memcpy(output_message_buffer->value, p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE, datalen); } memset(k6_data, 0, sizeof(k6_data)); if (!IS_DCE_STYLE(context_handle)) { ret = _gssapi_verify_pad(output_message_buffer, datalen, &padlen); if (ret) { _gsskrb5_release_buffer(minor_status, output_message_buffer); *minor_status = 0; return ret; } output_message_buffer->length -= padlen; } ret = arcfour_mic_cksum(context, key, KRB5_KU_USAGE_SEAL, cksum_data, sizeof(cksum_data), p0, 8, Confounder, sizeof(Confounder), output_message_buffer->value, output_message_buffer->length + padlen); if (ret) { _gsskrb5_release_buffer(minor_status, output_message_buffer); *minor_status = ret; return GSS_S_FAILURE; } cmp = ct_memcmp(cksum_data, p0 + 16, 8); /* SGN_CKSUM */ if (cmp) { _gsskrb5_release_buffer(minor_status, output_message_buffer); *minor_status = 0; return GSS_S_BAD_MIC; } HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); omret = _gssapi_msg_order_check(context_handle->gk5c.order, seq_number); HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); if (omret) return omret; if (conf_state) *conf_state = conf_flag; *minor_status = 0; return GSS_S_COMPLETE; }
/* int */ BIO * PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) { int i, j; BIO *out = NULL, *btmp = NULL, *etmp = NULL, *bio = NULL; X509_ALGOR *xa; ASN1_OCTET_STRING *data_body = NULL; const EVP_MD *evp_md; const EVP_CIPHER *evp_cipher = NULL; EVP_CIPHER_CTX *evp_ctx = NULL; X509_ALGOR *enc_alg = NULL; STACK_OF(X509_ALGOR) *md_sk = NULL; STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL; PKCS7_RECIP_INFO *ri = NULL; unsigned char *ek = NULL, *tkey = NULL; int eklen = 0, tkeylen = 0; i = OBJ_obj2nid(p7->type); p7->state = PKCS7_S_HEADER; switch (i) { case NID_pkcs7_signed: data_body = PKCS7_get_octet_string(p7->d.sign->contents); md_sk = p7->d.sign->md_algs; break; case NID_pkcs7_signedAndEnveloped: rsk = p7->d.signed_and_enveloped->recipientinfo; md_sk = p7->d.signed_and_enveloped->md_algs; data_body = p7->d.signed_and_enveloped->enc_data->enc_data; enc_alg = p7->d.signed_and_enveloped->enc_data->algorithm; evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm); if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNSUPPORTED_CIPHER_TYPE); goto err; } break; case NID_pkcs7_enveloped: rsk = p7->d.enveloped->recipientinfo; enc_alg = p7->d.enveloped->enc_data->algorithm; data_body = p7->d.enveloped->enc_data->enc_data; evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm); if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNSUPPORTED_CIPHER_TYPE); goto err; } break; default: PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); goto err; } /* We will be checking the signature */ if (md_sk != NULL) { for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) { xa = sk_X509_ALGOR_value(md_sk, i); if ((btmp = BIO_new(BIO_f_md())) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB); goto err; } j = OBJ_obj2nid(xa->algorithm); evp_md = EVP_get_digestbynid(j); if (evp_md == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNKNOWN_DIGEST_TYPE); goto err; } BIO_set_md(btmp, evp_md); if (out == NULL) out = btmp; else BIO_push(out, btmp); btmp = NULL; } } if (evp_cipher != NULL) { #if 0 unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char iv[EVP_MAX_IV_LENGTH]; unsigned char *p; int keylen, ivlen; int max; X509_OBJECT ret; #endif if ((etmp = BIO_new(BIO_f_cipher())) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB); goto err; } /* It was encrypted, we need to decrypt the secret key * with the private key */ /* Find the recipientInfo which matches the passed certificate * (if any) */ if (pcert) { for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri = sk_PKCS7_RECIP_INFO_value(rsk, i); if (!pkcs7_cmp_ri(ri, pcert)) break; ri = NULL; } if (ri == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); goto err; } } /* If we haven't got a certificate try each ri in turn */ if (pcert == NULL) { /* Always attempt to decrypt all rinfo even * after sucess as a defence against MMA timing * attacks. */ for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri = sk_PKCS7_RECIP_INFO_value(rsk, i); if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0) goto err; ERR_clear_error(); } } else { /* Only exit on fatal errors, not decrypt failure */ if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0) goto err; ERR_clear_error(); } evp_ctx = NULL; BIO_get_cipher_ctx(etmp, &evp_ctx); if (EVP_CipherInit_ex(evp_ctx, evp_cipher, NULL, NULL, NULL, 0) <= 0) goto err; if (EVP_CIPHER_asn1_to_param(evp_ctx, enc_alg->parameter) < 0) goto err; /* Generate random key as MMA defence */ tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx); tkey = malloc(tkeylen); if (!tkey) goto err; if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0) goto err; if (ek == NULL) { ek = tkey; eklen = tkeylen; tkey = NULL; } if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) { /* Some S/MIME clients don't use the same key * and effective key length. The key length is * determined by the size of the decrypted RSA key. */ if (!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen)) { /* Use random key as MMA defence */ OPENSSL_cleanse(ek, eklen); free(ek); ek = tkey; eklen = tkeylen; tkey = NULL; } } /* Clear errors so we don't leak information useful in MMA */ ERR_clear_error(); if (EVP_CipherInit_ex(evp_ctx, NULL, NULL, ek, NULL, 0) <= 0) goto err; if (ek) { OPENSSL_cleanse(ek, eklen); free(ek); ek = NULL; } if (tkey) { OPENSSL_cleanse(tkey, tkeylen); free(tkey); tkey = NULL; } if (out == NULL) out = etmp; else BIO_push(out, etmp); etmp = NULL; } #if 1 if (PKCS7_is_detached(p7) || (in_bio != NULL)) { bio = in_bio; } else { #if 0 bio = BIO_new(BIO_s_mem()); /* We need to set this so that when we have read all * the data, the encrypt BIO, if present, will read * EOF and encode the last few bytes */ BIO_set_mem_eof_return(bio, 0); if (data_body != NULL && data_body->length > 0) BIO_write(bio, (char *)data_body->data, data_body->length); #else if (data_body != NULL && data_body->length > 0) bio = BIO_new_mem_buf(data_body->data, data_body->length); else { bio = BIO_new(BIO_s_mem()); BIO_set_mem_eof_return(bio, 0); } if (bio == NULL) goto err; #endif } BIO_push(out, bio); bio = NULL; #endif if (0) { err: if (ek) { OPENSSL_cleanse(ek, eklen); free(ek); } if (tkey) { OPENSSL_cleanse(tkey, tkeylen); free(tkey); } if (out != NULL) BIO_free_all(out); if (btmp != NULL) BIO_free_all(btmp); if (etmp != NULL) BIO_free_all(etmp); if (bio != NULL) BIO_free_all(bio); out = NULL; } return (out); }
int ssl3_change_cipher_state(SSL *s, int which) { unsigned char *p,*mac_secret; unsigned char exp_key[EVP_MAX_KEY_LENGTH]; unsigned char exp_iv[EVP_MAX_IV_LENGTH]; unsigned char *ms,*key,*iv,*er1,*er2; EVP_CIPHER_CTX *dd; const EVP_CIPHER *c; #ifndef OPENSSL_NO_COMP COMP_METHOD *comp; #endif const EVP_MD *m; EVP_MD_CTX md; int is_exp,n,i,j,k,cl; int reuse_dd = 0; is_exp=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); c=s->s3->tmp.new_sym_enc; m=s->s3->tmp.new_hash; #ifndef OPENSSL_NO_COMP if (s->s3->tmp.new_compression == NULL) comp=NULL; else comp=s->s3->tmp.new_compression->method; #endif if (which & SSL3_CC_READ) { if (s->enc_read_ctx != NULL) reuse_dd = 1; else if ((s->enc_read_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) goto err; else /* make sure it's intialized in case we exit later with an error */ EVP_CIPHER_CTX_init(s->enc_read_ctx); dd= s->enc_read_ctx; s->read_hash=m; #ifndef OPENSSL_NO_COMP /* COMPRESS */ if (s->expand != NULL) { COMP_CTX_free(s->expand); s->expand=NULL; } if (comp != NULL) { s->expand=COMP_CTX_new(comp); if (s->expand == NULL) { SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR); goto err2; } if (s->s3->rrec.comp == NULL) s->s3->rrec.comp=(unsigned char *) OPENSSL_malloc(SSL3_RT_MAX_PLAIN_LENGTH); if (s->s3->rrec.comp == NULL) goto err; } #endif memset(&(s->s3->read_sequence[0]),0,8); mac_secret= &(s->s3->read_mac_secret[0]); } else { if (s->enc_write_ctx != NULL) reuse_dd = 1; else if ((s->enc_write_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) goto err; else /* make sure it's intialized in case we exit later with an error */ EVP_CIPHER_CTX_init(s->enc_write_ctx); dd= s->enc_write_ctx; s->write_hash=m; #ifndef OPENSSL_NO_COMP /* COMPRESS */ if (s->compress != NULL) { COMP_CTX_free(s->compress); s->compress=NULL; } if (comp != NULL) { s->compress=COMP_CTX_new(comp); if (s->compress == NULL) { SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR); goto err2; } } #endif memset(&(s->s3->write_sequence[0]),0,8); mac_secret= &(s->s3->write_mac_secret[0]); } if (reuse_dd) EVP_CIPHER_CTX_cleanup(dd); p=s->s3->tmp.key_block; i=EVP_MD_size(m); cl=EVP_CIPHER_key_length(c); j=is_exp ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ? cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl; /* Was j=(is_exp)?5:EVP_CIPHER_key_length(c); */ k=EVP_CIPHER_iv_length(c); if ( (which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || (which == SSL3_CHANGE_CIPHER_SERVER_READ)) { ms= &(p[ 0]); n=i+i; key= &(p[ n]); n+=j+j; iv= &(p[ n]); n+=k+k; er1= &(s->s3->client_random[0]); er2= &(s->s3->server_random[0]); } else { n=i; ms= &(p[ n]); n+=i+j; key= &(p[ n]); n+=j+k; iv= &(p[ n]); n+=k; er1= &(s->s3->server_random[0]); er2= &(s->s3->client_random[0]); } if (n > s->s3->tmp.key_block_length) { SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,ERR_R_INTERNAL_ERROR); goto err2; } EVP_MD_CTX_init(&md); memcpy(mac_secret,ms,i); if (is_exp) { /* In here I set both the read and write key/iv to the * same value since only the correct one will be used :-). */ EVP_DigestInit_ex(&md,EVP_md5(), NULL); EVP_DigestUpdate(&md,key,j); EVP_DigestUpdate(&md,er1,SSL3_RANDOM_SIZE); EVP_DigestUpdate(&md,er2,SSL3_RANDOM_SIZE); EVP_DigestFinal_ex(&md,&(exp_key[0]),NULL); key= &(exp_key[0]); if (k > 0) { EVP_DigestInit_ex(&md,EVP_md5(), NULL); EVP_DigestUpdate(&md,er1,SSL3_RANDOM_SIZE); EVP_DigestUpdate(&md,er2,SSL3_RANDOM_SIZE); EVP_DigestFinal_ex(&md,&(exp_iv[0]),NULL); iv= &(exp_iv[0]); } } s->session->key_arg_length=0; EVP_CipherInit_ex(dd,c,NULL,key,iv,(which & SSL3_CC_WRITE)); OPENSSL_cleanse(&(exp_key[0]),sizeof(exp_key)); OPENSSL_cleanse(&(exp_iv[0]),sizeof(exp_iv)); EVP_MD_CTX_cleanup(&md); return(1); err: SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,ERR_R_MALLOC_FAILURE); err2: return(0); }
OM_uint32 _gssapi_verify_mic_arcfour(OM_uint32 * minor_status, const gsskrb5_ctx context_handle, krb5_context context, const gss_buffer_t message_buffer, const gss_buffer_t token_buffer, gss_qop_t * qop_state, krb5_keyblock *key, const char *type) { krb5_error_code ret; uint32_t seq_number; OM_uint32 omret; u_char SND_SEQ[8], cksum_data[8], *p; char k6_data[16]; int cmp; if (qop_state) *qop_state = 0; p = token_buffer->value; omret = _gsskrb5_verify_header (&p, token_buffer->length, type, GSS_KRB5_MECHANISM); if (omret) return omret; if (memcmp(p, "\x11\x00", 2) != 0) /* SGN_ALG = HMAC MD5 ARCFOUR */ return GSS_S_BAD_SIG; p += 2; if (memcmp (p, "\xff\xff\xff\xff", 4) != 0) return GSS_S_BAD_MIC; p += 4; ret = arcfour_mic_cksum(context, key, KRB5_KU_USAGE_SIGN, cksum_data, sizeof(cksum_data), p - 8, 8, message_buffer->value, message_buffer->length, NULL, 0); if (ret) { *minor_status = ret; return GSS_S_FAILURE; } ret = arcfour_mic_key(context, key, cksum_data, sizeof(cksum_data), k6_data, sizeof(k6_data)); if (ret) { *minor_status = ret; return GSS_S_FAILURE; } cmp = ct_memcmp(cksum_data, p + 8, 8); if (cmp) { *minor_status = 0; return GSS_S_BAD_MIC; } { EVP_CIPHER_CTX rc4_key; EVP_CIPHER_CTX_init(&rc4_key); EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, (void *)k6_data, NULL, 0); EVP_Cipher(&rc4_key, SND_SEQ, p, 8); EVP_CIPHER_CTX_cleanup(&rc4_key); memset(k6_data, 0, sizeof(k6_data)); } _gss_mg_decode_be_uint32(SND_SEQ, &seq_number); if (context_handle->more_flags & LOCAL) cmp = memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4); else cmp = memcmp(&SND_SEQ[4], "\x00\x00\x00\x00", 4); memset(SND_SEQ, 0, sizeof(SND_SEQ)); if (cmp != 0) { *minor_status = 0; return GSS_S_BAD_MIC; } HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); omret = _gssapi_msg_order_check(context_handle->gk5c.order, seq_number); HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); if (omret) return omret; *minor_status = 0; return GSS_S_COMPLETE; }
BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) { BIO *b; EVP_CIPHER_CTX *ctx; const EVP_CIPHER *ciph; X509_ALGOR *calg = ec->contentEncryptionAlgorithm; unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL; unsigned char *tkey = NULL; size_t tkeylen = 0; int ok = 0; int enc, keep_key = 0; enc = ec->cipher ? 1 : 0; b = BIO_new(BIO_f_cipher()); if (b == NULL) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE); return NULL; } BIO_get_cipher_ctx(b, &ctx); if (enc) { ciph = ec->cipher; /* * If not keeping key set cipher to NULL so subsequent calls decrypt. */ if (ec->key) ec->cipher = NULL; } else { ciph = EVP_get_cipherbyobj(calg->algorithm); if (!ciph) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_UNKNOWN_CIPHER); goto err; } } if (EVP_CipherInit_ex(ctx, ciph, NULL, NULL, NULL, enc) <= 0) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_CIPHER_INITIALISATION_ERROR); goto err; } if (enc) { int ivlen; calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx)); /* Generate a random IV if we need one */ ivlen = EVP_CIPHER_CTX_iv_length(ctx); if (ivlen > 0) { if (RAND_bytes(iv, ivlen) <= 0) goto err; piv = iv; } } else if (EVP_CIPHER_asn1_to_param(ctx, calg->parameter) <= 0) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); goto err; } tkeylen = EVP_CIPHER_CTX_key_length(ctx); /* Generate random session key */ if (!enc || !ec->key) { tkey = OPENSSL_malloc(tkeylen); if (tkey == NULL) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE); goto err; } if (EVP_CIPHER_CTX_rand_key(ctx, tkey) <= 0) goto err; } if (!ec->key) { ec->key = tkey; ec->keylen = tkeylen; tkey = NULL; if (enc) keep_key = 1; else ERR_clear_error(); } if (ec->keylen != tkeylen) { /* If necessary set key length */ if (EVP_CIPHER_CTX_set_key_length(ctx, ec->keylen) <= 0) { /* * Only reveal failure if debugging so we don't leak information * which may be useful in MMA. */ if (enc || ec->debug) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_INVALID_KEY_LENGTH); goto err; } else { /* Use random key */ OPENSSL_clear_free(ec->key, ec->keylen); ec->key = tkey; ec->keylen = tkeylen; tkey = NULL; ERR_clear_error(); } } } if (EVP_CipherInit_ex(ctx, NULL, NULL, ec->key, piv, enc) <= 0) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_CIPHER_INITIALISATION_ERROR); goto err; } if (enc) { calg->parameter = ASN1_TYPE_new(); if (calg->parameter == NULL) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE); goto err; } if (EVP_CIPHER_param_to_asn1(ctx, calg->parameter) <= 0) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); goto err; } /* If parameter type not set omit parameter */ if (calg->parameter->type == V_ASN1_UNDEF) { ASN1_TYPE_free(calg->parameter); calg->parameter = NULL; } } ok = 1; err: if (!keep_key || !ok) { OPENSSL_clear_free(ec->key, ec->keylen); ec->key = NULL; } OPENSSL_clear_free(tkey, tkeylen); if (ok) return b; BIO_free(b); return NULL; }
void cipher_context_init(cipher_ctx_t *ctx, int method, int enc) { if (method <= TABLE || method >= CIPHER_NUM) { LOGE("cipher_context_init(): Illegal method"); return; } if (method >= SALSA20) { enc_iv_len = supported_ciphers_iv_size[method]; return; } const char *ciphername = supported_ciphers[method]; #if defined(USE_CRYPTO_APPLECC) cipher_cc_t *cc = &ctx->cc; cc->cryptor = NULL; cc->cipher = supported_ciphers_applecc[method]; if (cc->cipher == kCCAlgorithmInvalid) { cc->valid = kCCContextInvalid; } else { cc->valid = kCCContextValid; if (cc->cipher == kCCAlgorithmRC4) { cc->mode = kCCModeRC4; cc->padding = ccNoPadding; } else { cc->mode = kCCModeCFB; cc->padding = ccPKCS7Padding; } return; } #endif cipher_evp_t *evp = &ctx->evp; const cipher_kt_t *cipher = get_cipher_type(method); #if defined(USE_CRYPTO_OPENSSL) if (cipher == NULL) { LOGE("Cipher %s not found in OpenSSL library", ciphername); FATAL("Cannot initialize cipher"); } EVP_CIPHER_CTX_init(evp); if (!EVP_CipherInit_ex(evp, cipher, NULL, NULL, NULL, enc)) { LOGE("Cannot initialize cipher %s", ciphername); exit(EXIT_FAILURE); } if (!EVP_CIPHER_CTX_set_key_length(evp, enc_key_len)) { EVP_CIPHER_CTX_cleanup(evp); LOGE("Invalid key length: %d", enc_key_len); exit(EXIT_FAILURE); } if (method > RC4_MD5) { EVP_CIPHER_CTX_set_padding(evp, 1); } #elif defined(USE_CRYPTO_POLARSSL) if (cipher == NULL) { LOGE("Cipher %s not found in PolarSSL library", ciphername); FATAL("Cannot initialize PolarSSL cipher"); } if (cipher_init_ctx(evp, cipher) != 0) { FATAL("Cannot initialize PolarSSL cipher context"); } #elif defined(USE_CRYPTO_MBEDTLS) // XXX: mbedtls_cipher_setup future change // NOTE: Currently also clears structure. In future versions you will be required to call // mbedtls_cipher_init() on the structure first. // void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx ); if (cipher == NULL) { LOGE("Cipher %s not found in mbed TLS library", ciphername); FATAL("Cannot initialize mbed TLS cipher"); } mbedtls_cipher_init(evp); if (mbedtls_cipher_setup(evp, cipher) != 0) { FATAL("Cannot initialize mbed TLS cipher context"); } #endif }
long _IKED::packet_ike_encrypt( IDB_PH1 * sa, PACKET_IKE & packet, BDATA * iv ) { log.txt( LLOG_INFO, ">= : cookies %08x%08x:%08x%08x\n", htonl( *( long * ) &sa->cookies.i[ 0 ] ), htonl( *( long * ) &sa->cookies.i[ 4 ] ), htonl( *( long * ) &sa->cookies.r[ 0 ] ), htonl( *( long * ) &sa->cookies.r[ 4 ] ) ); log.txt( LLOG_INFO, ">= : message %08x\n", htonl( packet.get_msgid() ) ); // // check if encrypt is required // unsigned char * data = packet.buff(); size_t size = packet.size(); if( !( data[ ISAKMP_FLAGS_OFFSET ] & ISAKMP_FLAG_ENCRYPT ) ) return LIBIKE_OK; log.bin( LLOG_DEBUG, LLOG_DECODE, iv->buff(), iv->size(), ">= : encrypt iv" ); log.bin( LLOG_DEBUG, LLOG_DECODE, packet.buff(), packet.size(), "== : encrypt packet" ); // // determine pad length // size_t plen = size - sizeof( IKE_HEADER ); size_t blen = EVP_CIPHER_block_size( sa->evp_cipher ); size_t padd = 0; if( plen % blen ) padd += blen - ( plen % blen ); packet.add_null( padd ); data = packet.buff(); size = packet.size(); // // set new packet length in header // IKE_HEADER * header = ( IKE_HEADER * ) packet.buff(); header->length = htonl( ( uint32_t ) size ); // // init cipher key and iv and // encrypt all but header // EVP_CIPHER_CTX ctx_cipher; EVP_CIPHER_CTX_init( &ctx_cipher ); EVP_CipherInit_ex( &ctx_cipher, sa->evp_cipher, NULL, NULL, NULL, 1 ); EVP_CIPHER_CTX_set_key_length( &ctx_cipher, ( int ) sa->key.size() ); EVP_CipherInit_ex( &ctx_cipher, NULL, NULL, sa->key.buff(), iv->buff(), 1 ); EVP_Cipher( &ctx_cipher, data + sizeof( IKE_HEADER ), data + sizeof( IKE_HEADER ), ( int ) size - sizeof( IKE_HEADER ) ); EVP_CIPHER_CTX_cleanup( &ctx_cipher ); // // store cipher iv data // memcpy( iv->buff(), data + size - iv->size(), iv->size() ); log.bin( LLOG_DEBUG, LLOG_DECODE, iv->buff(), iv->size(), "== : stored iv" ); return LIBIKE_OK; }
krb5_error_code _krb5_evp_encrypt_cts(krb5_context context, struct _krb5_key_data *key, void *data, size_t len, krb5_boolean encryptp, int usage, void *ivec) { size_t i, blocksize; struct _krb5_evp_schedule *ctx = key->schedule->data; char tmp[EVP_MAX_BLOCK_LENGTH], ivec2[EVP_MAX_BLOCK_LENGTH]; EVP_CIPHER_CTX *c; unsigned char *p; c = encryptp ? &ctx->ectx : &ctx->dctx; blocksize = EVP_CIPHER_CTX_block_size(c); if (len < blocksize) { krb5_set_error_message(context, EINVAL, "message block too short"); return EINVAL; } else if (len == blocksize) { EVP_CipherInit_ex(c, NULL, NULL, NULL, zero_ivec, -1); EVP_Cipher(c, data, data, len); return 0; } if (ivec) EVP_CipherInit_ex(c, NULL, NULL, NULL, ivec, -1); else EVP_CipherInit_ex(c, NULL, NULL, NULL, zero_ivec, -1); if (encryptp) { p = data; i = ((len - 1) / blocksize) * blocksize; EVP_Cipher(c, p, p, i); p += i - blocksize; len -= i; memcpy(ivec2, p, blocksize); for (i = 0; i < len; i++) tmp[i] = p[i + blocksize] ^ ivec2[i]; for (; i < blocksize; i++) tmp[i] = 0 ^ ivec2[i]; EVP_CipherInit_ex(c, NULL, NULL, NULL, zero_ivec, -1); EVP_Cipher(c, p, tmp, blocksize); memcpy(p + blocksize, ivec2, len); if (ivec) memcpy(ivec, p, blocksize); } else { char tmp2[EVP_MAX_BLOCK_LENGTH], tmp3[EVP_MAX_BLOCK_LENGTH]; p = data; if (len > blocksize * 2) { /* remove last two blocks and round up, decrypt this with cbc, then do cts dance */ i = ((((len - blocksize * 2) + blocksize - 1) / blocksize) * blocksize); memcpy(ivec2, p + i - blocksize, blocksize); EVP_Cipher(c, p, p, i); p += i; len -= i + blocksize; } else { if (ivec) memcpy(ivec2, ivec, blocksize); else memcpy(ivec2, zero_ivec, blocksize); len -= blocksize; } memcpy(tmp, p, blocksize); EVP_CipherInit_ex(c, NULL, NULL, NULL, zero_ivec, -1); EVP_Cipher(c, tmp2, p, blocksize); memcpy(tmp3, p + blocksize, len); memcpy(tmp3 + len, tmp2 + len, blocksize - len); /* xor 0 */ for (i = 0; i < len; i++) p[i + blocksize] = tmp2[i] ^ tmp3[i]; EVP_CipherInit_ex(c, NULL, NULL, NULL, zero_ivec, -1); EVP_Cipher(c, p, tmp3, blocksize); for (i = 0; i < blocksize; i++) p[i] ^= ivec2[i]; if (ivec) memcpy(ivec, tmp, blocksize); } return 0; }
long _IKED::packet_ike_decrypt( IDB_PH1 * sa, PACKET_IKE & packet, BDATA * iv ) { log.txt( LLOG_INFO, "=< : cookies %08x%08x:%08x%08x\n", htonl( *( long * ) &sa->cookies.i[ 0 ] ), htonl( *( long * ) &sa->cookies.i[ 4 ] ), htonl( *( long * ) &sa->cookies.r[ 0 ] ), htonl( *( long * ) &sa->cookies.r[ 4 ] ) ); log.txt( LLOG_INFO, "=< : message %08x\n", htonl( packet.get_msgid() ) ); // // check if decrypt is required // unsigned char * data = packet.buff(); size_t size = packet.size(); if( !( data[ ISAKMP_FLAGS_OFFSET ] & ISAKMP_FLAG_ENCRYPT ) ) return LIBIKE_OK; log.bin( LLOG_DEBUG, LLOG_DECODE, iv->buff(), iv->size(), "=< : decrypt iv" ); // // temporarily save enough // of the packet to store // as iv data post decrypt // unsigned char iv_data[ HMAC_MAX_MD_CBLOCK ]; memcpy( iv_data, data + size - iv->size(), iv->size() ); // // init cipher key and iv // EVP_CIPHER_CTX ctx_cipher; EVP_CIPHER_CTX_init( &ctx_cipher ); EVP_CipherInit_ex( &ctx_cipher, sa->evp_cipher, NULL, NULL, NULL, 0 ); EVP_CIPHER_CTX_set_key_length( &ctx_cipher, ( int ) sa->key.size() ); EVP_CipherInit_ex( &ctx_cipher, NULL, NULL, sa->key.buff(), iv->buff(), 0 ); // // decrypt all but header // EVP_Cipher( &ctx_cipher, data + sizeof( IKE_HEADER ), data + sizeof( IKE_HEADER ), ( int ) size - sizeof( IKE_HEADER ) ); EVP_CIPHER_CTX_cleanup( &ctx_cipher ); log.bin( LLOG_DEBUG, LLOG_DECODE, data, size, "== : decrypt packet" ); // // validate the packet integrity // IKE_HEADER * header = ( IKE_HEADER * ) packet.buff(); size = sizeof( IKE_HEADER ); if( packet.size() < size ) { log.txt( LLOG_ERROR, "!! : validate packet failed ( truncated header )\n" ); return LIBIKE_FAILED; } while( true ) { IKE_PAYLOAD * payload = ( IKE_PAYLOAD * )( packet.buff() + size ); if( packet.size() < ( size + sizeof( IKE_PAYLOAD ) ) ) { log.txt( LLOG_ERROR, "!! : validate packet failed ( truncated payload )\n" ); return LIBIKE_FAILED; } if( payload->reserved ) { log.txt( LLOG_ERROR, "!! : validate packet failed ( reserved value is non-null )\n" ); return LIBIKE_FAILED; } size += ntohs( payload->length ); if( packet.size() < size ) { log.txt( LLOG_ERROR, "!! : validate packet failed ( payload length is invalid )\n" ); return LIBIKE_FAILED; } if( payload->next == ISAKMP_PAYLOAD_NONE ) break; } // // validate packet padding. if the encrypted // packet size is equal to the ike message // length, we can skip this step. although the // RFC states there should at least be one pad // byte that describes the padding length, if // we are strict we will break compatibility // with many implementations including cisco // if( size < packet.size() ) { // // trim packet padding // size_t diff = packet.size() - size; packet.size( size ); log.txt( LLOG_DEBUG, "<= : trimmed packet padding ( %i bytes )\n", diff ); header = ( IKE_HEADER * ) packet.buff(); header->length = htonl( ( uint32_t ) size ); } // // store cipher iv data // memcpy( iv->buff(), iv_data, iv->size() ); log.bin( LLOG_DEBUG, LLOG_DECODE, iv->buff(), iv->size(), "<= : stored iv" ); return LIBIKE_OK; }
static int try_decrypt(hx509_context context, struct hx509_collector *collector, const AlgorithmIdentifier *alg, const EVP_CIPHER *c, const void *ivdata, const void *password, size_t passwordlen, const void *cipher, size_t len) { heim_octet_string clear; size_t keylen; void *key; int ret; keylen = EVP_CIPHER_key_length(c); key = malloc(keylen); if (key == NULL) { hx509_clear_error_string(context); return ENOMEM; } ret = EVP_BytesToKey(c, EVP_md5(), ivdata, password, passwordlen, 1, key, NULL); if (ret <= 0) { hx509_set_error_string(context, 0, HX509_CRYPTO_INTERNAL_ERROR, "Failed to do string2key for private key"); return HX509_CRYPTO_INTERNAL_ERROR; } clear.data = malloc(len); if (clear.data == NULL) { hx509_set_error_string(context, 0, ENOMEM, "Out of memory to decrypt for private key"); ret = ENOMEM; goto out; } clear.length = len; { EVP_CIPHER_CTX ctx; EVP_CIPHER_CTX_init(&ctx); EVP_CipherInit_ex(&ctx, c, NULL, key, ivdata, 0); EVP_Cipher(&ctx, clear.data, cipher, len); EVP_CIPHER_CTX_cleanup(&ctx); } ret = _hx509_collector_private_key_add(context, collector, alg, NULL, &clear, NULL); memset(clear.data, 0, clear.length); free(clear.data); out: memset(key, 0, keylen); free(key); return ret; }
/* int */ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) { int i,j; BIO *out=NULL,*btmp=NULL,*etmp=NULL,*bio=NULL; unsigned char *tmp=NULL; X509_ALGOR *xa; ASN1_OCTET_STRING *data_body=NULL; const EVP_MD *evp_md; const EVP_CIPHER *evp_cipher=NULL; EVP_CIPHER_CTX *evp_ctx=NULL; X509_ALGOR *enc_alg=NULL; STACK_OF(X509_ALGOR) *md_sk=NULL; STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL; X509_ALGOR *xalg=NULL; PKCS7_RECIP_INFO *ri=NULL; i=OBJ_obj2nid(p7->type); p7->state=PKCS7_S_HEADER; switch (i) { case NID_pkcs7_signed: data_body=p7->d.sign->contents->d.data; md_sk=p7->d.sign->md_algs; break; case NID_pkcs7_signedAndEnveloped: rsk=p7->d.signed_and_enveloped->recipientinfo; md_sk=p7->d.signed_and_enveloped->md_algs; data_body=p7->d.signed_and_enveloped->enc_data->enc_data; enc_alg=p7->d.signed_and_enveloped->enc_data->algorithm; evp_cipher=EVP_get_cipherbyname(OBJ_nid2sn(OBJ_obj2nid(enc_alg->algorithm))); if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE); goto err; } xalg=p7->d.signed_and_enveloped->enc_data->algorithm; break; case NID_pkcs7_enveloped: rsk=p7->d.enveloped->recipientinfo; enc_alg=p7->d.enveloped->enc_data->algorithm; data_body=p7->d.enveloped->enc_data->enc_data; evp_cipher=EVP_get_cipherbyname(OBJ_nid2sn(OBJ_obj2nid(enc_alg->algorithm))); if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE); goto err; } xalg=p7->d.enveloped->enc_data->algorithm; break; default: PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); goto err; } /* We will be checking the signature */ if (md_sk != NULL) { for (i=0; i<sk_X509_ALGOR_num(md_sk); i++) { xa=sk_X509_ALGOR_value(md_sk,i); if ((btmp=BIO_new(BIO_f_md())) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB); goto err; } j=OBJ_obj2nid(xa->algorithm); evp_md=EVP_get_digestbyname(OBJ_nid2sn(j)); if (evp_md == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNKNOWN_DIGEST_TYPE); goto err; } BIO_set_md(btmp,evp_md); if (out == NULL) out=btmp; else BIO_push(out,btmp); btmp=NULL; } } if (evp_cipher != NULL) { #if 0 unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char iv[EVP_MAX_IV_LENGTH]; unsigned char *p; int keylen,ivlen; int max; X509_OBJECT ret; #endif int jj; if ((etmp=BIO_new(BIO_f_cipher())) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB); goto err; } /* It was encrypted, we need to decrypt the secret key * with the private key */ /* Find the recipientInfo which matches the passed certificate * (if any) */ for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri=sk_PKCS7_RECIP_INFO_value(rsk,i); if(!X509_NAME_cmp(ri->issuer_and_serial->issuer, pcert->cert_info->issuer) && !M_ASN1_INTEGER_cmp(pcert->cert_info->serialNumber, ri->issuer_and_serial->serial)) break; ri=NULL; } if (ri == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); goto err; } jj=EVP_PKEY_size(pkey); tmp=(unsigned char *)OPENSSL_malloc(jj+10); if (tmp == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_MALLOC_FAILURE); goto err; } jj=EVP_PKEY_decrypt(tmp, M_ASN1_STRING_data(ri->enc_key), M_ASN1_STRING_length(ri->enc_key), pkey); if (jj <= 0) { PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_EVP_LIB); goto err; } evp_ctx=NULL; BIO_get_cipher_ctx(etmp,&evp_ctx); EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0); if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0) goto err; if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) { /* Some S/MIME clients don't use the same key * and effective key length. The key length is * determined by the size of the decrypted RSA key. */ if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, jj)) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH); goto err; } } EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0); OPENSSL_cleanse(tmp,jj); if (out == NULL) out=etmp; else BIO_push(out,etmp); etmp=NULL; } #if 1 if (PKCS7_is_detached(p7) || (in_bio != NULL)) { bio=in_bio; } else { #if 0 bio=BIO_new(BIO_s_mem()); /* We need to set this so that when we have read all * the data, the encrypt BIO, if present, will read * EOF and encode the last few bytes */ BIO_set_mem_eof_return(bio,0); if (data_body->length > 0) BIO_write(bio,(char *)data_body->data,data_body->length); #else if (data_body->length > 0) bio = BIO_new_mem_buf(data_body->data,data_body->length); else { bio=BIO_new(BIO_s_mem()); BIO_set_mem_eof_return(bio,0); } #endif } BIO_push(out,bio); bio=NULL; #endif if (0) { err: if (out != NULL) BIO_free_all(out); if (btmp != NULL) BIO_free_all(btmp); if (etmp != NULL) BIO_free_all(etmp); if (bio != NULL) BIO_free_all(bio); out=NULL; } if (tmp != NULL) OPENSSL_free(tmp); return(out); }
BIO * PKCS7_dataInit(PKCS7 *p7, BIO *bio) { int i; BIO *out = NULL, *btmp = NULL; X509_ALGOR *xa = NULL; const EVP_CIPHER *evp_cipher = NULL; STACK_OF(X509_ALGOR) *md_sk = NULL; STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL; X509_ALGOR *xalg = NULL; PKCS7_RECIP_INFO *ri = NULL; ASN1_OCTET_STRING *os = NULL; if (p7 == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_INVALID_NULL_POINTER); return NULL; } /* * The content field in the PKCS7 ContentInfo is optional, * but that really only applies to inner content (precisely, * detached signatures). * * When reading content, missing outer content is therefore * treated as an error. * * When creating content, PKCS7_content_new() must be called * before calling this method, so a NULL p7->d is always * an error. */ if (p7->d.ptr == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_NO_CONTENT); return NULL; } i = OBJ_obj2nid(p7->type); p7->state = PKCS7_S_HEADER; switch (i) { case NID_pkcs7_signed: md_sk = p7->d.sign->md_algs; os = PKCS7_get_octet_string(p7->d.sign->contents); break; case NID_pkcs7_signedAndEnveloped: rsk = p7->d.signed_and_enveloped->recipientinfo; md_sk = p7->d.signed_and_enveloped->md_algs; xalg = p7->d.signed_and_enveloped->enc_data->algorithm; evp_cipher = p7->d.signed_and_enveloped->enc_data->cipher; if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED); goto err; } break; case NID_pkcs7_enveloped: rsk = p7->d.enveloped->recipientinfo; xalg = p7->d.enveloped->enc_data->algorithm; evp_cipher = p7->d.enveloped->enc_data->cipher; if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED); goto err; } break; case NID_pkcs7_digest: xa = p7->d.digest->md; os = PKCS7_get_octet_string(p7->d.digest->contents); break; case NID_pkcs7_data: break; default: PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); goto err; } for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i))) goto err; if (xa && !PKCS7_bio_add_digest(&out, xa)) goto err; if (evp_cipher != NULL) { unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char iv[EVP_MAX_IV_LENGTH]; int keylen, ivlen; EVP_CIPHER_CTX *ctx; if ((btmp = BIO_new(BIO_f_cipher())) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT, ERR_R_BIO_LIB); goto err; } BIO_get_cipher_ctx(btmp, &ctx); keylen = EVP_CIPHER_key_length(evp_cipher); ivlen = EVP_CIPHER_iv_length(evp_cipher); xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher)); if (ivlen > 0) arc4random_buf(iv, ivlen); if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1) <= 0) goto err; if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0) goto err; if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0) goto err; if (ivlen > 0) { if (xalg->parameter == NULL) { xalg->parameter = ASN1_TYPE_new(); if (xalg->parameter == NULL) goto err; } if (EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0) goto err; } /* Lets do the pub key stuff :-) */ for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri = sk_PKCS7_RECIP_INFO_value(rsk, i); if (pkcs7_encode_rinfo(ri, key, keylen) <= 0) goto err; } explicit_bzero(key, keylen); if (out == NULL) out = btmp; else BIO_push(out, btmp); btmp = NULL; } if (bio == NULL) { if (PKCS7_is_detached(p7)) bio = BIO_new(BIO_s_null()); else if (os && os->length > 0) bio = BIO_new_mem_buf(os->data, os->length); if (bio == NULL) { bio = BIO_new(BIO_s_mem()); if (bio == NULL) goto err; BIO_set_mem_eof_return(bio, 0); } } if (out) BIO_push(out, bio); else out = bio; bio = NULL; if (0) { err: if (out != NULL) BIO_free_all(out); if (btmp != NULL) BIO_free_all(btmp); out = NULL; } return (out); }
void cipher_context_set_iv(cipher_ctx_t *ctx, uint8_t *iv, size_t iv_len, int enc) { const unsigned char *true_key; if (iv == NULL) { LOGE("cipher_context_set_iv(): IV is null"); return; } if (!enc) { memcpy(ctx->iv, iv, iv_len); } if (enc_method >= SALSA20) { return; } if (enc_method == RC4_MD5) { unsigned char key_iv[32]; memcpy(key_iv, enc_key, 16); memcpy(key_iv + 16, iv, 16); true_key = enc_md5(key_iv, 32, NULL); iv_len = 0; } else { true_key = enc_key; } #ifdef USE_CRYPTO_APPLECC cipher_cc_t *cc = &ctx->cc; if (cc->valid == kCCContextValid) { memcpy(cc->iv, iv, iv_len); memcpy(cc->key, true_key, enc_key_len); cc->iv_len = iv_len; cc->key_len = enc_key_len; cc->encrypt = enc ? kCCEncrypt : kCCDecrypt; if (cc->cryptor != NULL) { CCCryptorRelease(cc->cryptor); cc->cryptor = NULL; } CCCryptorStatus ret; ret = CCCryptorCreateWithMode( cc->encrypt, cc->mode, cc->cipher, cc->padding, cc->iv, cc->key, cc->key_len, NULL, 0, 0, 0, &cc->cryptor); if (ret != kCCSuccess) { if (cc->cryptor != NULL) { CCCryptorRelease(cc->cryptor); cc->cryptor = NULL; } FATAL("Cannot set CommonCrypto key and IV"); } return; } #endif cipher_evp_t *evp = &ctx->evp; if (evp == NULL) { LOGE("cipher_context_set_iv(): Cipher context is null"); return; } #if defined(USE_CRYPTO_OPENSSL) if (!EVP_CipherInit_ex(evp, NULL, NULL, true_key, iv, enc)) { EVP_CIPHER_CTX_cleanup(evp); FATAL("Cannot set key and IV"); } #elif defined(USE_CRYPTO_POLARSSL) // XXX: PolarSSL 1.3.11: cipher_free_ctx deprecated, Use cipher_free() instead. if (cipher_setkey(evp, true_key, enc_key_len * 8, enc) != 0) { cipher_free_ctx(evp); FATAL("Cannot set PolarSSL cipher key"); } #if POLARSSL_VERSION_NUMBER >= 0x01030000 if (cipher_set_iv(evp, iv, iv_len) != 0) { cipher_free_ctx(evp); FATAL("Cannot set PolarSSL cipher IV"); } if (cipher_reset(evp) != 0) { cipher_free_ctx(evp); FATAL("Cannot finalize PolarSSL cipher context"); } #else if (cipher_reset(evp, iv) != 0) { cipher_free_ctx(evp); FATAL("Cannot set PolarSSL cipher IV"); } #endif #elif defined(USE_CRYPTO_MBEDTLS) if (mbedtls_cipher_setkey(evp, true_key, enc_key_len * 8, enc) != 0) { mbedtls_cipher_free(evp); FATAL("Cannot set mbed TLS cipher key"); } if (mbedtls_cipher_set_iv(evp, iv, iv_len) != 0) { mbedtls_cipher_free(evp); FATAL("Cannot set mbed TLS cipher IV"); } if (mbedtls_cipher_reset(evp) != 0) { mbedtls_cipher_free(evp); FATAL("Cannot finalize mbed TLS cipher context"); } #endif #ifdef DEBUG dump("IV", (char *)iv, iv_len); #endif }
int tls1_change_cipher_state(SSL *s, int which) { static const unsigned char empty[]=""; unsigned char *p,*key_block,*mac_secret; unsigned char *exp_label; unsigned char tmp1[EVP_MAX_KEY_LENGTH]; unsigned char tmp2[EVP_MAX_KEY_LENGTH]; unsigned char iv1[EVP_MAX_IV_LENGTH*2]; unsigned char iv2[EVP_MAX_IV_LENGTH*2]; unsigned char *ms,*key,*iv,*er1,*er2; int client_write; EVP_CIPHER_CTX *dd; const EVP_CIPHER *c; #ifndef OPENSSL_NO_COMP const SSL_COMP *comp; #endif const EVP_MD *m; int mac_type; int *mac_secret_size; EVP_MD_CTX *mac_ctx; EVP_PKEY *mac_key; int is_export,n,i,j,k,exp_label_len,cl; int reuse_dd = 0; is_export=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); c=s->s3->tmp.new_sym_enc; m=s->s3->tmp.new_hash; mac_type = s->s3->tmp.new_mac_pkey_type; #ifndef OPENSSL_NO_COMP comp=s->s3->tmp.new_compression; #endif key_block=s->s3->tmp.key_block; #ifdef KSSL_DEBUG printf("tls1_change_cipher_state(which= %d) w/\n", which); printf("\talg= %ld/%ld, comp= %p\n", s->s3->tmp.new_cipher->algorithm_mkey, s->s3->tmp.new_cipher->algorithm_auth, comp); printf("\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", c); printf("\tevp_cipher: nid, blksz= %d, %d, keylen=%d, ivlen=%d\n", c->nid,c->block_size,c->key_len,c->iv_len); printf("\tkey_block: len= %d, data= ", s->s3->tmp.key_block_length); { int i; for (i=0; i<s->s3->tmp.key_block_length; i++) printf("%02x", key_block[i]); printf("\n"); } #endif /* KSSL_DEBUG */ if (which & SSL3_CC_READ) { if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM; else s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM; if (s->enc_read_ctx != NULL) reuse_dd = 1; else if ((s->enc_read_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) goto err; else /* make sure it's intialized in case we exit later with an error */ EVP_CIPHER_CTX_init(s->enc_read_ctx); dd= s->enc_read_ctx; mac_ctx=ssl_replace_hash(&s->read_hash,NULL); #ifndef OPENSSL_NO_COMP if (s->expand != NULL) { COMP_CTX_free(s->expand); s->expand=NULL; } if (comp != NULL) { s->expand=COMP_CTX_new(comp->method); if (s->expand == NULL) { SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR); goto err2; } if (s->s3->rrec.comp == NULL) s->s3->rrec.comp=(unsigned char *) OPENSSL_malloc(SSL3_RT_MAX_ENCRYPTED_LENGTH); if (s->s3->rrec.comp == NULL) goto err; } #endif /* this is done by dtls1_reset_seq_numbers for DTLS1_VERSION */ if (s->version != DTLS1_VERSION) memset(&(s->s3->read_sequence[0]),0,8); mac_secret= &(s->s3->read_mac_secret[0]); mac_secret_size=&(s->s3->read_mac_secret_size); } else { if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM; else s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM; if (s->enc_write_ctx != NULL) reuse_dd = 1; else if ((s->enc_write_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) goto err; else /* make sure it's intialized in case we exit later with an error */ EVP_CIPHER_CTX_init(s->enc_write_ctx); dd= s->enc_write_ctx; mac_ctx = ssl_replace_hash(&s->write_hash,NULL); #ifndef OPENSSL_NO_COMP if (s->compress != NULL) { COMP_CTX_free(s->compress); s->compress=NULL; } if (comp != NULL) { s->compress=COMP_CTX_new(comp->method); if (s->compress == NULL) { SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR); goto err2; } } #endif /* this is done by dtls1_reset_seq_numbers for DTLS1_VERSION */ if (s->version != DTLS1_VERSION) memset(&(s->s3->write_sequence[0]),0,8); mac_secret= &(s->s3->write_mac_secret[0]); mac_secret_size = &(s->s3->write_mac_secret_size); } if (reuse_dd) EVP_CIPHER_CTX_cleanup(dd); p=s->s3->tmp.key_block; i=*mac_secret_size=s->s3->tmp.new_mac_secret_size; cl=EVP_CIPHER_key_length(c); j=is_export ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ? cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl; /* Was j=(exp)?5:EVP_CIPHER_key_length(c); */ k=EVP_CIPHER_iv_length(c); er1= &(s->s3->client_random[0]); er2= &(s->s3->server_random[0]); if ( (which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || (which == SSL3_CHANGE_CIPHER_SERVER_READ)) { ms= &(p[ 0]); n=i+i; key= &(p[ n]); n+=j+j; iv= &(p[ n]); n+=k+k; exp_label=(unsigned char *)TLS_MD_CLIENT_WRITE_KEY_CONST; exp_label_len=TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE; client_write=1; } else { n=i; ms= &(p[ n]); n+=i+j; key= &(p[ n]); n+=j+k; iv= &(p[ n]); n+=k; exp_label=(unsigned char *)TLS_MD_SERVER_WRITE_KEY_CONST; exp_label_len=TLS_MD_SERVER_WRITE_KEY_CONST_SIZE; client_write=0; } if (n > s->s3->tmp.key_block_length) { SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_INTERNAL_ERROR); goto err2; } memcpy(mac_secret,ms,i); mac_key = EVP_PKEY_new_mac_key(mac_type, NULL, mac_secret,*mac_secret_size); EVP_DigestSignInit(mac_ctx,NULL,m,NULL,mac_key); EVP_PKEY_free(mac_key); #ifdef TLS_DEBUG printf("which = %04X\nmac key=",which); { int z; for (z=0; z<i; z++) printf("%02X%c",ms[z],((z+1)%16)?' ':'\n'); } #endif if (is_export) { /* In here I set both the read and write key/iv to the * same value since only the correct one will be used :-). */ tls1_PRF(s->s3->tmp.new_cipher->algorithm2, exp_label,exp_label_len, s->s3->client_random,SSL3_RANDOM_SIZE, s->s3->server_random,SSL3_RANDOM_SIZE, NULL,0,NULL,0, key,j,tmp1,tmp2,EVP_CIPHER_key_length(c)); key=tmp1; if (k > 0) { tls1_PRF(s->s3->tmp.new_cipher->algorithm2, TLS_MD_IV_BLOCK_CONST,TLS_MD_IV_BLOCK_CONST_SIZE, s->s3->client_random,SSL3_RANDOM_SIZE, s->s3->server_random,SSL3_RANDOM_SIZE, NULL,0,NULL,0, empty,0,iv1,iv2,k*2); if (client_write) iv=iv1; else iv= &(iv1[k]); } } s->session->key_arg_length=0; #ifdef KSSL_DEBUG { int i; printf("EVP_CipherInit_ex(dd,c,key=,iv=,which)\n"); printf("\tkey= "); for (i=0; i<c->key_len; i++) printf("%02x", key[i]); printf("\n"); printf("\t iv= "); for (i=0; i<c->iv_len; i++) printf("%02x", iv[i]); printf("\n"); } #endif /* KSSL_DEBUG */ EVP_CipherInit_ex(dd,c,NULL,key,iv,(which & SSL3_CC_WRITE)); #ifdef TLS_DEBUG printf("which = %04X\nkey=",which); { int z; for (z=0; z<EVP_CIPHER_key_length(c); z++) printf("%02X%c",key[z],((z+1)%16)?' ':'\n'); } printf("\niv="); { int z; for (z=0; z<k; z++) printf("%02X%c",iv[z],((z+1)%16)?' ':'\n'); } printf("\n"); #endif OPENSSL_cleanse(tmp1,sizeof(tmp1)); OPENSSL_cleanse(tmp2,sizeof(tmp1)); OPENSSL_cleanse(iv1,sizeof(iv1)); OPENSSL_cleanse(iv2,sizeof(iv2)); return(1); err: SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_MALLOC_FAILURE); err2: return(0); }
BUF_MEM * retail_mac_des(const BUF_MEM * key, const BUF_MEM * in) { /* ISO 9797-1 algorithm 3 retail mac without any padding */ BUF_MEM * c_tmp = NULL, *d_tmp = NULL, *mac = NULL, *block = NULL; EVP_CIPHER_CTX * ctx = NULL; size_t len; check(key, "Invalid arguments"); /* Flawfinder: ignore */ len = EVP_CIPHER_block_size(EVP_des_cbc()); check(key->length >= 2*len, "Key too short"); ctx = EVP_CIPHER_CTX_new(); if (!ctx) goto err; EVP_CIPHER_CTX_init(ctx); /* Flawfinder: ignore */ if (!EVP_CipherInit_ex(ctx, EVP_des_cbc(), NULL, (unsigned char *) key->data, NULL, 1) || !EVP_CIPHER_CTX_set_padding(ctx, 0)) goto err; /* get last block of des_cbc encrypted input */ /* Flawfinder: ignore */ c_tmp = cipher(ctx, EVP_des_cbc(), NULL, NULL, NULL, 1, in); if (!c_tmp) goto err; block = BUF_MEM_create_init(c_tmp->data + c_tmp->length - len, len); /* decrypt last block with the rest of the key */ /* IV is always NULL */ /* Flawfinder: ignore */ if (!block || !EVP_CipherInit_ex(ctx, EVP_des_cbc(), NULL, (unsigned char *) key->data + len, NULL, 0) || !EVP_CIPHER_CTX_set_padding(ctx, 0)) goto err; /* Flawfinder: ignore */ d_tmp = cipher(ctx, EVP_des_cbc(), NULL, NULL, NULL, 0, block); /* encrypt last block with the first key */ /* IV is always NULL */ /* Flawfinder: ignore */ if (!d_tmp || !EVP_CipherInit_ex(ctx, EVP_des_cbc(), NULL, (unsigned char *) key->data, NULL, 1) || !EVP_CIPHER_CTX_set_padding(ctx, 0)) goto err; /* Flawfinder: ignore */ mac = cipher(ctx, EVP_des_cbc(), NULL, NULL, NULL, 1, d_tmp); BUF_MEM_free(block); BUF_MEM_free(c_tmp); BUF_MEM_free(d_tmp); EVP_CIPHER_CTX_free(ctx); return mac; err: if (block) BUF_MEM_free(block); if (c_tmp) BUF_MEM_free(c_tmp); if (d_tmp) BUF_MEM_free(d_tmp); if (ctx) EVP_CIPHER_CTX_free(ctx); return NULL; }
OM_uint32 _gssapi_get_mic_arcfour(OM_uint32 * minor_status, const gsskrb5_ctx context_handle, krb5_context context, gss_qop_t qop_req, const gss_buffer_t message_buffer, gss_buffer_t message_token, krb5_keyblock *key) { krb5_error_code ret; int32_t seq_number; size_t len, total_len; u_char k6_data[16], *p0, *p; EVP_CIPHER_CTX rc4_key; _gsskrb5_encap_length (22, &len, &total_len, GSS_KRB5_MECHANISM); message_token->length = total_len; message_token->value = malloc (total_len); if (message_token->value == NULL) { *minor_status = ENOMEM; return GSS_S_FAILURE; } p0 = _gssapi_make_mech_header(message_token->value, len, GSS_KRB5_MECHANISM); p = p0; *p++ = 0x01; /* TOK_ID */ *p++ = 0x01; *p++ = 0x11; /* SGN_ALG */ *p++ = 0x00; *p++ = 0xff; /* Filler */ *p++ = 0xff; *p++ = 0xff; *p++ = 0xff; p = NULL; ret = arcfour_mic_cksum(context, key, KRB5_KU_USAGE_SIGN, p0 + 16, 8, /* SGN_CKSUM */ p0, 8, /* TOK_ID, SGN_ALG, Filer */ message_buffer->value, message_buffer->length, NULL, 0); if (ret) { _gsskrb5_release_buffer(minor_status, message_token); *minor_status = ret; return GSS_S_FAILURE; } ret = arcfour_mic_key(context, key, p0 + 16, 8, /* SGN_CKSUM */ k6_data, sizeof(k6_data)); if (ret) { _gsskrb5_release_buffer(minor_status, message_token); *minor_status = ret; return GSS_S_FAILURE; } HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); krb5_auth_con_getlocalseqnumber (context, context_handle->auth_context, &seq_number); p = p0 + 8; /* SND_SEQ */ _gss_mg_encode_be_uint32(seq_number, p); krb5_auth_con_setlocalseqnumber (context, context_handle->auth_context, ++seq_number); HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); memset (p + 4, (context_handle->more_flags & LOCAL) ? 0 : 0xff, 4); EVP_CIPHER_CTX_init(&rc4_key); EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1); EVP_Cipher(&rc4_key, p, p, 8); EVP_CIPHER_CTX_cleanup(&rc4_key); memset(k6_data, 0, sizeof(k6_data)); *minor_status = 0; return GSS_S_COMPLETE; }
X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, unsigned char *salt, int saltlen, unsigned char *aiv, int prf_nid) { X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL; int alg_nid, keylen; EVP_CIPHER_CTX ctx; unsigned char iv[EVP_MAX_IV_LENGTH]; PBE2PARAM *pbe2 = NULL; const ASN1_OBJECT *obj; alg_nid = EVP_CIPHER_nid(cipher); if(alg_nid == NID_undef) { OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbe2_set_iv, PKCS8_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 = (ASN1_OBJECT*) obj; if(!(scheme->parameter = ASN1_TYPE_new())) goto merr; /* Create random IV */ if (EVP_CIPHER_iv_length(cipher)) { if (aiv) memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher)); else if (RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0) goto err; } EVP_CIPHER_CTX_init(&ctx); /* Dummy cipherinit to just setup the IV, and PRF */ if (!EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0)) goto err; if(param_to_asn1(&ctx, scheme->parameter) < 0) { OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbe2_set_iv, PKCS8_R_ERROR_SETTING_CIPHER_PARAMS); EVP_CIPHER_CTX_cleanup(&ctx); goto err; } /* If prf NID unspecified see if cipher has a preference. * An error is OK here: just means use default PRF. */ if ((prf_nid == -1) && EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0) { ERR_clear_error(); prf_nid = NID_hmacWithSHA1; } EVP_CIPHER_CTX_cleanup(&ctx); /* If its RC2 then we'd better setup the key length */ if(alg_nid == NID_rc2_cbc) keylen = EVP_CIPHER_key_length(cipher); else keylen = -1; /* Setup keyfunc */ X509_ALGOR_free(pbe2->keyfunc); pbe2->keyfunc = PKCS5_pbkdf2_set(iter, salt, saltlen, prf_nid, keylen); if (!pbe2->keyfunc) goto merr; /* Now set up top level AlgorithmIdentifier */ if(!(ret = X509_ALGOR_new())) goto merr; if(!(ret->parameter = ASN1_TYPE_new())) goto merr; ret->algorithm = (ASN1_OBJECT*) OBJ_nid2obj(NID_pbes2); /* Encode PBE2PARAM into parameter */ if(!ASN1_item_pack(pbe2, ASN1_ITEM_rptr(PBE2PARAM), &ret->parameter->value.sequence)) goto merr; ret->parameter->type = V_ASN1_SEQUENCE; PBE2PARAM_free(pbe2); pbe2 = NULL; return ret; merr: OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbe2_set_iv, ERR_R_MALLOC_FAILURE); err: PBE2PARAM_free(pbe2); /* Note 'scheme' is freed as part of pbe2 */ X509_ALGOR_free(kalg); X509_ALGOR_free(ret); return NULL; }
OM_uint32 _gssapi_wrap_arcfour(OM_uint32 * minor_status, const gsskrb5_ctx context_handle, krb5_context context, int conf_req_flag, gss_qop_t qop_req, const gss_buffer_t input_message_buffer, int * conf_state, gss_buffer_t output_message_buffer, krb5_keyblock *key) { u_char Klocaldata[16], k6_data[16], *p, *p0; size_t len, total_len, datalen; krb5_keyblock Klocal; krb5_error_code ret; int32_t seq_number; if (conf_state) *conf_state = 0; datalen = input_message_buffer->length; if (IS_DCE_STYLE(context_handle)) { len = GSS_ARCFOUR_WRAP_TOKEN_SIZE; _gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM); total_len += datalen; } else { datalen += 1; /* padding */ len = datalen + GSS_ARCFOUR_WRAP_TOKEN_SIZE; _gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM); } output_message_buffer->length = total_len; output_message_buffer->value = malloc (total_len); if (output_message_buffer->value == NULL) { *minor_status = ENOMEM; return GSS_S_FAILURE; } p0 = _gssapi_make_mech_header(output_message_buffer->value, len, GSS_KRB5_MECHANISM); p = p0; *p++ = 0x02; /* TOK_ID */ *p++ = 0x01; *p++ = 0x11; /* SGN_ALG */ *p++ = 0x00; if (conf_req_flag) { *p++ = 0x10; /* SEAL_ALG */ *p++ = 0x00; } else { *p++ = 0xff; /* SEAL_ALG */ *p++ = 0xff; } *p++ = 0xff; /* Filler */ *p++ = 0xff; p = NULL; HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); krb5_auth_con_getlocalseqnumber (context, context_handle->auth_context, &seq_number); _gss_mg_encode_be_uint32(seq_number, p0 + 8); krb5_auth_con_setlocalseqnumber (context, context_handle->auth_context, ++seq_number); HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); memset (p0 + 8 + 4, (context_handle->more_flags & LOCAL) ? 0 : 0xff, 4); krb5_generate_random_block(p0 + 24, 8); /* fill in Confounder */ /* p points to data */ p = p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE; memcpy(p, input_message_buffer->value, input_message_buffer->length); if (!IS_DCE_STYLE(context_handle)) p[input_message_buffer->length] = 1; /* padding */ ret = arcfour_mic_cksum(context, key, KRB5_KU_USAGE_SEAL, p0 + 16, 8, /* SGN_CKSUM */ p0, 8, /* TOK_ID, SGN_ALG, SEAL_ALG, Filler */ p0 + 24, 8, /* Confounder */ p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE, datalen); if (ret) { *minor_status = ret; _gsskrb5_release_buffer(minor_status, output_message_buffer); return GSS_S_FAILURE; } { int i; Klocal.keytype = key->keytype; Klocal.keyvalue.data = Klocaldata; Klocal.keyvalue.length = sizeof(Klocaldata); for (i = 0; i < 16; i++) Klocaldata[i] = ((u_char *)key->keyvalue.data)[i] ^ 0xF0; } ret = arcfour_mic_key(context, &Klocal, p0 + 8, 4, /* SND_SEQ */ k6_data, sizeof(k6_data)); memset(Klocaldata, 0, sizeof(Klocaldata)); if (ret) { _gsskrb5_release_buffer(minor_status, output_message_buffer); *minor_status = ret; return GSS_S_FAILURE; } if(conf_req_flag) { EVP_CIPHER_CTX rc4_key; EVP_CIPHER_CTX_init(&rc4_key); EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1); EVP_Cipher(&rc4_key, p0 + 24, p0 + 24, 8 + datalen); EVP_CIPHER_CTX_cleanup(&rc4_key); } memset(k6_data, 0, sizeof(k6_data)); ret = arcfour_mic_key(context, key, p0 + 16, 8, /* SGN_CKSUM */ k6_data, sizeof(k6_data)); if (ret) { _gsskrb5_release_buffer(minor_status, output_message_buffer); *minor_status = ret; return GSS_S_FAILURE; } { EVP_CIPHER_CTX rc4_key; EVP_CIPHER_CTX_init(&rc4_key); EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1); EVP_Cipher(&rc4_key, p0 + 8, p0 + 8 /* SND_SEQ */, 8); EVP_CIPHER_CTX_cleanup(&rc4_key); memset(k6_data, 0, sizeof(k6_data)); } if (conf_state) *conf_state = conf_req_flag; *minor_status = 0; return GSS_S_COMPLETE; }
static long enc_ctrl(BIO *b, int cmd, long num, void *ptr) { BIO *dbio; BIO_ENC_CTX *ctx,*dctx; long ret=1; int i; EVP_CIPHER_CTX **c_ctx; ctx=(BIO_ENC_CTX *)b->ptr; switch (cmd) { case BIO_CTRL_RESET: ctx->ok=1; ctx->finished=0; EVP_CipherInit_ex(&(ctx->cipher),NULL,NULL,NULL,NULL, ctx->cipher.encrypt); 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=enc_write(b,NULL,0); if (i < 0) return i; } if (!ctx->finished) { ctx->finished=1; ctx->buf_off=0; ret=EVP_CipherFinal_ex(&(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_C_GET_CIPHER_CTX: c_ctx=(EVP_CIPHER_CTX **)ptr; (*c_ctx)= &(ctx->cipher); b->init=1; 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); }
BIO * PKCS7_dataInit(PKCS7 *p7, BIO *bio) { int i; BIO *out = NULL, *btmp = NULL; X509_ALGOR *xa = NULL; const EVP_CIPHER *evp_cipher = NULL; STACK_OF(X509_ALGOR) *md_sk = NULL; STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL; X509_ALGOR *xalg = NULL; PKCS7_RECIP_INFO *ri = NULL; ASN1_OCTET_STRING *os = NULL; i = OBJ_obj2nid(p7->type); p7->state = PKCS7_S_HEADER; switch (i) { case NID_pkcs7_signed: md_sk = p7->d.sign->md_algs; os = PKCS7_get_octet_string(p7->d.sign->contents); break; case NID_pkcs7_signedAndEnveloped: rsk = p7->d.signed_and_enveloped->recipientinfo; md_sk = p7->d.signed_and_enveloped->md_algs; xalg = p7->d.signed_and_enveloped->enc_data->algorithm; evp_cipher = p7->d.signed_and_enveloped->enc_data->cipher; if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED); goto err; } break; case NID_pkcs7_enveloped: rsk = p7->d.enveloped->recipientinfo; xalg = p7->d.enveloped->enc_data->algorithm; evp_cipher = p7->d.enveloped->enc_data->cipher; if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED); goto err; } break; case NID_pkcs7_digest: xa = p7->d.digest->md; os = PKCS7_get_octet_string(p7->d.digest->contents); break; case NID_pkcs7_data: break; default: PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); goto err; } for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i))) goto err; if (xa && !PKCS7_bio_add_digest(&out, xa)) goto err; if (evp_cipher != NULL) { unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char iv[EVP_MAX_IV_LENGTH]; int keylen, ivlen; EVP_CIPHER_CTX *ctx; if ((btmp = BIO_new(BIO_f_cipher())) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT, ERR_R_BIO_LIB); goto err; } BIO_get_cipher_ctx(btmp, &ctx); keylen = EVP_CIPHER_key_length(evp_cipher); ivlen = EVP_CIPHER_iv_length(evp_cipher); xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher)); if (ivlen > 0) if (RAND_pseudo_bytes(iv, ivlen) <= 0) goto err; if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1) <= 0) goto err; if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0) goto err; if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0) goto err; if (ivlen > 0) { if (xalg->parameter == NULL) { xalg->parameter = ASN1_TYPE_new(); if (xalg->parameter == NULL) goto err; } if (EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0) goto err; } /* Lets do the pub key stuff :-) */ for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri = sk_PKCS7_RECIP_INFO_value(rsk, i); if (pkcs7_encode_rinfo(ri, key, keylen) <= 0) goto err; } OPENSSL_cleanse(key, keylen); if (out == NULL) out = btmp; else BIO_push(out, btmp); btmp = NULL; } if (bio == NULL) { if (PKCS7_is_detached(p7)) bio = BIO_new(BIO_s_null()); else if (os && os->length > 0) bio = BIO_new_mem_buf(os->data, os->length); if (bio == NULL) { bio = BIO_new(BIO_s_mem()); if (bio == NULL) goto err; BIO_set_mem_eof_return(bio, 0); } } if (out) BIO_push(out, bio); else out = bio; bio = NULL; if (0) { err: if (out != NULL) BIO_free_all(out); if (btmp != NULL) BIO_free_all(btmp); out = NULL; } return (out); }
int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen, ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md, int en_de) { EVP_MD_CTX ctx; unsigned char md_tmp[EVP_MAX_MD_SIZE]; unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; int i; PBEPARAM *pbe; int saltlen, iter; unsigned char *salt; const unsigned char *pbuf; int mdsize; /* Extract useful info from parameter */ if (param == NULL || param->type != V_ASN1_SEQUENCE || param->value.sequence == NULL) { EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN,EVP_R_DECODE_ERROR); return 0; } pbuf = param->value.sequence->data; if (!(pbe = d2i_PBEPARAM(NULL, &pbuf, param->value.sequence->length))) { EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN,EVP_R_DECODE_ERROR); return 0; } if (!pbe->iter) iter = 1; else iter = ASN1_INTEGER_get (pbe->iter); salt = pbe->salt->data; saltlen = pbe->salt->length; if(!pass) passlen = 0; else if(passlen == -1) passlen = TINYCLR_SSL_STRLEN(pass); EVP_MD_CTX_init(&ctx); EVP_DigestInit_ex(&ctx, md, NULL); EVP_DigestUpdate(&ctx, pass, passlen); EVP_DigestUpdate(&ctx, salt, saltlen); PBEPARAM_free(pbe); EVP_DigestFinal_ex(&ctx, md_tmp, NULL); mdsize = EVP_MD_size(md); if (mdsize < 0) return 0; for (i = 1; i < iter; i++) { EVP_DigestInit_ex(&ctx, md, NULL); EVP_DigestUpdate(&ctx, md_tmp, mdsize); EVP_DigestFinal_ex (&ctx, md_tmp, NULL); } EVP_MD_CTX_cleanup(&ctx); TINYCLR_SSL_ASSERT(EVP_CIPHER_key_length(cipher) <= (int)sizeof(md_tmp)); TINYCLR_SSL_MEMCPY(key, md_tmp, EVP_CIPHER_key_length(cipher)); TINYCLR_SSL_ASSERT(EVP_CIPHER_iv_length(cipher) <= 16); TINYCLR_SSL_MEMCPY(iv, md_tmp + (16 - EVP_CIPHER_iv_length(cipher)), EVP_CIPHER_iv_length(cipher)); EVP_CipherInit_ex(cctx, cipher, NULL, key, iv, en_de); OPENSSL_cleanse(md_tmp, EVP_MAX_MD_SIZE); OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH); OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH); return 1; }
int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen, ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md, int en_de) { EVP_MD_CTX *ctx; unsigned char md_tmp[EVP_MAX_MD_SIZE]; unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; int i; PBEPARAM *pbe; int saltlen, iter; unsigned char *salt; int mdsize; int rv = 0; /* Extract useful info from parameter */ if (param == NULL || param->type != V_ASN1_SEQUENCE || param->value.sequence == NULL) { EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, EVP_R_DECODE_ERROR); return 0; } pbe = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBEPARAM), param); if (pbe == NULL) { EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, EVP_R_DECODE_ERROR); return 0; } if (!pbe->iter) iter = 1; else iter = ASN1_INTEGER_get(pbe->iter); salt = pbe->salt->data; saltlen = pbe->salt->length; if (!pass) passlen = 0; else if (passlen == -1) passlen = strlen(pass); ctx = EVP_MD_CTX_new(); if (ctx == NULL) { EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, ERR_R_MALLOC_FAILURE); goto err; } if (!EVP_DigestInit_ex(ctx, md, NULL)) goto err; if (!EVP_DigestUpdate(ctx, pass, passlen)) goto err; if (!EVP_DigestUpdate(ctx, salt, saltlen)) goto err; PBEPARAM_free(pbe); if (!EVP_DigestFinal_ex(ctx, md_tmp, NULL)) goto err; mdsize = EVP_MD_size(md); if (mdsize < 0) return 0; for (i = 1; i < iter; i++) { if (!EVP_DigestInit_ex(ctx, md, NULL)) goto err; if (!EVP_DigestUpdate(ctx, md_tmp, mdsize)) goto err; if (!EVP_DigestFinal_ex(ctx, md_tmp, NULL)) goto err; } OPENSSL_assert(EVP_CIPHER_key_length(cipher) <= (int)sizeof(md_tmp)); memcpy(key, md_tmp, EVP_CIPHER_key_length(cipher)); OPENSSL_assert(EVP_CIPHER_iv_length(cipher) <= 16); memcpy(iv, md_tmp + (16 - EVP_CIPHER_iv_length(cipher)), EVP_CIPHER_iv_length(cipher)); if (!EVP_CipherInit_ex(cctx, cipher, NULL, key, iv, en_de)) goto err; OPENSSL_cleanse(md_tmp, EVP_MAX_MD_SIZE); OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH); OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH); rv = 1; err: EVP_MD_CTX_free(ctx); return rv; }
int MAIN(int argc, char **argv) { #ifndef OPENSSL_NO_ENGINE ENGINE *e = NULL; #endif static const char magic[]="Salted__"; char mbuf[sizeof magic-1]; char *strbuf=NULL; unsigned char *buff=NULL,*bufsize=NULL; int bsize=BSIZE,verbose=0; int ret=1,inl; int nopad = 0; unsigned char key[EVP_MAX_KEY_LENGTH],iv[EVP_MAX_IV_LENGTH]; unsigned char salt[PKCS5_SALT_LEN]; char *str=NULL, *passarg = NULL, *pass = NULL; char *hkey=NULL,*hiv=NULL,*hsalt = NULL; char *md=NULL; int enc=1,printkey=0,i,base64=0; int debug=0,olb64=0,nosalt=0; const EVP_CIPHER *cipher=NULL,*c; EVP_CIPHER_CTX *ctx = NULL; char *inf=NULL,*outf=NULL; BIO *in=NULL,*out=NULL,*b64=NULL,*benc=NULL,*rbio=NULL,*wbio=NULL; #define PROG_NAME_SIZE 39 char pname[PROG_NAME_SIZE+1]; #ifndef OPENSSL_NO_ENGINE char *engine = NULL; #endif const EVP_MD *dgst=NULL; int non_fips_allow = 0; apps_startup(); if (bio_err == NULL) if ((bio_err=BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); if (!load_config(bio_err, NULL)) goto end; /* first check the program name */ program_name(argv[0],pname,sizeof pname); if (strcmp(pname,"base64") == 0) base64=1; cipher=EVP_get_cipherbyname(pname); if (!base64 && (cipher == NULL) && (strcmp(pname,"enc") != 0)) { BIO_printf(bio_err,"%s is an unknown cipher\n",pname); goto bad; } argc--; argv++; while (argc >= 1) { if (strcmp(*argv,"-e") == 0) enc=1; else if (strcmp(*argv,"-in") == 0) { if (--argc < 1) goto bad; inf= *(++argv); } else if (strcmp(*argv,"-out") == 0) { if (--argc < 1) goto bad; outf= *(++argv); } else if (strcmp(*argv,"-pass") == 0) { if (--argc < 1) goto bad; passarg= *(++argv); } #ifndef OPENSSL_NO_ENGINE else if (strcmp(*argv,"-engine") == 0) { if (--argc < 1) goto bad; engine= *(++argv); } #endif else if (strcmp(*argv,"-d") == 0) enc=0; else if (strcmp(*argv,"-p") == 0) printkey=1; else if (strcmp(*argv,"-v") == 0) verbose=1; else if (strcmp(*argv,"-nopad") == 0) nopad=1; else if (strcmp(*argv,"-salt") == 0) nosalt=0; else if (strcmp(*argv,"-nosalt") == 0) nosalt=1; else if (strcmp(*argv,"-debug") == 0) debug=1; else if (strcmp(*argv,"-P") == 0) printkey=2; else if (strcmp(*argv,"-A") == 0) olb64=1; else if (strcmp(*argv,"-a") == 0) base64=1; else if (strcmp(*argv,"-base64") == 0) base64=1; else if (strcmp(*argv,"-bufsize") == 0) { if (--argc < 1) goto bad; bufsize=(unsigned char *)*(++argv); } else if (strcmp(*argv,"-k") == 0) { if (--argc < 1) goto bad; str= *(++argv); } else if (strcmp(*argv,"-kfile") == 0) { static char buf[128]; FILE *infile; char *file; if (--argc < 1) goto bad; file= *(++argv); infile=fopen(file,"r"); if (infile == NULL) { BIO_printf(bio_err,"unable to read key from '%s'\n", file); goto bad; } buf[0]='\0'; fgets(buf,sizeof buf,infile); fclose(infile); i=strlen(buf); if ((i > 0) && ((buf[i-1] == '\n') || (buf[i-1] == '\r'))) buf[--i]='\0'; if ((i > 0) && ((buf[i-1] == '\n') || (buf[i-1] == '\r'))) buf[--i]='\0'; if (i < 1) { BIO_printf(bio_err,"zero length password\n"); goto bad; } str=buf; } else if (strcmp(*argv,"-K") == 0) { if (--argc < 1) goto bad; hkey= *(++argv); } else if (strcmp(*argv,"-S") == 0) { if (--argc < 1) goto bad; hsalt= *(++argv); } else if (strcmp(*argv,"-iv") == 0) { if (--argc < 1) goto bad; hiv= *(++argv); } else if (strcmp(*argv,"-md") == 0) { if (--argc < 1) goto bad; md= *(++argv); } else if (strcmp(*argv,"-non-fips-allow") == 0) non_fips_allow = 1; else if ((argv[0][0] == '-') && ((c=EVP_get_cipherbyname(&(argv[0][1]))) != NULL)) { cipher=c; } else if (strcmp(*argv,"-none") == 0) cipher=NULL; else { BIO_printf(bio_err,"unknown option '%s'\n",*argv); bad: BIO_printf(bio_err,"options are\n"); BIO_printf(bio_err,"%-14s input file\n","-in <file>"); BIO_printf(bio_err,"%-14s output file\n","-out <file>"); BIO_printf(bio_err,"%-14s pass phrase source\n","-pass <arg>"); BIO_printf(bio_err,"%-14s encrypt\n","-e"); BIO_printf(bio_err,"%-14s decrypt\n","-d"); BIO_printf(bio_err,"%-14s base64 encode/decode, depending on encryption flag\n","-a/-base64"); BIO_printf(bio_err,"%-14s passphrase is the next argument\n","-k"); BIO_printf(bio_err,"%-14s passphrase is the first line of the file argument\n","-kfile"); BIO_printf(bio_err,"%-14s the next argument is the md to use to create a key\n","-md"); BIO_printf(bio_err,"%-14s from a passphrase. One of md2, md5, sha or sha1\n",""); BIO_printf(bio_err,"%-14s key/iv in hex is the next argument\n","-K/-iv"); BIO_printf(bio_err,"%-14s print the iv/key (then exit if -P)\n","-[pP]"); BIO_printf(bio_err,"%-14s buffer size\n","-bufsize <n>"); #ifndef OPENSSL_NO_ENGINE BIO_printf(bio_err,"%-14s use engine e, possibly a hardware device.\n","-engine e"); #endif BIO_printf(bio_err,"Cipher Types\n"); OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, show_ciphers, bio_err); BIO_printf(bio_err,"\n"); goto end; } argc--; argv++; } #ifndef OPENSSL_NO_ENGINE e = setup_engine(bio_err, engine, 0); #endif if (md && (dgst=EVP_get_digestbyname(md)) == NULL) { BIO_printf(bio_err,"%s is an unsupported message digest type\n",md); goto end; } if (dgst == NULL) { if (in_FIPS_mode) dgst = EVP_sha1(); else dgst = EVP_md5(); } if (bufsize != NULL) { unsigned long n; for (n=0; *bufsize; bufsize++) { i= *bufsize; if ((i <= '9') && (i >= '0')) n=n*10+i-'0'; else if (i == 'k') { n*=1024; bufsize++; break; } } if (*bufsize != '\0') { BIO_printf(bio_err,"invalid 'bufsize' specified.\n"); goto end; } /* It must be large enough for a base64 encoded line */ if (base64 && n < 80) n=80; bsize=(int)n; if (verbose) BIO_printf(bio_err,"bufsize=%d\n",bsize); } strbuf=OPENSSL_malloc(SIZE); buff=(unsigned char *)OPENSSL_malloc(EVP_ENCODE_LENGTH(bsize)); if ((buff == NULL) || (strbuf == NULL)) { BIO_printf(bio_err,"OPENSSL_malloc failure %ld\n",(long)EVP_ENCODE_LENGTH(bsize)); goto end; } in=BIO_new(BIO_s_file()); out=BIO_new(BIO_s_file()); if ((in == NULL) || (out == NULL)) { ERR_print_errors(bio_err); goto end; } if (debug) { BIO_set_callback(in,BIO_debug_callback); BIO_set_callback(out,BIO_debug_callback); BIO_set_callback_arg(in,(char *)bio_err); BIO_set_callback_arg(out,(char *)bio_err); } if (inf == NULL) { if (bufsize != NULL) setvbuf(stdin, (char *)NULL, _IONBF, 0); BIO_set_fp(in,stdin,BIO_NOCLOSE); } else { if (BIO_read_filename(in,inf) <= 0) { perror(inf); goto end; } } if(!str && passarg) { if(!app_passwd(bio_err, passarg, NULL, &pass, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } str = pass; } if ((str == NULL) && (cipher != NULL) && (hkey == NULL)) { for (;;) { char buf[200]; BIO_snprintf(buf,sizeof buf,"enter %s %s password:"******"encryption":"decryption"); strbuf[0]='\0'; i=EVP_read_pw_string((char *)strbuf,SIZE,buf,enc); if (i == 0) { if (strbuf[0] == '\0') { ret=1; goto end; } str=strbuf; break; } if (i < 0) { BIO_printf(bio_err,"bad password read\n"); goto end; } } } if (outf == NULL) { BIO_set_fp(out,stdout,BIO_NOCLOSE); if (bufsize != NULL) setvbuf(stdout, (char *)NULL, _IONBF, 0); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } else { if (BIO_write_filename(out,outf) <= 0) { perror(outf); goto end; } } rbio=in; wbio=out; if (base64) { if ((b64=BIO_new(BIO_f_base64())) == NULL) goto end; if (debug) { BIO_set_callback(b64,BIO_debug_callback); BIO_set_callback_arg(b64,(char *)bio_err); } if (olb64) BIO_set_flags(b64,BIO_FLAGS_BASE64_NO_NL); if (enc) wbio=BIO_push(b64,wbio); else rbio=BIO_push(b64,rbio); } if (cipher != NULL) { /* Note that str is NULL if a key was passed on the command * line, so we get no salt in that case. Is this a bug? */ if (str != NULL) { /* Salt handling: if encrypting generate a salt and * write to output BIO. If decrypting read salt from * input BIO. */ unsigned char *sptr; if(nosalt) sptr = NULL; else { if(enc) { if(hsalt) { if(!set_hex(hsalt,salt,sizeof salt)) { BIO_printf(bio_err, "invalid hex salt value\n"); goto end; } } else if (RAND_pseudo_bytes(salt, sizeof salt) < 0) goto end; /* If -P option then don't bother writing */ if((printkey != 2) && (BIO_write(wbio,magic, sizeof magic-1) != sizeof magic-1 || BIO_write(wbio, (char *)salt, sizeof salt) != sizeof salt)) { BIO_printf(bio_err,"error writing output file\n"); goto end; } } else if(BIO_read(rbio,mbuf,sizeof mbuf) != sizeof mbuf || BIO_read(rbio, (unsigned char *)salt, sizeof salt) != sizeof salt) { BIO_printf(bio_err,"error reading input file\n"); goto end; } else if(memcmp(mbuf,magic,sizeof magic-1)) { BIO_printf(bio_err,"bad magic number\n"); goto end; } sptr = salt; } EVP_BytesToKey(cipher,dgst,sptr, (unsigned char *)str, strlen(str),1,key,iv); /* zero the complete buffer or the string * passed from the command line * bug picked up by * Larry J. Hughes Jr. <*****@*****.**> */ if (str == strbuf) OPENSSL_cleanse(str,SIZE); else OPENSSL_cleanse(str,strlen(str)); } if ((hiv != NULL) && !set_hex(hiv,iv,sizeof iv)) { BIO_printf(bio_err,"invalid hex iv value\n"); goto end; } if ((hiv == NULL) && (str == NULL) && EVP_CIPHER_iv_length(cipher) != 0) { /* No IV was explicitly set and no IV was generated * during EVP_BytesToKey. Hence the IV is undefined, * making correct decryption impossible. */ BIO_printf(bio_err, "iv undefined\n"); goto end; } if ((hkey != NULL) && !set_hex(hkey,key,sizeof key)) { BIO_printf(bio_err,"invalid hex key value\n"); goto end; } if ((benc=BIO_new(BIO_f_cipher())) == NULL) goto end; /* Since we may be changing parameters work on the encryption * context rather than calling BIO_set_cipher(). */ BIO_get_cipher_ctx(benc, &ctx); if (non_fips_allow) EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPH_FLAG_NON_FIPS_ALLOW); if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc)) { BIO_printf(bio_err, "Error setting cipher %s\n", EVP_CIPHER_name(cipher)); ERR_print_errors(bio_err); goto end; } if (nopad) EVP_CIPHER_CTX_set_padding(ctx, 0); if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc)) { BIO_printf(bio_err, "Error setting cipher %s\n", EVP_CIPHER_name(cipher)); ERR_print_errors(bio_err); goto end; } if (debug) { BIO_set_callback(benc,BIO_debug_callback); BIO_set_callback_arg(benc,(char *)bio_err); } if (printkey) { if (!nosalt) { printf("salt="); for (i=0; i<(int)sizeof(salt); i++) printf("%02X",salt[i]); printf("\n"); } if (cipher->key_len > 0) { printf("key="); for (i=0; i<cipher->key_len; i++) printf("%02X",key[i]); printf("\n"); } if (cipher->iv_len > 0) { printf("iv ="); for (i=0; i<cipher->iv_len; i++) printf("%02X",iv[i]); printf("\n"); } if (printkey == 2) { ret=0; goto end; } } } /* Only encrypt/decrypt as we write the file */ if (benc != NULL) wbio=BIO_push(benc,wbio); for (;;) { inl=BIO_read(rbio,(char *)buff,bsize); if (inl <= 0) break; if (BIO_write(wbio,(char *)buff,inl) != inl) { BIO_printf(bio_err,"error writing output file\n"); goto end; } } if (!BIO_flush(wbio)) { BIO_printf(bio_err,"bad decrypt\n"); goto end; } ret=0; if (verbose) { BIO_printf(bio_err,"bytes read :%8ld\n",BIO_number_read(in)); BIO_printf(bio_err,"bytes written:%8ld\n",BIO_number_written(out)); } end: ERR_print_errors(bio_err); if (strbuf != NULL) OPENSSL_free(strbuf); if (buff != NULL) OPENSSL_free(buff); if (in != NULL) BIO_free(in); if (out != NULL) BIO_free_all(out); if (benc != NULL) BIO_free(benc); if (b64 != NULL) BIO_free(b64); if(pass) OPENSSL_free(pass); apps_shutdown(); OPENSSL_EXIT(ret); }
static OM_uint32 verify_mic_des (OM_uint32 * minor_status, const gsskrb5_ctx context_handle, krb5_context context, const gss_buffer_t message_buffer, const gss_buffer_t token_buffer, gss_qop_t * qop_state, krb5_keyblock *key, const char *type ) { u_char *p; EVP_MD_CTX *md5; u_char hash[16], *seq; DES_key_schedule schedule; EVP_CIPHER_CTX des_ctx; DES_cblock zero; DES_cblock deskey; uint32_t seq_number; OM_uint32 ret; int cmp; p = token_buffer->value; ret = _gsskrb5_verify_header (&p, token_buffer->length, type, GSS_KRB5_MECHANISM); if (ret) return ret; if (memcmp(p, "\x00\x00", 2) != 0) return GSS_S_BAD_SIG; p += 2; if (memcmp (p, "\xff\xff\xff\xff", 4) != 0) return GSS_S_BAD_MIC; p += 4; p += 16; /* verify checksum */ md5 = EVP_MD_CTX_create(); EVP_DigestInit_ex(md5, EVP_md5(), NULL); EVP_DigestUpdate(md5, p - 24, 8); EVP_DigestUpdate(md5, message_buffer->value, message_buffer->length); EVP_DigestFinal_ex(md5, hash, NULL); EVP_MD_CTX_destroy(md5); memset (&zero, 0, sizeof(zero)); memcpy (&deskey, key->keyvalue.data, sizeof(deskey)); DES_set_key_unchecked (&deskey, &schedule); DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash), &schedule, &zero); if (ct_memcmp (p - 8, hash, 8) != 0) { memset (deskey, 0, sizeof(deskey)); memset (&schedule, 0, sizeof(schedule)); return GSS_S_BAD_MIC; } /* verify sequence number */ HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); p -= 16; EVP_CIPHER_CTX_init(&des_ctx); EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, key->keyvalue.data, hash, 0); EVP_Cipher(&des_ctx, p, p, 8); EVP_CIPHER_CTX_cleanup(&des_ctx); memset (deskey, 0, sizeof(deskey)); memset (&schedule, 0, sizeof(schedule)); seq = p; _gsskrb5_decode_om_uint32(seq, &seq_number); if (context_handle->more_flags & LOCAL) cmp = ct_memcmp(&seq[4], "\xff\xff\xff\xff", 4); else cmp = ct_memcmp(&seq[4], "\x00\x00\x00\x00", 4); if (cmp != 0) { HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); return GSS_S_BAD_MIC; } ret = _gssapi_msg_order_check(context_handle->order, seq_number); if (ret) { HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); return ret; } HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); return GSS_S_COMPLETE; }
static int test_tls13_encryption(void) { SSL_CTX *ctx = NULL; SSL *s = NULL; SSL3_RECORD rec; unsigned char *key = NULL, *iv = NULL, *seq = NULL; const EVP_CIPHER *ciph = EVP_aes_128_gcm(); int ret = 0; size_t ivlen, ctr; /* * Encrypted TLSv1.3 records always have an outer content type of * application data, and a record version of TLSv1.2. */ rec.data = NULL; rec.type = SSL3_RT_APPLICATION_DATA; rec.rec_version = TLS1_2_VERSION; ctx = SSL_CTX_new(TLS_method()); if (!TEST_ptr(ctx)) { TEST_info("Failed creating SSL_CTX"); goto err; } s = SSL_new(ctx); if (!TEST_ptr(s)) { TEST_info("Failed creating SSL"); goto err; } s->enc_read_ctx = EVP_CIPHER_CTX_new(); if (!TEST_ptr(s->enc_read_ctx)) goto err; s->enc_write_ctx = EVP_CIPHER_CTX_new(); if (!TEST_ptr(s->enc_write_ctx)) goto err; s->s3->tmp.new_cipher = SSL_CIPHER_find(s, TLS13_AES_128_GCM_SHA256_BYTES); if (!TEST_ptr(s->s3->tmp.new_cipher)) { TEST_info("Failed to find cipher"); goto err; } for (ctr = 0; ctr < OSSL_NELEM(refdata); ctr++) { /* Load the record */ ivlen = EVP_CIPHER_iv_length(ciph); if (!load_record(&rec, &refdata[ctr], &key, s->read_iv, ivlen, RECORD_LAYER_get_read_sequence(&s->rlayer))) { TEST_error("Failed loading key into EVP_CIPHER_CTX"); goto err; } /* Set up the read/write sequences */ memcpy(RECORD_LAYER_get_write_sequence(&s->rlayer), RECORD_LAYER_get_read_sequence(&s->rlayer), SEQ_NUM_SIZE); memcpy(s->write_iv, s->read_iv, ivlen); /* Load the key into the EVP_CIPHER_CTXs */ if (EVP_CipherInit_ex(s->enc_write_ctx, ciph, NULL, key, NULL, 1) <= 0 || EVP_CipherInit_ex(s->enc_read_ctx, ciph, NULL, key, NULL, 0) <= 0) { TEST_error("Failed loading key into EVP_CIPHER_CTX\n"); goto err; } /* Encrypt it */ if (!TEST_size_t_eq(tls13_enc(s, &rec, 1, 1), 1)) { TEST_info("Failed to encrypt record %zu", ctr); goto err; } if (!TEST_true(test_record(&rec, &refdata[ctr], 1))) { TEST_info("Record %zu encryption test failed", ctr); goto err; } /* Decrypt it */ if (!TEST_int_eq(tls13_enc(s, &rec, 1, 0), 1)) { TEST_info("Failed to decrypt record %zu", ctr); goto err; } if (!TEST_true(test_record(&rec, &refdata[ctr], 0))) { TEST_info("Record %zu decryption test failed", ctr); goto err; } OPENSSL_free(rec.data); OPENSSL_free(key); OPENSSL_free(iv); OPENSSL_free(seq); rec.data = NULL; key = NULL; iv = NULL; seq = NULL; } TEST_note("PASS: %zu records tested", ctr); ret = 1; err: OPENSSL_free(rec.data); OPENSSL_free(key); OPENSSL_free(iv); OPENSSL_free(seq); SSL_free(s); SSL_CTX_free(ctx); return ret; }
int ssl3_change_cipher_state(SSL *s, int which) { unsigned char *p, *mac_secret; unsigned char exp_key[EVP_MAX_KEY_LENGTH]; unsigned char exp_iv[EVP_MAX_IV_LENGTH]; unsigned char *ms, *key, *iv; EVP_CIPHER_CTX *dd; const EVP_CIPHER *c; #ifndef OPENSSL_NO_COMP COMP_METHOD *comp; #endif const EVP_MD *m; int n, i, j, k, cl; int reuse_dd = 0; c = s->s3->tmp.new_sym_enc; m = s->s3->tmp.new_hash; /* m == NULL will lead to a crash later */ OPENSSL_assert(m); #ifndef OPENSSL_NO_COMP if (s->s3->tmp.new_compression == NULL) comp = NULL; else comp = s->s3->tmp.new_compression->method; #endif if (which & SSL3_CC_READ) { if (s->enc_read_ctx != NULL) reuse_dd = 1; else if ((s->enc_read_ctx = EVP_CIPHER_CTX_new()) == NULL) goto err; else /* * make sure it's initialised in case we exit later with an error */ EVP_CIPHER_CTX_reset(s->enc_read_ctx); dd = s->enc_read_ctx; if (ssl_replace_hash(&s->read_hash, m) == NULL) { SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); goto err2; } #ifndef OPENSSL_NO_COMP /* COMPRESS */ COMP_CTX_free(s->expand); s->expand = NULL; if (comp != NULL) { s->expand = COMP_CTX_new(comp); if (s->expand == NULL) { SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, SSL_R_COMPRESSION_LIBRARY_ERROR); goto err2; } } #endif RECORD_LAYER_reset_read_sequence(&s->rlayer); mac_secret = &(s->s3->read_mac_secret[0]); } else { if (s->enc_write_ctx != NULL) reuse_dd = 1; else if ((s->enc_write_ctx = EVP_CIPHER_CTX_new()) == NULL) goto err; else /* * make sure it's initialised in case we exit later with an error */ EVP_CIPHER_CTX_reset(s->enc_write_ctx); dd = s->enc_write_ctx; if (ssl_replace_hash(&s->write_hash, m) == NULL) { SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); goto err2; } #ifndef OPENSSL_NO_COMP /* COMPRESS */ COMP_CTX_free(s->compress); s->compress = NULL; if (comp != NULL) { s->compress = COMP_CTX_new(comp); if (s->compress == NULL) { SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, SSL_R_COMPRESSION_LIBRARY_ERROR); goto err2; } } #endif RECORD_LAYER_reset_write_sequence(&s->rlayer); mac_secret = &(s->s3->write_mac_secret[0]); } if (reuse_dd) EVP_CIPHER_CTX_reset(dd); p = s->s3->tmp.key_block; i = EVP_MD_size(m); if (i < 0) goto err2; cl = EVP_CIPHER_key_length(c); j = cl; k = EVP_CIPHER_iv_length(c); if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || (which == SSL3_CHANGE_CIPHER_SERVER_READ)) { ms = &(p[0]); n = i + i; key = &(p[n]); n += j + j; iv = &(p[n]); n += k + k; } else { n = i; ms = &(p[n]); n += i + j; key = &(p[n]); n += j + k; iv = &(p[n]); n += k; } if (n > s->s3->tmp.key_block_length) { SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); goto err2; } memcpy(mac_secret, ms, i); EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE)); #ifdef OPENSSL_SSL_TRACE_CRYPTO if (s->msg_callback) { int wh = which & SSL3_CC_WRITE ? TLS1_RT_CRYPTO_WRITE : TLS1_RT_CRYPTO_READ; s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_MAC, mac_secret, EVP_MD_size(m), s, s->msg_callback_arg); if (c->key_len) s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_KEY, key, c->key_len, s, s->msg_callback_arg); if (k) { s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_IV, iv, k, s, s->msg_callback_arg); } } #endif OPENSSL_cleanse(exp_key, sizeof(exp_key)); OPENSSL_cleanse(exp_iv, sizeof(exp_iv)); return (1); err: SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE); err2: OPENSSL_cleanse(exp_key, sizeof(exp_key)); OPENSSL_cleanse(exp_iv, sizeof(exp_iv)); return (0); }
int AesFileEnc::do_crypt(FILE *in, FILE *out, int do_encrypt) { /* Allow enough space in output buffer for additional block */ unsigned char inbuf[1024], outbuf[1024 + EVP_MAX_BLOCK_LENGTH]; int inlen, outlen; EVP_CIPHER_CTX ctx; std::cout << "tutaj"; unsigned char* key = this->key(); // std::cout <<key<<std::endl; //unsigned char key[] = "0123456789abcdeF"; std::cout <<key<< std::endl; //unsigned char iv[] = "1234567887654321"; EVP_CIPHER_CTX_init(&ctx); switch(this->type) { case cbc128: EVP_CipherInit_ex(&ctx, EVP_aes_128_cbc(), NULL, NULL, NULL, do_encrypt); break; case cbc192: EVP_CipherInit_ex(&ctx, EVP_aes_192_cbc(), NULL, NULL, NULL, do_encrypt); break; case cbc256: EVP_CipherInit_ex(&ctx, EVP_aes_256_cbc(), NULL, NULL, NULL, do_encrypt); break; case ecb128: EVP_CipherInit_ex(&ctx, EVP_aes_128_ecb(), NULL, NULL, NULL, do_encrypt); break; case ecb192: EVP_CipherInit_ex(&ctx, EVP_aes_192_ecb(), NULL, NULL, NULL, do_encrypt); break; case ecb256: EVP_CipherInit_ex(&ctx, EVP_aes_256_ecb(), NULL, NULL, NULL, do_encrypt); break; case cfb128: EVP_CipherInit_ex(&ctx, EVP_aes_128_cfb(), NULL, NULL, NULL, do_encrypt); break; case cfb192: EVP_CipherInit_ex(&ctx, EVP_aes_192_cfb(), NULL, NULL, NULL, do_encrypt); break; case cfb256: EVP_CipherInit_ex(&ctx, EVP_aes_256_cfb(), NULL, NULL, NULL, do_encrypt); break; case ofb128: EVP_CipherInit_ex(&ctx, EVP_aes_128_ofb(), NULL, NULL, NULL, do_encrypt); break; case ofb192: EVP_CipherInit_ex(&ctx, EVP_aes_192_ofb(), NULL, NULL, NULL, do_encrypt); break; case ofb256: EVP_CipherInit_ex(&ctx, EVP_aes_256_ofb(), NULL, NULL, NULL, do_encrypt); break; } unsigned char *iv = this->iv(EVP_CIPHER_CTX_iv_length(&ctx)); std::cout<< this->keyLength << std::endl; std::cout<< EVP_CIPHER_CTX_iv_length(&ctx) <<std::endl; OPENSSL_assert(EVP_CIPHER_CTX_key_length(&ctx) == this->keyLength); //OPENSSL_assert(EVP_CIPHER_CTX_iv_length(&ctx) == this->keyLength); EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, do_encrypt); for(;;) { inlen = fread(inbuf, 1, 1024, in); if(inlen <= 0) break; if(!EVP_CipherUpdate(&ctx, outbuf, &outlen, inbuf, inlen)) { EVP_CIPHER_CTX_cleanup(&ctx); return 0; } fwrite(outbuf, 1, outlen, out); } if(!EVP_CipherFinal_ex(&ctx, outbuf, &outlen)) { EVP_CIPHER_CTX_cleanup(&ctx); return 0; } fwrite(outbuf, 1, outlen, out); EVP_CIPHER_CTX_cleanup(&ctx); return 1; }