int ssl_setup(SSL_CTX **ctxp, struct pki *pki, int (*sni_cb)(SSL *,int *,void *), const char *ciphers) { DH *dh; SSL_CTX *ctx; uint8_t sid[SSL_MAX_SID_CTX_LENGTH]; ctx = ssl_ctx_create(pki->pki_name, pki->pki_cert, pki->pki_cert_len, ciphers); /* * Set session ID context to a random value. We don't support * persistent caching of sessions so it is OK to set a temporary * session ID context that is valid during run time. */ arc4random_buf(sid, sizeof(sid)); if (!SSL_CTX_set_session_id_context(ctx, sid, sizeof(sid))) goto err; if (sni_cb) SSL_CTX_set_tlsext_servername_callback(ctx, sni_cb); if (pki->pki_dhparams_len == 0) dh = get_dh2048(); else dh = get_dh_from_memory(pki->pki_dhparams, pki->pki_dhparams_len); ssl_set_ephemeral_key_exchange(ctx, dh); DH_free(dh); SSL_CTX_set_ecdh_auto(ctx, 1); *ctxp = ctx; return 1; err: SSL_CTX_free(ctx); ssl_error("ssl_setup"); return 0; }
char * create_key(int bits) { int i, j; char *hexkey; u_char *key; key = xmalloc(bits / 8); hexkey = xmalloc((bits / 4) + 1); arc4random_buf(key, bits / 8); for (i = j = 0; i < (bits / 8); i++) { snprintf(hexkey + j, 3, "%02x", key[i]); j += 2; } hexkey[j] = '\0'; bzero(key, bits / 8); free(key); return(hexkey); }
/* * Enable multicast routing */ int ip6_mrouter_init(struct socket *so, int v, int cmd) { #ifdef MRT6DEBUG if (mrt6debug) log(LOG_DEBUG, "ip6_mrouter_init: so_type = %d, pr_protocol = %d\n", so->so_type, so->so_proto->pr_protocol); #endif if (so->so_type != SOCK_RAW || so->so_proto->pr_protocol != IPPROTO_ICMPV6) return (EOPNOTSUPP); if (v != 1) return (ENOPROTOOPT); if (ip6_mrouter != NULL) return (EADDRINUSE); ip6_mrouter = so; ip6_mrouter_ver = cmd; bzero((caddr_t)mf6ctable, sizeof(mf6ctable)); arc4random_buf(&mf6chashkey, sizeof(mf6chashkey)); bzero((caddr_t)n6expire, sizeof(n6expire)); pim6 = 0;/* used for stubbing out/in pim stuff */ timeout_set(&expire_upcalls6_ch, expire_upcalls6, NULL); timeout_add(&expire_upcalls6_ch, EXPIRE_TIMEOUT); #ifdef MRT6DEBUG if (mrt6debug) log(LOG_DEBUG, "ip6_mrouter_init\n"); #endif return 0; }
std::vector<char> metadata_realm_encryption_key() { const size_t key_size = 64; const std::string service = "io.realm.sync.keychain"; const std::string account = "metadata"; auto search_dictionary = build_search_dictionary(account, service, none); CFDataRef retained_key_data; if (OSStatus status = SecItemCopyMatching(search_dictionary.get(), (CFTypeRef *)&retained_key_data)) { if (status != errSecItemNotFound) { throw KeychainAccessException(status); } // Key was not found. Generate a new key, store it, and return it. std::vector<char> key(key_size); arc4random_buf(key.data(), key_size); auto key_data = adoptCF(CFDataCreate(nullptr, reinterpret_cast<const UInt8 *>(key.data()), key_size)); if (!key_data) { throw std::bad_alloc(); } CFDictionaryAddValue(search_dictionary.get(), kSecValueData, key_data.get()); if (OSStatus status = SecItemAdd(search_dictionary.get(), nullptr)) { throw KeychainAccessException(status); } return key; } CFPtr<CFDataRef> key_data = adoptCF(retained_key_data); // Key was previously stored. Extract it. if (key_size != CFDataGetLength(key_data.get())) { throw std::runtime_error("Password stored in keychain was not expected size."); } auto key_bytes = reinterpret_cast<const char *>(CFDataGetBytePtr(key_data.get())); return std::vector<char>(key_bytes, key_bytes + key_size); }
/* * Return a random IP id. Shuffle the new value we get into the previous half * of the ip_shuffle ring (-32767 or swap with ourself), to avoid duplicates * occuring too quickly but also still be random. * * 0 is a special IP ID -- don't return it. */ u_int16_t ip_randomid(void) { static int ipid_initialized; u_int16_t si, r; int i, i2; if (!ipid_initialized) { ipid_initialized = 1; /* * Initialize with a random permutation. Do so using Knuth * which avoids the exchange in the Durstenfeld shuffle. * (See "The Art of Computer Programming, Vol 2" 3rd ed, pg. 145). * * Even if our PRNG is imperfect at boot time, we have deferred * doing this until the first packet being sent and now must * generate an ID. */ for (i = 0; i < sizeof(ip_shuffle)/sizeof(ip_shuffle[0]); ++i) { i2 = arc4random_uniform(i + 1); ip_shuffle[i] = ip_shuffle[i2]; ip_shuffle[i2] = i; } } do { arc4random_buf(&si, sizeof(si)); i = isindex & 0xFFFF; i2 = (isindex - (si & 0x7FFF)) & 0xFFFF; r = ip_shuffle[i]; ip_shuffle[i] = ip_shuffle[i2]; ip_shuffle[i2] = r; isindex++; } while (r == 0); return (r); }
/* Set up a mac structure */ int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen, const EVP_MD *md_type) { if (!(p12->mac = PKCS12_MAC_DATA_new())) return PKCS12_ERROR; if (iter > 1) { if (!(p12->mac->iter = M_ASN1_INTEGER_new())) { PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); return 0; } if (!ASN1_INTEGER_set(p12->mac->iter, iter)) { PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); return 0; } } if (!saltlen) saltlen = PKCS12_SALT_LEN; if (!(p12->mac->salt->data = malloc(saltlen))) { PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); return 0; } p12->mac->salt->length = saltlen; if (!salt) arc4random_buf(p12->mac->salt->data, saltlen); else memcpy (p12->mac->salt->data, salt, saltlen); p12->mac->dinfo->algor->algorithm = OBJ_nid2obj(EVP_MD_type(md_type)); if (!(p12->mac->dinfo->algor->parameter = ASN1_TYPE_new())) { PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); return 0; } p12->mac->dinfo->algor->parameter->type = V_ASN1_NULL; return 1; }
char * host_hash(const char *host, const char *name_from_hostfile, u_int src_len) { struct ssh_hmac_ctx *ctx; u_char salt[256], result[256]; char uu_salt[512], uu_result[512]; static char encoded[1024]; u_int len; len = ssh_digest_bytes(SSH_DIGEST_SHA1); if (name_from_hostfile == NULL) { /* Create new salt */ arc4random_buf(salt, len); } else { /* Extract salt from known host entry */ if (extract_salt(name_from_hostfile, src_len, salt, sizeof(salt)) == -1) return (NULL); } if ((ctx = ssh_hmac_start(SSH_DIGEST_SHA1)) == NULL || ssh_hmac_init(ctx, salt, len) < 0 || ssh_hmac_update(ctx, host, strlen(host)) < 0 || ssh_hmac_final(ctx, result, sizeof(result))) fatal("%s: ssh_hmac failed", __func__); ssh_hmac_free(ctx); if (__b64_ntop(salt, len, uu_salt, sizeof(uu_salt)) == -1 || __b64_ntop(result, len, uu_result, sizeof(uu_result)) == -1) fatal("%s: __b64_ntop failed", __func__); snprintf(encoded, sizeof(encoded), "%s%s%c%s", HASH_MAGIC, uu_salt, HASH_DELIM, uu_result); return (encoded); }
int sshkey_xmss_init_enc_key(struct sshkey *k, const char *ciphername) { struct ssh_xmss_state *state = k->xmss_state; const struct sshcipher *cipher; size_t keylen = 0, ivlen = 0; if (state == NULL) return SSH_ERR_INVALID_ARGUMENT; if ((cipher = cipher_by_name(ciphername)) == NULL) return SSH_ERR_INTERNAL_ERROR; if ((state->enc_ciphername = strdup(ciphername)) == NULL) return SSH_ERR_ALLOC_FAIL; keylen = cipher_keylen(cipher); ivlen = cipher_ivlen(cipher); state->enc_keyiv_len = keylen + ivlen; if ((state->enc_keyiv = calloc(state->enc_keyiv_len, 1)) == NULL) { free(state->enc_ciphername); state->enc_ciphername = NULL; return SSH_ERR_ALLOC_FAIL; } arc4random_buf(state->enc_keyiv, state->enc_keyiv_len); return 0; }
static void li_rand_init (void) { /* (intended to be called at init and after fork() in order to re-seed PRNG * so that forked children, grandchildren, etc do not share PRNG seed) * https://github.com/ramsey/uuid/issues/80 * https://www.agwa.name/blog/post/libressls_prng_is_unsafe_on_linux * (issue in early version of libressl has since been fixed) * https://github.com/libressl-portable/portable/commit/32d9eeeecf4e951e1566d5f4a42b36ea37b60f35 */ unsigned int u; li_rand_inited = 1; if (1 == li_rand_device_bytes((unsigned char *)xsubi, (int)sizeof(xsubi))) { u = ((unsigned int)xsubi[0] << 16) | xsubi[1]; } else { #ifdef HAVE_ARC4RANDOM_BUF u = arc4random(); arc4random_buf(xsubi, sizeof(xsubi)); #else /* NOTE: not cryptographically random !!! */ srand((unsigned int)(time(NULL) ^ getpid())); for (u = 0; u < sizeof(unsigned short); ++u) /* coverity[dont_call : FALSE] */ xsubi[u] = (unsigned short)(rand() & 0xFFFF); u = ((unsigned int)xsubi[0] << 16) | xsubi[1]; #endif } srand(u); /*(initialize just in case rand() used elsewhere)*/ #ifdef HAVE_SRANDOM srandom(u); /*(initialize just in case random() used elsewhere)*/ #endif #ifdef USE_OPENSSL_CRYPTO RAND_poll(); RAND_seed(xsubi, (int)sizeof(xsubi)); #endif }
static int def_generate_session_id(const SSL *ssl, unsigned char *id, unsigned int *id_len) { unsigned int retry = 0; do { arc4random_buf(id, *id_len); } while (SSL_has_matching_session_id(ssl, id, *id_len) && (++retry < MAX_SESS_ID_ATTEMPTS)); if (retry < MAX_SESS_ID_ATTEMPTS) return 1; /* else - woops a session_id match */ /* XXX We should also check the external cache -- * but the probability of a collision is negligible, and * we could not prevent the concurrent creation of sessions * with identical IDs since we currently don't have means * to atomically check whether a session ID already exists * and make a reservation for it if it does not * (this problem applies to the internal cache as well). */ return 0; }
TEST(argdata_create_int, signed) { for (size_t i = 0; i < 1000; ++i) { // Create new integer object. intmax_t j; arc4random_buf(&j, sizeof(j)); argdata_t *ad = argdata_create_int(j); // Read the value back in as a signed integer. intmax_t k; ASSERT_EQ(0, argdata_get_int(ad, &k)); ASSERT_EQ(j, k); if (j >= 0) { // Value can be read in as an unsigned integer. uintmax_t l; ASSERT_EQ(0, argdata_get_int(ad, &l)); ASSERT_EQ(j, l); } else { // Value cannot be read in as an unsigned integer. ASSERT_EQ(ERANGE, argdata_get_int(ad, (uintmax_t *)NULL)); } argdata_free(ad); } }
/* ------------------------------------------------------------------------------------ Init routine called by the EAP engine when it needs the module. Identity of the peer is known at this point. mode is 0 for client, 1 for server. cookie is the EAP engine context, to pass to subsequent calls to EAP. context is EAP module context, that will be passed to subsequent calls to the module ------------------------------------------------------------------------------------ */ int EAPAKAInit (EAP_Input_t *eap_in, void **context, CFDictionaryRef eapOptions) { int error; EAPClientModuleStatus status; int ret = EAP_ERROR_GENERIC; error = EAPAKALoad(); if (error) return error; bundle = (CFBundleRef)eap_in->data; if (bundle) CFRetain(bundle); EAPAKAGetOptions(); bzero(&eapData, sizeof(eapData)); /* remaining fields are read-only: */ uint32_t username_len = strlen(eap_in->username); eapData.username = (uint8_t *)strndup(eap_in->username, username_len); memcpy((void*)&eapData.username_length, &username_len, sizeof(uint32_t)); *((bool *)&eapData.log_enabled) = 1; *((uint32_t *)&eapData.log_level) = LOG_NOTICE; *((uint32_t *)&eapData.mtu) = eap_in->mtu; *((uint32_t *)&eapData.generation) = 0;/* changed when user updates */ arc4random_buf(eapaka_unique, sizeof(eapaka_unique) - 1); eapaka_unique[sizeof(eapaka_unique)-1] = 0; eapData.unique_id = eapaka_unique; /* used for TLS session resumption??? */ *((uint32_t *)&eapData.unique_id_length) = strlen(eapData.unique_id); if (eapOptions) { CFTypeRef value = CFDictionaryGetValue(eapOptions, kEAPPropertiesTypeEAPAKA); if (value && CFGetTypeID(value) == CFDictionaryGetTypeID()) { eapProperties = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, (CFDictionaryRef)value); } else { eapProperties = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, eapOptions); } } else eapProperties = CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); if (eapProperties == NULL) { plog(ASL_LEVEL_ERR, "EAP-AKA: Cannot allocate memory\n"); goto failed; } *((CFDictionaryRef *)&eapData.properties) = (CFDictionaryRef)eapProperties; status = EAPClientModulePluginInit(eapRef, &eapData, NULL, &error); if (status != kEAPClientStatusOK) { plog(ASL_LEVEL_ERR, "EAP-AKA: EAPClientPluginInit(eapaka) failed, error %d\n", status); goto failed; } eapSavePacket = NULL; return EAP_NO_ERROR; failed: return ret; }
static int i2b_PVK(unsigned char **out, EVP_PKEY*pk, int enclevel, pem_password_cb *cb, void *u) { int outlen = 24, pklen; unsigned char *p, *salt = NULL; EVP_CIPHER_CTX cctx; EVP_CIPHER_CTX_init(&cctx); if (enclevel) outlen += PVK_SALTLEN; pklen = do_i2b(NULL, pk, 0); if (pklen < 0) return -1; outlen += pklen; p = malloc(outlen); if (!p) { PEMerror(ERR_R_MALLOC_FAILURE); return -1; } write_ledword(&p, MS_PVKMAGIC); write_ledword(&p, 0); if (pk->type == EVP_PKEY_DSA) write_ledword(&p, MS_KEYTYPE_SIGN); else write_ledword(&p, MS_KEYTYPE_KEYX); write_ledword(&p, enclevel ? 1 : 0); write_ledword(&p, enclevel ? PVK_SALTLEN : 0); write_ledword(&p, pklen); if (enclevel) { arc4random_buf(p, PVK_SALTLEN); salt = p; p += PVK_SALTLEN; } do_i2b(&p, pk, 0); if (enclevel == 0) { *out = p; return outlen; } else { char psbuf[PEM_BUFSIZE]; unsigned char keybuf[20]; int enctmplen, inlen; if (cb) inlen = cb(psbuf, PEM_BUFSIZE, 1, u); else inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 1, u); if (inlen <= 0) { PEMerror(PEM_R_BAD_PASSWORD_READ); goto error; } if (!derive_pvk_key(keybuf, salt, PVK_SALTLEN, (unsigned char *)psbuf, inlen)) goto error; if (enclevel == 1) memset(keybuf + 5, 0, 11); p = salt + PVK_SALTLEN + 8; if (!EVP_EncryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL)) goto error; explicit_bzero(keybuf, 20); if (!EVP_DecryptUpdate(&cctx, p, &enctmplen, p, pklen - 8)) goto error; if (!EVP_DecryptFinal_ex(&cctx, p + enctmplen, &enctmplen)) goto error; } EVP_CIPHER_CTX_cleanup(&cctx); *out = p; return outlen; error: EVP_CIPHER_CTX_cleanup(&cctx); free(p); return -1; }
int dtls1_client_hello(SSL *s) { unsigned char *bufend, *d, *p; unsigned int i; if (s->state == SSL3_ST_CW_CLNT_HELLO_A) { SSL_SESSION *sess = s->session; if ((s->session == NULL) || (s->session->ssl_version != s->version) || (!sess->session_id_length && !sess->tlsext_tick) || (s->session->not_resumable)) { if (!ssl_get_new_session(s, 0)) goto err; } /* else use the pre-loaded session */ p = s->s3->client_random; /* if client_random is initialized, reuse it, we are * required to use same upon reply to HelloVerify */ for (i = 0; p[i]=='\0' && i < sizeof(s->s3->client_random); i++) ; if (i == sizeof(s->s3->client_random)) arc4random_buf(p, sizeof(s->s3->client_random)); d = p = ssl3_handshake_msg_start(s, SSL3_MT_CLIENT_HELLO); *(p++) = s->version >> 8; *(p++) = s->version&0xff; s->client_version = s->version; /* Random stuff */ memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE); p += SSL3_RANDOM_SIZE; /* Session ID */ if (s->new_session) i = 0; else i = s->session->session_id_length; *(p++) = i; if (i != 0) { if (i > sizeof s->session->session_id) { SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); goto err; } memcpy(p, s->session->session_id, i); p += i; } /* cookie stuff */ if (s->d1->cookie_len > sizeof(s->d1->cookie)) { SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); goto err; } *(p++) = s->d1->cookie_len; memcpy(p, s->d1->cookie, s->d1->cookie_len); p += s->d1->cookie_len; /* Ciphers supported */ i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &p[2]); if (i == 0) { SSLerr(SSL_F_DTLS1_CLIENT_HELLO, SSL_R_NO_CIPHERS_AVAILABLE); goto err; } s2n(i, p); p += i; /* add in (no) COMPRESSION */ *(p++) = 1; *(p++) = 0; /* Add the NULL method */ bufend = (unsigned char *)s->init_buf->data + SSL3_RT_MAX_PLAIN_LENGTH; if ((p = ssl_add_clienthello_tlsext(s, p, bufend)) == NULL) { SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); goto err; } ssl3_handshake_msg_finish(s, p - d); s->state = SSL3_ST_CW_CLNT_HELLO_B; }
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); }
/** Generate 128 bits of random noise for seeding RNGs. Attempts to * use various OS-specific sources of random bits, with a fallback * based on time and pid. */ void generate_seed(uint64_t seeds[]) { bool seed_generated = false; static int stream_count = 0; int len = sizeof(uint64_t) * 2; #ifdef HAVE_GETENTROPY /* On OpenBSD and up to date Linux, use getentropy() to avoid the open/read/close sequence with /dev/urandom */ if (!seed_generated && getentropy(seeds, len) == 0) { fprintf(stderr, "Seeded RNG with getentropy()\n"); seed_generated = true; } #endif #ifdef HAVE_ARC4RANDOM_BUF /* Most (all?) of the BSDs have this seeder. Use it for the reasons above. Also available on Linux with libbsd, but we don't check for that. */ if (!seed_generated) { arc4random_buf(seeds, len); fprintf(stderr, "Seeded RNG with arc4random\n"); seed_generated = true; } #endif #ifdef WIN32 if (!seed_generated) { /* Use the Win32 bcrypto RNG interface */ if (BCryptGenRandom(NULL, (PUCHAR) seeds, len, BCRYPT_USE_SYSTEM_PREFERRED_RNG) == STATUS_SUCCESS) { fprintf(stderr, "Seeding RNG with BCryptGenRandom()\n"); seed_generated = true; } } #endif #ifdef HAVE_DEV_URANDOM if (!seed_generated) { /* Seed from /dev/urandom if available */ int fd; fd = open("/dev/urandom", O_RDONLY); if (fd >= 0) { int r = read(fd, (void *) seeds, len); close(fd); if (r != len) { fprintf(stderr, "Couldn't read from /dev/urandom! Resorting to normal " "seeding method.\n"); } else { fprintf(stderr, "Seeding RNG with /dev/urandom\n"); seed_generated = true; } } else { fprintf(stderr, "Couldn't open /dev/urandom to seed random number " "generator. Resorting to normal seeding method.\n"); } } #endif if (!seed_generated) { /* Default seeder. Pick a seed that's slightly random */ #ifdef WIN32 seeds[0] = (uint64_t) time(NULL); seeds[1] = (uint64_t) GetCurrentProcessId() + stream_count; #else seeds[0] = (uint64_t) time(NULL); seeds[1] = (uint64_t) getpid() + stream_count; #endif stream_count += 1; } }
void arc4random_stir(void) { n=0; arc4random_buf(buf,sizeof(buf)); }
static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) { EVP_AES_GCM_CTX *gctx = c->cipher_data; switch (type) { case EVP_CTRL_INIT: gctx->key_set = 0; gctx->iv_set = 0; gctx->ivlen = c->cipher->iv_len; gctx->iv = c->iv; gctx->taglen = -1; gctx->iv_gen = 0; gctx->tls_aad_len = -1; return 1; case EVP_CTRL_GCM_SET_IVLEN: if (arg <= 0) return 0; /* Allocate memory for IV if needed */ if ((arg > EVP_MAX_IV_LENGTH) && (arg > gctx->ivlen)) { if (gctx->iv != c->iv) free(gctx->iv); gctx->iv = malloc(arg); if (!gctx->iv) return 0; } gctx->ivlen = arg; return 1; case EVP_CTRL_GCM_SET_TAG: if (arg <= 0 || arg > 16 || c->encrypt) return 0; memcpy(c->buf, ptr, arg); gctx->taglen = arg; return 1; case EVP_CTRL_GCM_GET_TAG: if (arg <= 0 || arg > 16 || !c->encrypt || gctx->taglen < 0) return 0; memcpy(ptr, c->buf, arg); return 1; case EVP_CTRL_GCM_SET_IV_FIXED: /* Special case: -1 length restores whole IV */ if (arg == -1) { memcpy(gctx->iv, ptr, gctx->ivlen); gctx->iv_gen = 1; return 1; } /* Fixed field must be at least 4 bytes and invocation field * at least 8. */ if ((arg < 4) || (gctx->ivlen - arg) < 8) return 0; if (arg) memcpy(gctx->iv, ptr, arg); if (c->encrypt) arc4random_buf(gctx->iv + arg, gctx->ivlen - arg); gctx->iv_gen = 1; return 1; case EVP_CTRL_GCM_IV_GEN: if (gctx->iv_gen == 0 || gctx->key_set == 0) return 0; CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen); if (arg <= 0 || arg > gctx->ivlen) arg = gctx->ivlen; memcpy(ptr, gctx->iv + gctx->ivlen - arg, arg); /* Invocation field will be at least 8 bytes in size and * so no need to check wrap around or increment more than * last 8 bytes. */ ctr64_inc(gctx->iv + gctx->ivlen - 8); gctx->iv_set = 1; return 1; case EVP_CTRL_GCM_SET_IV_INV: if (gctx->iv_gen == 0 || gctx->key_set == 0 || c->encrypt) return 0; memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg); CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen); gctx->iv_set = 1; return 1; case EVP_CTRL_AEAD_TLS1_AAD: /* Save the AAD for later use */ if (arg != 13) return 0; memcpy(c->buf, ptr, arg); gctx->tls_aad_len = arg; { unsigned int len = c->buf[arg - 2] << 8 | c->buf[arg - 1]; /* Correct length for explicit IV */ len -= EVP_GCM_TLS_EXPLICIT_IV_LEN; /* If decrypting correct for tag too */ if (!c->encrypt) len -= EVP_GCM_TLS_TAG_LEN; c->buf[arg - 2] = len >> 8; c->buf[arg - 1] = len & 0xff; } /* Extra padding: tag appended to record */ return EVP_GCM_TLS_TAG_LEN; case EVP_CTRL_COPY: { EVP_CIPHER_CTX *out = ptr; EVP_AES_GCM_CTX *gctx_out = out->cipher_data; if (gctx->gcm.key) { if (gctx->gcm.key != &gctx->ks) return 0; gctx_out->gcm.key = &gctx_out->ks; } if (gctx->iv == c->iv) gctx_out->iv = out->iv; else { gctx_out->iv = malloc(gctx->ivlen); if (!gctx_out->iv) return 0; memcpy(gctx_out->iv, gctx->iv, gctx->ivlen); } return 1; } default: return -1; } }
/* * Serialises the authentication (private) key to a blob, encrypting it with * passphrase. The identification of the blob (lowest 64 bits of n) will * precede the key to provide identification of the key without needing a * passphrase. */ static int sshkey_private_rsa1_to_blob(struct sshkey *key, struct sshbuf *blob, const char *passphrase, const char *comment) { struct sshbuf *buffer = NULL, *encrypted = NULL; u_char buf[8]; int r, cipher_num; struct sshcipher_ctx ciphercontext; const struct sshcipher *cipher; u_char *cp; /* * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting * to another cipher; otherwise use SSH_AUTHFILE_CIPHER. */ cipher_num = (strcmp(passphrase, "") == 0) ? SSH_CIPHER_NONE : SSH_AUTHFILE_CIPHER; if ((cipher = cipher_by_number(cipher_num)) == NULL) return SSH_ERR_INTERNAL_ERROR; /* This buffer is used to build the secret part of the private key. */ if ((buffer = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; /* Put checkbytes for checking passphrase validity. */ if ((r = sshbuf_reserve(buffer, 4, &cp)) != 0) goto out; arc4random_buf(cp, 2); memcpy(cp + 2, cp, 2); /* * Store the private key (n and e will not be stored because they * will be stored in plain text, and storing them also in encrypted * format would just give known plaintext). * Note: q and p are stored in reverse order to SSL. */ if ((r = sshbuf_put_bignum1(buffer, key->rsa->d)) != 0 || (r = sshbuf_put_bignum1(buffer, key->rsa->iqmp)) != 0 || (r = sshbuf_put_bignum1(buffer, key->rsa->q)) != 0 || (r = sshbuf_put_bignum1(buffer, key->rsa->p)) != 0) goto out; /* Pad the part to be encrypted to a size that is a multiple of 8. */ bzero(buf, 8); if ((r = sshbuf_put(buffer, buf, 8 - (sshbuf_len(buffer) % 8))) != 0) goto out; /* This buffer will be used to contain the data in the file. */ if ((encrypted = sshbuf_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } /* First store keyfile id string. */ if ((r = sshbuf_put(encrypted, authfile_id_string, sizeof(authfile_id_string))) != 0) goto out; /* Store cipher type and "reserved" field. */ if ((r = sshbuf_put_u8(encrypted, cipher_num)) != 0 || (r = sshbuf_put_u32(encrypted, 0)) != 0) goto out; /* Store public key. This will be in plain text. */ if ((r = sshbuf_put_u32(encrypted, BN_num_bits(key->rsa->n))) != 0 || (r = sshbuf_put_bignum1(encrypted, key->rsa->n) != 0) || (r = sshbuf_put_bignum1(encrypted, key->rsa->e) != 0) || (r = sshbuf_put_cstring(encrypted, comment) != 0)) goto out; /* Allocate space for the private part of the key in the buffer. */ if ((r = sshbuf_reserve(encrypted, sshbuf_len(buffer), &cp)) != 0) goto out; if ((r = cipher_set_key_string(&ciphercontext, cipher, passphrase, CIPHER_ENCRYPT)) != 0) goto out; if ((r = cipher_crypt(&ciphercontext, cp, sshbuf_ptr(buffer), sshbuf_len(buffer), 0, 0)) != 0) goto out; if ((r = cipher_cleanup(&ciphercontext)) != 0) goto out; r = sshbuf_putb(blob, encrypted); out: bzero(&ciphercontext, sizeof(ciphercontext)); bzero(buf, sizeof(buf)); if (buffer != NULL) sshbuf_free(buffer); if (encrypted != NULL) sshbuf_free(encrypted); return r; }
static int php_random_bytes(void *bytes, size_t size) { #if PHP_WIN32 /* Defer to CryptGenRandom on Windows */ if (php_win32_get_random_bytes(bytes, size) == FAILURE) { zend_throw_exception(zend_ce_exception, "Could not gather sufficient random data", 0); return FAILURE; } #elif HAVE_DECL_ARC4RANDOM_BUF && ((defined(__OpenBSD__) && OpenBSD >= 201405) || (defined(__NetBSD__) && __NetBSD_Version__ >= 700000001)) arc4random_buf(bytes, size); #elif HAVE_DECL_GETRANDOM /* Linux getrandom(2) syscall */ size_t read_bytes = 0; size_t amount_to_read = 0; ssize_t n; /* Keep reading until we get enough entropy */ do { amount_to_read = size - read_bytes; /* Below, (bytes + read_bytes) is pointer arithmetic. bytes read_bytes size | | | [#######=============] (we're going to write over the = region) \\\\\\\\\\\\\ amount_to_read */ n = syscall(SYS_getrandom, bytes + read_bytes, amount_to_read, 0); if (n == -1) { if (errno == EINTR || errno == EAGAIN) { /* Try again */ continue; } /* If the syscall fails, we are doomed. The loop that calls php_random_bytes should be terminated by the exception instead of proceeding to demand more entropy. */ zend_throw_exception(zend_ce_exception, "Could not gather sufficient random data", errno); return FAILURE; } read_bytes += (size_t) n; } while (read_bytes < size); #else int fd = RANDOM_G(fd); struct stat st; size_t read_bytes = 0; ssize_t n; if (fd < 0) { #if HAVE_DEV_URANDOM fd = open("/dev/urandom", O_RDONLY); #endif if (fd < 0) { zend_throw_exception(zend_ce_exception, "Cannot open source device", 0); return FAILURE; } /* Does the file exist and is it a character device? */ if (fstat(fd, &st) != 0 || # ifdef S_ISNAM !(S_ISNAM(st.st_mode) || S_ISCHR(st.st_mode)) # else !S_ISCHR(st.st_mode) # endif ) { close(fd); zend_throw_exception(zend_ce_exception, "Error reading from source device", 0); return FAILURE; } RANDOM_G(fd) = fd; } while (read_bytes < size) { n = read(fd, bytes + read_bytes, size - read_bytes); if (n <= 0) { break; } read_bytes += n; } if (read_bytes < size) { zend_throw_exception(zend_ce_exception, "Could not gather sufficient random data", 0); return FAILURE; } #endif return SUCCESS; }
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); }
int udf_mountfs(struct vnode *devvp, struct mount *mp, uint32_t lb, struct proc *p) { struct buf *bp = NULL; struct anchor_vdp avdp; struct umount *ump = NULL; struct part_desc *pd; struct logvol_desc *lvd; struct fileset_desc *fsd; struct extfile_entry *xfentry; struct file_entry *fentry; uint32_t sector, size, mvds_start, mvds_end; uint32_t fsd_offset = 0; uint16_t part_num = 0, fsd_part = 0; int error = EINVAL; int logvol_found = 0, part_found = 0, fsd_found = 0; int bsize; /* * Disallow multiple mounts of the same device. * Disallow mounting of a device that is currently in use * (except for root, which might share swap device for miniroot). * Flush out any old buffers remaining from a previous use. */ if ((error = vfs_mountedon(devvp))) return (error); if (vcount(devvp) > 1 && devvp != rootvp) return (EBUSY); vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p); error = vinvalbuf(devvp, V_SAVE, p->p_ucred, p, 0, 0); VOP_UNLOCK(devvp, 0, p); if (error) return (error); error = VOP_OPEN(devvp, FREAD, FSCRED, p); if (error) return (error); ump = malloc(sizeof(*ump), M_UDFMOUNT, M_WAITOK | M_ZERO); mp->mnt_data = (qaddr_t) ump; mp->mnt_stat.f_fsid.val[0] = devvp->v_rdev; mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum; mp->mnt_flag |= MNT_LOCAL; ump->um_mountp = mp; ump->um_dev = devvp->v_rdev; ump->um_devvp = devvp; bsize = 2048; /* Should probe the media for its size. */ /* * Get the Anchor Volume Descriptor Pointer from sector 256. * Should also check sector n - 256, n, and 512. */ sector = 256; if ((error = bread(devvp, sector * btodb(bsize), bsize, &bp)) != 0) goto bail; if ((error = udf_checktag((struct desc_tag *)bp->b_data, TAGID_ANCHOR))) goto bail; bcopy(bp->b_data, &avdp, sizeof(struct anchor_vdp)); brelse(bp); bp = NULL; /* * Extract the Partition Descriptor and Logical Volume Descriptor * from the Volume Descriptor Sequence. * Should we care about the partition type right now? * What about multiple partitions? */ mvds_start = letoh32(avdp.main_vds_ex.loc); mvds_end = mvds_start + (letoh32(avdp.main_vds_ex.len) - 1) / bsize; for (sector = mvds_start; sector < mvds_end; sector++) { if ((error = bread(devvp, sector * btodb(bsize), bsize, &bp)) != 0) { printf("Can't read sector %d of VDS\n", sector); goto bail; } lvd = (struct logvol_desc *)bp->b_data; if (!udf_checktag(&lvd->tag, TAGID_LOGVOL)) { ump->um_bsize = letoh32(lvd->lb_size); ump->um_bmask = ump->um_bsize - 1; ump->um_bshift = ffs(ump->um_bsize) - 1; fsd_part = letoh16(lvd->_lvd_use.fsd_loc.loc.part_num); fsd_offset = letoh32(lvd->_lvd_use.fsd_loc.loc.lb_num); if (udf_find_partmaps(ump, lvd)) break; logvol_found = 1; } pd = (struct part_desc *)bp->b_data; if (!udf_checktag(&pd->tag, TAGID_PARTITION)) { part_found = 1; part_num = letoh16(pd->part_num); ump->um_len = ump->um_reallen = letoh32(pd->part_len); ump->um_start = ump->um_realstart = letoh32(pd->start_loc); } brelse(bp); bp = NULL; if ((part_found) && (logvol_found)) break; } if (!part_found || !logvol_found) { error = EINVAL; goto bail; } if (ISSET(ump->um_flags, UDF_MNT_USES_META)) { /* Read Metadata File 'File Entry' to find Metadata file. */ struct long_ad *la; sector = ump->um_start + ump->um_meta_start; /* Set in udf_get_mpartmap() */ if ((error = RDSECTOR(devvp, sector, ump->um_bsize, &bp)) != 0) { printf("Cannot read sector %d for Metadata File Entry\n", sector); error = EINVAL; goto bail; } xfentry = (struct extfile_entry *)bp->b_data; fentry = (struct file_entry *)bp->b_data; if (udf_checktag(&xfentry->tag, TAGID_EXTFENTRY) == 0) la = (struct long_ad *)&xfentry->data[letoh32(xfentry->l_ea)]; else if (udf_checktag(&fentry->tag, TAGID_FENTRY) == 0) la = (struct long_ad *)&fentry->data[letoh32(fentry->l_ea)]; else { printf("Invalid Metadata File FE @ sector %d! (tag.id %d)\n", sector, fentry->tag.id); error = EINVAL; goto bail; } ump->um_meta_start = letoh32(la->loc.lb_num); ump->um_meta_len = letoh32(la->len); if (bp != NULL) { brelse(bp); bp = NULL; } } else if (fsd_part != part_num) { printf("FSD does not lie within the partition!\n"); error = EINVAL; goto bail; } mtx_init(&ump->um_hashmtx, IPL_NONE); ump->um_hashtbl = hashinit(UDF_HASHTBLSIZE, M_UDFMOUNT, M_WAITOK, &ump->um_hashsz); arc4random_buf(&ump->um_hashkey, sizeof(ump->um_hashkey)); /* Get the VAT, if needed */ if (ump->um_flags & UDF_MNT_FIND_VAT) { error = udf_vat_get(ump, lb); if (error) goto bail; } /* * Grab the Fileset Descriptor * Thanks to Chuck McCrobie <*****@*****.**> for pointing * me in the right direction here. */ if (ISSET(ump->um_flags, UDF_MNT_USES_META)) sector = ump->um_meta_start; else sector = fsd_offset; udf_vat_map(ump, §or); if ((error = RDSECTOR(devvp, sector, ump->um_bsize, &bp)) != 0) { printf("Cannot read sector %d of FSD\n", sector); goto bail; } fsd = (struct fileset_desc *)bp->b_data; if (!udf_checktag(&fsd->tag, TAGID_FSD)) { fsd_found = 1; bcopy(&fsd->rootdir_icb, &ump->um_root_icb, sizeof(struct long_ad)); if (ISSET(ump->um_flags, UDF_MNT_USES_META)) { ump->um_root_icb.loc.lb_num += ump->um_meta_start; ump->um_root_icb.loc.part_num = part_num; } } brelse(bp); bp = NULL; if (!fsd_found) { printf("Couldn't find the fsd\n"); error = EINVAL; goto bail; } /* * Find the file entry for the root directory. */ sector = letoh32(ump->um_root_icb.loc.lb_num); size = letoh32(ump->um_root_icb.len); udf_vat_map(ump, §or); if ((error = udf_readlblks(ump, sector, size, &bp)) != 0) { printf("Cannot read sector %d\n", sector); goto bail; } xfentry = (struct extfile_entry *)bp->b_data; fentry = (struct file_entry *)bp->b_data; error = udf_checktag(&xfentry->tag, TAGID_EXTFENTRY); if (error) { error = udf_checktag(&fentry->tag, TAGID_FENTRY); if (error) { printf("Invalid root file entry!\n"); goto bail; } } brelse(bp); bp = NULL; devvp->v_specmountpoint = mp; return (0); bail: if (ump->um_hashtbl != NULL) free(ump->um_hashtbl, M_UDFMOUNT, 0); if (ump != NULL) { free(ump, M_UDFMOUNT, 0); mp->mnt_data = NULL; mp->mnt_flag &= ~MNT_LOCAL; } if (bp != NULL) brelse(bp); vn_lock(devvp, LK_EXCLUSIVE|LK_RETRY, p); VOP_CLOSE(devvp, FREAD, FSCRED, p); VOP_UNLOCK(devvp, 0, p); return (error); }
int generate_cookie_callback(SSL * ssl, unsigned char *cookie, unsigned int *cookie_len) { unsigned char *buffer, result[EVP_MAX_MD_SIZE]; unsigned int length, resultlength; union { struct sockaddr sa; struct sockaddr_in s4; struct sockaddr_in6 s6; } peer; /* Initialize a random secret */ if (!cookie_initialized) { arc4random_buf(cookie_secret, COOKIE_SECRET_LENGTH); cookie_initialized = 1; } /* Read peer information */ (void) BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer); /* Create buffer with peer's address and port */ length = 0; switch (peer.sa.sa_family) { case AF_INET: length += sizeof(struct in_addr); length += sizeof(peer.s4.sin_port); break; case AF_INET6: length += sizeof(struct in6_addr); length += sizeof(peer.s6.sin6_port); break; default: OPENSSL_assert(0); break; } buffer = malloc(length); if (buffer == NULL) { BIO_printf(bio_err, "out of memory\n"); return 0; } switch (peer.sa.sa_family) { case AF_INET: memcpy(buffer, &peer.s4.sin_port, sizeof(peer.s4.sin_port)); memcpy(buffer + sizeof(peer.s4.sin_port), &peer.s4.sin_addr, sizeof(struct in_addr)); break; case AF_INET6: memcpy(buffer, &peer.s6.sin6_port, sizeof(peer.s6.sin6_port)); memcpy(buffer + sizeof(peer.s6.sin6_port), &peer.s6.sin6_addr, sizeof(struct in6_addr)); break; default: OPENSSL_assert(0); break; } /* Calculate HMAC of buffer using the secret */ HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH, buffer, length, result, &resultlength); free(buffer); memcpy(cookie, result, resultlength); *cookie_len = resultlength; return 1; }
/* dtls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively. * * Returns: * 0: (in non-constant time) if the record is publically invalid (i.e. too * short etc). * 1: if the record's padding is valid / the encryption was successful. * -1: if the record's padding/AEAD-authenticator is invalid or, if sending, * an internal error occured. */ int dtls1_enc(SSL *s, int send) { SSL3_RECORD *rec; EVP_CIPHER_CTX *ds; unsigned long l; int bs, i, j, k, mac_size = 0; const EVP_CIPHER *enc; if (send) { if (EVP_MD_CTX_md(s->write_hash)) { mac_size = EVP_MD_CTX_size(s->write_hash); if (mac_size < 0) return -1; } ds = s->enc_write_ctx; rec = &(s->s3->wrec); if (s->enc_write_ctx == NULL) enc = NULL; else { enc = EVP_CIPHER_CTX_cipher(s->enc_write_ctx); if (rec->data != rec->input) /* we can't write into the input stream */ fprintf(stderr, "%s:%d: rec->data != rec->input\n", __FILE__, __LINE__); else if (EVP_CIPHER_block_size(ds->cipher) > 1) { arc4random_buf(rec->input, EVP_CIPHER_block_size(ds->cipher)); } } } else { if (EVP_MD_CTX_md(s->read_hash)) { mac_size = EVP_MD_CTX_size(s->read_hash); OPENSSL_assert(mac_size >= 0); } ds = s->enc_read_ctx; rec = &(s->s3->rrec); if (s->enc_read_ctx == NULL) enc = NULL; else enc = EVP_CIPHER_CTX_cipher(s->enc_read_ctx); } if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) { memmove(rec->data, rec->input, rec->length); rec->input = rec->data; } else { l = rec->length; bs = EVP_CIPHER_block_size(ds->cipher); if ((bs != 1) && send) { i = bs - ((int)l % bs); /* Add weird padding of upto 256 bytes */ /* we need to add 'i' padding bytes of value j */ j = i - 1; if (s->options & SSL_OP_TLS_BLOCK_PADDING_BUG) { if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) j++; } for (k = (int)l; k < (int)(l + i); k++) rec->input[k] = j; l += i; rec->length += i; } if (!send) { if (l == 0 || l % bs != 0) return 0; } EVP_Cipher(ds, rec->data, rec->input, l); if ((bs != 1) && !send) return tls1_cbc_remove_padding(s, rec, bs, mac_size); } return (1); }
static void ev_arc4random_buf(void *buf, size_t n) { arc4random_buf(buf, n); }
void evutil_secure_rng_get_bytes(void *buf, size_t n) { arc4random_buf(buf, n); }
void __randombytes_sysrandom_buf(void * const buf, const size_t size) { return arc4random_buf(buf, size); }
double random_value () { double x; arc4random_buf (&x, sizeof x); return x; }
int DES_enc_write(int fd, const void *_buf, int len, DES_key_schedule *sched, DES_cblock *iv) { #ifdef _LIBC extern unsigned long time(); extern int write(); #endif const unsigned char *buf=_buf; long rnum; int i,j,k,outnum; static unsigned char *outbuf=NULL; unsigned char shortbuf[8]; unsigned char *p; const unsigned char *cp; static int start=1; if (outbuf == NULL) { outbuf=malloc(BSIZE+HDRSIZE); if (outbuf == NULL) return(-1); } /* If we are sending less than 8 bytes, the same char will look * the same if we don't pad it out with random bytes */ if (start) { start=0; } /* lets recurse if we want to send the data in small chunks */ if (len > MAXWRITE) { j=0; for (i=0; i<len; i+=k) { k=DES_enc_write(fd,&(buf[i]), ((len-i) > MAXWRITE)?MAXWRITE:(len-i),sched,iv); if (k < 0) return(k); else j+=k; } return(j); } /* write length first */ p=outbuf; l2n(len,p); /* pad short strings */ if (len < 8) { cp=shortbuf; memcpy(shortbuf,buf,len); arc4random_buf(shortbuf+len, 8-len); rnum=8; } else { cp=buf; rnum=((len+7)/8*8); /* round up to nearest eight */ } if (DES_rw_mode & DES_PCBC_MODE) DES_pcbc_encrypt(cp,&(outbuf[HDRSIZE]),(len<8)?8:len,sched,iv, DES_ENCRYPT); else DES_cbc_encrypt(cp,&(outbuf[HDRSIZE]),(len<8)?8:len,sched,iv, DES_ENCRYPT); /* output */ outnum=rnum+HDRSIZE; for (j=0; j<outnum; j+=i) { /* eay 26/08/92 I was not doing writing from where we * got up to. */ i=write(fd,(void *)&(outbuf[j]),outnum-j); if (i == -1) { #ifdef EINTR if (errno == EINTR) i=0; else #endif /* This is really a bad error - very bad * It will stuff-up both ends. */ return(-1); } } return(len); }
byte * pcp_gennonce() { byte *nonce = ucmalloc(LNONCE); arc4random_buf(nonce, LNONCE); return nonce; }