Exemple #1
0
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;
}
Exemple #2
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);
}
Exemple #3
0
/*
 * 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;
}
Exemple #4
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);
}
Exemple #5
0
/*
 * 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);
}
Exemple #8
0
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;
}
Exemple #9
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
}
Exemple #10
0
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);
  }
}
Exemple #12
0
/* ------------------------------------------------------------------------------------
 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;
}
Exemple #13
0
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;
}
Exemple #14
0
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;
	}
Exemple #15
0
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);
}
Exemple #16
0
/** 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;
  }
}
Exemple #17
0
void arc4random_stir(void) {
  n=0;
  arc4random_buf(buf,sizeof(buf));
}
Exemple #18
0
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;

	}
}
Exemple #19
0
/*
 * 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;
}
Exemple #20
0
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;
}
Exemple #21
0
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);
}
Exemple #22
0
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, &sector);
	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, &sector);
	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);
}
Exemple #23
0
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;
}
Exemple #24
0
/* 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);
}
Exemple #25
0
static void
ev_arc4random_buf(void *buf, size_t n)
{
	arc4random_buf(buf, n);
}
Exemple #26
0
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);
}
Exemple #28
0
double random_value ()
{
  double x;
  arc4random_buf (&x, sizeof x);
  return x;
}
Exemple #29
0
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);
	}
Exemple #30
0
byte * pcp_gennonce() {
  byte *nonce = ucmalloc(LNONCE);
  arc4random_buf(nonce, LNONCE);
  return nonce;
}