Пример #1
0
void Simulation::create_random_vertex(const int vertexIndex)
{
   const float centerX = random_float(-1.0f, 1.0f);
   const float centerY = random_float(-1.0f, 1.0f);
   const float Range = 0.15f;

   const unsigned char red = random_byte();
   const unsigned char green = random_byte();
   const unsigned char blue = random_byte();
   const unsigned char alpha = random_byte();

   currentVertices[vertexIndex + 0] = ColorVertex(centerX + random_float(-Range, Range), centerY + random_float(-Range, Range), red, green, blue, alpha);
   currentVertices[vertexIndex + 1] = ColorVertex(centerX + random_float(-Range, Range), centerY + random_float(-Range, Range), red, green, blue, alpha);
   currentVertices[vertexIndex + 2] = ColorVertex(centerX + random_float(-Range, Range), centerY + random_float(-Range, Range), red, green, blue, alpha);
   currentVertexCount += 3;
}
Пример #2
0
int rsaencrypt(unsigned char *data, int length, struct RSAKey *key)
{
    Bignum b1, b2;
    int i;
    unsigned char *p;

    if (key->bytes < length + 4)
	return 0;		       /* RSA key too short! */

    memmove(data + key->bytes - length, data, length);
    data[0] = 0;
    data[1] = 2;

    for (i = 2; i < key->bytes - length - 1; i++) {
	do {
	    data[i] = random_byte();
	} while (data[i] == 0);
    }
    data[key->bytes - length - 1] = 0;

    b1 = bignum_from_bytes(data, key->bytes);

    b2 = modpow(b1, key->exponent, key->modulus);

    p = data;
    for (i = key->bytes; i--;) {
	*p++ = bignum_byte(b2, i);
    }

    freebn(b1);
    freebn(b2);

    return 1;
}
Пример #3
0
/*
 * DH stage 1: invent a number x between 1 and q, and compute e =
 * g^x mod p. Return e.
 * 
 * If `nbits' is greater than zero, it is used as an upper limit
 * for the number of bits in x. This is safe provided that (a) you
 * use twice as many bits in x as the number of bits you expect to
 * use in your session key, and (b) the DH group is a safe prime
 * (which SSH demands that it must be).
 * 
 * P. C. van Oorschot, M. J. Wiener
 * "On Diffie-Hellman Key Agreement with Short Exponents".
 * Advances in Cryptology: Proceedings of Eurocrypt '96
 * Springer-Verlag, May 1996.
 */
Bignum dh_create_e(void *handle, int nbits)
{
    struct dh_ctx *ctx = (struct dh_ctx *)handle;
    int i;

    int nbytes;
    unsigned char *buf;

    nbytes = (bignum_bitcount(ctx->qmask) + 7) / 8;
    buf = snewn(nbytes, unsigned char);

    do {
	/*
	 * Create a potential x, by ANDing a string of random bytes
	 * with qmask.
	 */
	if (ctx->x)
	    freebn(ctx->x);
	if (nbits == 0 || nbits > bignum_bitcount(ctx->qmask)) {
	    for (i = 0; i < nbytes; i++)
		buf[i] = bignum_byte(ctx->qmask, i) & random_byte();
	    ctx->x = bignum_from_bytes(buf, nbytes);
	} else {
	    int b, nb;
	    ctx->x = bn_power_2(nbits);
	    b = nb = 0;
	    for (i = 0; i < nbits; i++) {
		if (nb == 0) {
		    nb = 8;
		    b = random_byte();
		}
		bignum_set_bit(ctx->x, i, b & 1);
		b >>= 1;
		nb--;
	    }
	}
    } while (bignum_cmp(ctx->x, One) <= 0 || bignum_cmp(ctx->x, ctx->q) >= 0);

    sfree(buf);

    /*
     * Done. Now compute e = g^x mod p.
     */
    ctx->e = modpow(ctx->g, ctx->x, ctx->p);

    return ctx->e;
}
Пример #4
0
uint8_t * generate_random_bytes(size_t array_size) 
{
    uint8_t *arr = calloc(array_size, sizeof(uint8_t *));
    for (uint32_t i = 0; i < array_size; i++) {
        arr[i] = random_byte();
    }
    return arr;
}
Пример #5
0
// CXNN: Sets VX to a random number, masked by NN
static int op_CXXX(word_t op)
{
    int x  = (op >> 8) & 0xF;
    int nn = (op >> 0) & 0xFF;

    chip8.V[x] = random_byte() & nn;

    return SUCCESS;
}
Пример #6
0
void rsaencrypt(unsigned char *data, int length, struct RSAKey *key) {
    Bignum b1, b2;
    int w, i;
    unsigned char *p;

    debug(key->exponent);

    memmove(data+key->bytes-length, data, length);
    data[0] = 0;
    data[1] = 2;

    for (i = 2; i < key->bytes-length-1; i++) {
	do {
	    data[i] = random_byte();
	} while (data[i] == 0);
    }
    data[key->bytes-length-1] = 0;

    w = (key->bytes+1)/2;

    b1 = newbn(w);
    b2 = newbn(w);

    p = data;
    for (i=1; i<=w; i++)
	b1[i] = 0;
    for (i=0; i<key->bytes; i++) {
	unsigned char byte = *p++;
	if ((key->bytes-i) & 1)
	    b1[w-i/2] |= byte;
	else
	    b1[w-i/2] |= byte<<8;
    }

    debug(b1);

    modpow(b1, key->exponent, key->modulus, b2);

    debug(b2);

    p = data;
    for (i=0; i<key->bytes; i++) {
	unsigned char b;
	if (i & 1)
	    b = b2[w-i/2] & 0xFF;
	else
	    b = b2[w-i/2] >> 8;
	*p++ = b;
    }

    freebn(b1);
    freebn(b2);
}
Пример #7
0
void Profile::InitGeneralData()
{
	// Init m_iGuid.
	// Does the RNG need to be inited and seeded every time?
	random_init();
	random_add_noise( "ai8049ujr3odusj" );
	
	{
		m_sGuid = "";
		for( unsigned i=0; i<GUID_SIZE_BYTES; i++ )
			m_sGuid += ssprintf( "%02x", random_byte() );
	}


	m_bUsingProfileDefaultModifiers = false;
	m_sDefaultModifiers = "";
	m_SortOrder = SORT_INVALID;
	m_LastDifficulty = DIFFICULTY_INVALID;
	m_LastCourseDifficulty = DIFFICULTY_INVALID;
	m_lastSong.Unset();
	m_lastCourse.Unset();
	m_iTotalPlays = 0;
	m_iTotalPlaySeconds = 0;
	m_iTotalGameplaySeconds = 0;
	m_iCurrentCombo = 0;
	m_fTotalCaloriesBurned = 0;
	m_iTotalDancePoints = 0;
	m_iNumExtraStagesPassed = 0;
	m_iNumExtraStagesFailed = 0;
	m_iNumToasties = 0;
	m_UnlockedSongs.clear();
	m_sLastPlayedMachineGuid = "";
	m_LastPlayedDate.Init();
	m_iTotalTapsAndHolds = 0;
	m_iTotalJumps = 0;
	m_iTotalHolds = 0;
	m_iTotalMines = 0;
	m_iTotalHands = 0;

	int i;
	for( i=0; i<NUM_PLAY_MODES; i++ )
		m_iNumSongsPlayedByPlayMode[i] = 0;
	m_iNumSongsPlayedByStyle.clear();
	for( i=0; i<NUM_DIFFICULTIES; i++ )
		m_iNumSongsPlayedByDifficulty[i] = 0;
	for( i=0; i<MAX_METER+1; i++ )
		m_iNumSongsPlayedByMeter[i] = 0;
	ZERO( m_iNumStagesPassedByPlayMode );
	ZERO( m_iNumStagesPassedByGrade );
}
Пример #8
0
struct X11FakeAuth *x11_invent_fake_auth(tree234 *authtree, int authtype)
{
    struct X11FakeAuth *auth = snew(struct X11FakeAuth);
    int i;

    /*
     * This function has the job of inventing a set of X11 fake auth
     * data, and adding it to 'authtree'. We must preserve the
     * property that for any given actual authorisation attempt, _at
     * most one_ thing in the tree can possibly match it.
     *
     * For MIT-MAGIC-COOKIE-1, that's not too difficult: the match
     * criterion is simply that the entire cookie is correct, so we
     * just have to make sure we don't make up two cookies the same.
     * (Vanishingly unlikely, but we check anyway to be sure, and go
     * round again inventing a new cookie if add234 tells us the one
     * we thought of is already in use.)
     *
     * For XDM-AUTHORIZATION-1, it's a little more fiddly. The setup
     * with XA1 is that half the cookie is used as a DES key with
     * which to CBC-encrypt an assortment of stuff. Happily, the stuff
     * encrypted _begins_ with the other half of the cookie, and the
     * IV is always zero, which means that any valid XA1 authorisation
     * attempt for a given cookie must begin with the same cipher
     * block, consisting of the DES ECB encryption of the first half
     * of the cookie using the second half as a key. So we compute
     * that cipher block here and now, and use it as the sorting key
     * for distinguishing XA1 entries in the tree.
     */

    if (authtype == X11_MIT) {
	auth->proto = X11_MIT;

	/* MIT-MAGIC-COOKIE-1. Cookie size is 128 bits (16 bytes). */
        auth->datalen = 16;
	auth->data = snewn(auth->datalen, unsigned char);
        auth->xa1_firstblock = NULL;

        while (1) {
            for (i = 0; i < auth->datalen; i++)
                auth->data[i] = random_byte();
            if (add234(authtree, auth) == auth)
                break;
        }

	auth->xdmseen = NULL;
    } else {
Пример #9
0
// allocate (from normal malloc) a block of size blocks
//  and put data into it
// This supports data integrity tests.
unsigned char *allocate_and_fill(int size) {
  unsigned char *result;
  unsigned char *ptr;

  result = (unsigned char *) malloc(size);
  if (result == (unsigned char *) 0) {
    fprintf(stderr,"real memory system out of memory.\n");
    abort();
  }

  if (VERBOSE) {
      printf("ref fill for %x\n", result);
  }

  for (ptr = result; ptr < result + size; ptr++) {
    *ptr = random_byte();
    if (VERBOSE) {     // very
      printf("\tputting %u in %x\n", *ptr, ptr);
    }
  }

  return result;
}
Пример #10
0
/*
 * Save an RSA key file. Return nonzero on success.
 */
int saversakey(const Filename *filename, struct RSAKey *key, char *passphrase)
{
    unsigned char buf[16384];
    unsigned char keybuf[16];
    struct MD5Context md5c;
    unsigned char *p, *estart;
    FILE *fp;

    /*
     * Write the initial signature.
     */
    p = buf;
    memcpy(p, rsa_signature, sizeof(rsa_signature));
    p += sizeof(rsa_signature);

    /*
     * One byte giving encryption type, and one reserved (zero)
     * uint32.
     */
    *p++ = (passphrase ? SSH_CIPHER_3DES : 0);
    PUT_32BIT(p, 0);
    p += 4;

    /*
     * An ordinary SSH-1 public key consists of: a uint32
     * containing the bit count, then two bignums containing the
     * modulus and exponent respectively.
     */
    PUT_32BIT(p, bignum_bitcount(key->modulus));
    p += 4;
    p += ssh1_write_bignum(p, key->modulus);
    p += ssh1_write_bignum(p, key->exponent);

    /*
     * A string containing the comment field.
     */
    if (key->comment) {
	PUT_32BIT(p, strlen(key->comment));
	p += 4;
	memcpy(p, key->comment, strlen(key->comment));
	p += strlen(key->comment);
    } else {
	PUT_32BIT(p, 0);
	p += 4;
    }

    /*
     * The encrypted portion starts here.
     */
    estart = p;

    /*
     * Two bytes, then the same two bytes repeated.
     */
    *p++ = random_byte();
    *p++ = random_byte();
    p[0] = p[-2];
    p[1] = p[-1];
    p += 2;

    /*
     * Four more bignums: the decryption exponent, then iqmp, then
     * q, then p.
     */
    p += ssh1_write_bignum(p, key->private_exponent);
    p += ssh1_write_bignum(p, key->iqmp);
    p += ssh1_write_bignum(p, key->q);
    p += ssh1_write_bignum(p, key->p);

    /*
     * Now write zeros until the encrypted portion is a multiple of
     * 8 bytes.
     */
    while ((p - estart) % 8)
	*p++ = '\0';

    /*
     * Now encrypt the encrypted portion.
     */
    if (passphrase) {
	MD5Init(&md5c);
	MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
	MD5Final(keybuf, &md5c);
	des3_encrypt_pubkey(keybuf, estart, p - estart);
	smemclr(keybuf, sizeof(keybuf));	/* burn the evidence */
    }

    /*
     * Done. Write the result to the file.
     */
    fp = f_open(filename, "wb", TRUE);
    if (fp) {
	int ret = (fwrite(buf, 1, p - buf, fp) == (size_t) (p - buf));
        if (fclose(fp))
            ret = 0;
	return ret;
    } else
	return 0;
}
Пример #11
0
Файл: ssh.c Проект: rdebath/sgt
static void ssh_protocol(unsigned char *in, int inlen, int ispkt) {
    int i, j, len;
    unsigned char session_id[16];
    unsigned char *rsabuf, *keystr1, *keystr2;
    unsigned char cookie[8];
    struct RSAKey servkey, hostkey;
    struct MD5Context md5c;
    unsigned long supported_ciphers_mask;
    int cipher_type;

    extern struct ssh_cipher ssh_3des;
    extern struct ssh_cipher ssh_blowfish;

    crBegin;

    random_init();

    while (!ispkt)
	crReturnV;

    if (pktin.type != 2)
	fatalbox("Public key packet not received");

    memcpy(cookie, pktin.body, 8);

    MD5Init(&md5c);

    i = makekey(pktin.body+8, &servkey, &keystr1);

    j = makekey(pktin.body+8+i, &hostkey, &keystr2);

    supported_ciphers_mask = (pktin.body[12+i+j] << 24) |
                             (pktin.body[13+i+j] << 16) |
                             (pktin.body[14+i+j] << 8) |
                             (pktin.body[15+i+j]);

    MD5Update(&md5c, keystr2, hostkey.bytes);
    MD5Update(&md5c, keystr1, servkey.bytes);
    MD5Update(&md5c, pktin.body, 8);

    MD5Final(session_id, &md5c);

    for (i=0; i<32; i++)
	session_key[i] = random_byte();

    len = (hostkey.bytes > servkey.bytes ? hostkey.bytes : servkey.bytes);

    rsabuf = malloc(len);
    if (!rsabuf)
	fatalbox("Out of memory");

    verify_ssh_host_key(savedhost, &hostkey);

    for (i=0; i<32; i++) {
	rsabuf[i] = session_key[i];
	if (i < 16)
	    rsabuf[i] ^= session_id[i];
    }

    if (hostkey.bytes > servkey.bytes) {
	rsaencrypt(rsabuf, 32, &servkey);
	rsaencrypt(rsabuf, servkey.bytes, &hostkey);
    } else {
	rsaencrypt(rsabuf, 32, &hostkey);
	rsaencrypt(rsabuf, hostkey.bytes, &servkey);
    }

    cipher_type = cfg.cipher == CIPHER_BLOWFISH ? SSH_CIPHER_BLOWFISH :
                  SSH_CIPHER_3DES;
    if ((supported_ciphers_mask & (1 << cipher_type)) == 0) {
	c_write("Selected cipher not supported, falling back to 3DES\r\n", 53);
	cipher_type = SSH_CIPHER_3DES;
    }

    s_wrpkt_start(3, len+15);
    pktout.body[0] = cipher_type;
    memcpy(pktout.body+1, cookie, 8);
    pktout.body[9] = (len*8) >> 8;
    pktout.body[10] = (len*8) & 0xFF;
    memcpy(pktout.body+11, rsabuf, len);
    pktout.body[len+11] = pktout.body[len+12] = 0;   /* protocol flags */
    pktout.body[len+13] = pktout.body[len+14] = 0;
    s_wrpkt();

    free(rsabuf);

    cipher = cipher_type == SSH_CIPHER_BLOWFISH ? &ssh_blowfish :
             &ssh_3des;
    cipher->sesskey(session_key);

    do { crReturnV; } while (!ispkt);

    if (pktin.type != 14)
	fatalbox("Encryption not successfully enabled");

    fflush(stdout);
    {
	static char username[100];
	static int pos = 0;
	static char c;
	if (!*cfg.username) {
	    c_write("login as: ", 10);
	    while (pos >= 0) {
		do { crReturnV; } while (ispkt);
		while (inlen--) switch (c = *in++) {
		  case 10: case 13:
		    username[pos] = 0;
		    pos = -1;
		    break;
		  case 8: case 127:
		    if (pos > 0) {
			c_write("\b \b", 3);
			pos--;
		    }
		    break;
		  case 21: case 27:
		    while (pos > 0) {
			c_write("\b \b", 3);
			pos--;
		    }
		    break;
		  case 3: case 4:
		    random_save_seed();
		    exit(0);
		    break;
		  default:
		    if (c >= ' ' && c <= '~' && pos < 40) {
			username[pos++] = c;
			c_write(&c, 1);
		    }
		    break;
		}
	    }
	    c_write("\r\n", 2);
	    username[strcspn(username, "\n\r")] = '\0';
	} else {
	    char stuff[200];
	    strncpy(username, cfg.username, 99);
	    username[99] = '\0';
	    sprintf(stuff, "Sent username \"%s\".\r\n", username);
	    c_write(stuff, strlen(stuff));
	}
	s_wrpkt_start(4, 4+strlen(username));
	pktout.body[0] = pktout.body[1] = pktout.body[2] = 0;
	pktout.body[3] = strlen(username);
	memcpy(pktout.body+4, username, strlen(username));
	s_wrpkt();
    }

    do { crReturnV; } while (!ispkt);

    while (pktin.type == 15) {
	static char password[100];
	static int pos;
	static char c;
	c_write("password: "******"\r\n", 2);
	s_wrpkt_start(9, 4+strlen(password));
	pktout.body[0] = pktout.body[1] = pktout.body[2] = 0;
	pktout.body[3] = strlen(password);
	memcpy(pktout.body+4, password, strlen(password));
	s_wrpkt();
	memset(password, 0, strlen(password));
	do { crReturnV; } while (!ispkt);
	if (pktin.type == 15) {
	    c_write("Access denied\r\n", 15);
	} else if (pktin.type != 14) {
	    fatalbox("Strange packet received, type %d", pktin.type);
	}
    }

    if (!cfg.nopty) {
        i = strlen(cfg.termtype);
        s_wrpkt_start(10, i+5*4+1);
        pktout.body[0] = (i >> 24) & 0xFF;
        pktout.body[1] = (i >> 16) & 0xFF;
        pktout.body[2] = (i >> 8) & 0xFF;
        pktout.body[3] = i & 0xFF;
        memcpy(pktout.body+4, cfg.termtype, i);
        i += 4;
        pktout.body[i++] = (rows >> 24) & 0xFF;
        pktout.body[i++] = (rows >> 16) & 0xFF;
        pktout.body[i++] = (rows >> 8) & 0xFF;
        pktout.body[i++] = rows & 0xFF;
        pktout.body[i++] = (cols >> 24) & 0xFF;
        pktout.body[i++] = (cols >> 16) & 0xFF;
        pktout.body[i++] = (cols >> 8) & 0xFF;
        pktout.body[i++] = cols & 0xFF;
        memset(pktout.body+i, 0, 9);       /* 0 pixwidth, 0 pixheight, 0.b endofopt */
        s_wrpkt();
        ssh_state = SSH_STATE_INTERMED;
        do { crReturnV; } while (!ispkt);
        if (pktin.type != 14 && pktin.type != 15) {
            fatalbox("Protocol confusion");
        } else if (pktin.type == 15) {
            c_write("Server refused to allocate pty\r\n", 32);
        }
    }
Пример #12
0
struct X11Display *x11_setup_display(char *display, int authtype, Conf *conf)
{
    struct X11Display *disp = snew(struct X11Display);
    char *localcopy;
    int i;

    if (!display || !*display) {
	localcopy = platform_get_x_display();
	if (!localcopy || !*localcopy) {
	    sfree(localcopy);
	    localcopy = dupstr(":0");  /* plausible default for any platform */
	}
    } else
	localcopy = dupstr(display);

    /*
     * Parse the display name.
     *
     * We expect this to have one of the following forms:
     * 
     *  - the standard X format which looks like
     *    [ [ protocol '/' ] host ] ':' displaynumber [ '.' screennumber ]
     *    (X11 also permits a double colon to indicate DECnet, but
     *    that's not our problem, thankfully!)
     *
     * 	- only seen in the wild on MacOS (so far): a pathname to a
     * 	  Unix-domain socket, which will typically and confusingly
     * 	  end in ":0", and which I'm currently distinguishing from
     * 	  the standard scheme by noting that it starts with '/'.
     */
    if (localcopy[0] == '/') {
	disp->unixsocketpath = localcopy;
	disp->unixdomain = TRUE;
	disp->hostname = NULL;
	disp->displaynum = -1;
	disp->screennum = 0;
	disp->addr = NULL;
    } else {
	char *colon, *dot, *slash;
	char *protocol, *hostname;

	colon = strrchr(localcopy, ':');
	if (!colon) {
	    sfree(disp);
	    sfree(localcopy);
	    return NULL;	       /* FIXME: report a specific error? */
	}

	*colon++ = '\0';
	dot = strchr(colon, '.');
	if (dot)
	    *dot++ = '\0';

	disp->displaynum = atoi(colon);
	if (dot)
	    disp->screennum = atoi(dot);
	else
	    disp->screennum = 0;

	protocol = NULL;
	hostname = localcopy;
	if (colon > localcopy) {
	    slash = strchr(localcopy, '/');
	    if (slash) {
		*slash++ = '\0';
		protocol = localcopy;
		hostname = slash;
	    }
	}

	disp->hostname = *hostname ? dupstr(hostname) : NULL;

	if (protocol)
	    disp->unixdomain = (!strcmp(protocol, "local") ||
				!strcmp(protocol, "unix"));
	else if (!*hostname || !strcmp(hostname, "unix"))
	    disp->unixdomain = platform_uses_x11_unix_by_default;
	else
	    disp->unixdomain = FALSE;

	if (!disp->hostname && !disp->unixdomain)
	    disp->hostname = dupstr("localhost");

	disp->unixsocketpath = NULL;
	disp->addr = NULL;

	sfree(localcopy);
    }

    /*
     * Look up the display hostname, if we need to.
     */
    if (!disp->unixdomain) {
	const char *err;

	disp->port = 6000 + disp->displaynum;
	disp->addr = name_lookup(disp->hostname, disp->port,
				 &disp->realhost, conf, ADDRTYPE_UNSPEC);
    
	if ((err = sk_addr_error(disp->addr)) != NULL) {
	    sk_addr_free(disp->addr);
	    sfree(disp->hostname);
	    sfree(disp->unixsocketpath);
	    sfree(disp);
	    return NULL;	       /* FIXME: report an error */
	}
    }

    /*
     * Try upgrading an IP-style localhost display to a Unix-socket
     * display (as the standard X connection libraries do).
     */
    if (!disp->unixdomain && sk_address_is_local(disp->addr)) {
	SockAddr ux = platform_get_x11_unix_address(NULL, disp->displaynum);
	const char *err = sk_addr_error(ux);
	if (!err) {
	    /* Create trial connection to see if there is a useful Unix-domain
	     * socket */
	    const struct plug_function_table *dummy = &dummy_plug;
	    Socket s = putty_sk_new(sk_addr_dup(ux), 0, 0, 0, 0, 0, (Plug)&dummy
	    #ifdef MPEXT
		,
	    0, 0
	    #endif
	    );
	    err = sk_socket_error(s);
	    sk_close(s);
	}
	if (err) {
	    sk_addr_free(ux);
	} else {
	    sk_addr_free(disp->addr);
	    disp->unixdomain = TRUE;
	    disp->addr = ux;
	    /* Fill in the rest in a moment */
	}
    }

    if (disp->unixdomain) {
	if (!disp->addr)
	    disp->addr = platform_get_x11_unix_address(disp->unixsocketpath,
						       disp->displaynum);
	if (disp->unixsocketpath)
	    disp->realhost = dupstr(disp->unixsocketpath);
	else
	    disp->realhost = dupprintf("unix:%d", disp->displaynum);
	disp->port = 0;
    }

    /*
     * Invent the remote authorisation details.
     */
    if (authtype == X11_MIT) {
	disp->remoteauthproto = X11_MIT;

	/* MIT-MAGIC-COOKIE-1. Cookie size is 128 bits (16 bytes). */
	disp->remoteauthdata = snewn(16, unsigned char);
	for (i = 0; i < 16; i++)
	    disp->remoteauthdata[i] = random_byte();
	disp->remoteauthdatalen = 16;

	disp->xdmseen = NULL;
    } else {
Пример #13
0
int dsa_generate(struct dss_key *key, int bits, progfn_t pfn,
		 void *pfnparam)
{
    Bignum qm1, power, g, h, tmp;
    unsigned pfirst, qfirst;
    int progress;

    /*
     * Set up the phase limits for the progress report. We do this
     * by passing minus the phase number.
     *
     * For prime generation: our initial filter finds things
     * coprime to everything below 2^16. Computing the product of
     * (p-1)/p for all prime p below 2^16 gives about 20.33; so
     * among B-bit integers, one in every 20.33 will get through
     * the initial filter to be a candidate prime.
     *
     * Meanwhile, we are searching for primes in the region of 2^B;
     * since pi(x) ~ x/log(x), when x is in the region of 2^B, the
     * prime density will be d/dx pi(x) ~ 1/log(B), i.e. about
     * 1/0.6931B. So the chance of any given candidate being prime
     * is 20.33/0.6931B, which is roughly 29.34 divided by B.
     *
     * So now we have this probability P, we're looking at an
     * exponential distribution with parameter P: we will manage in
     * one attempt with probability P, in two with probability
     * P(1-P), in three with probability P(1-P)^2, etc. The
     * probability that we have still not managed to find a prime
     * after N attempts is (1-P)^N.
     * 
     * We therefore inform the progress indicator of the number B
     * (29.34/B), so that it knows how much to increment by each
     * time. We do this in 16-bit fixed point, so 29.34 becomes
     * 0x1D.57C4.
     */
    pfn(pfnparam, PROGFN_PHASE_EXTENT, 1, 0x2800);
    pfn(pfnparam, PROGFN_EXP_PHASE, 1, -0x1D57C4 / 160);
    pfn(pfnparam, PROGFN_PHASE_EXTENT, 2, 0x40 * bits);
    pfn(pfnparam, PROGFN_EXP_PHASE, 2, -0x1D57C4 / bits);

    /*
     * In phase three we are finding an order-q element of the
     * multiplicative group of p, by finding an element whose order
     * is _divisible_ by q and raising it to the power of (p-1)/q.
     * _Most_ elements will have order divisible by q, since for a
     * start phi(p) of them will be primitive roots. So
     * realistically we don't need to set this much below 1 (64K).
     * Still, we'll set it to 1/2 (32K) to be on the safe side.
     */
    pfn(pfnparam, PROGFN_PHASE_EXTENT, 3, 0x2000);
    pfn(pfnparam, PROGFN_EXP_PHASE, 3, -32768);

    /*
     * In phase four we are finding an element x between 1 and q-1
     * (exclusive), by inventing 160 random bits and hoping they
     * come out to a plausible number; so assuming q is uniformly
     * distributed between 2^159 and 2^160, the chance of any given
     * attempt succeeding is somewhere between 0.5 and 1. Lacking
     * the energy to arrange to be able to specify this probability
     * _after_ generating q, we'll just set it to 0.75.
     */
    pfn(pfnparam, PROGFN_PHASE_EXTENT, 4, 0x2000);
    pfn(pfnparam, PROGFN_EXP_PHASE, 4, -49152);

    pfn(pfnparam, PROGFN_READY, 0, 0);

    invent_firstbits(&pfirst, &qfirst);
    /*
     * Generate q: a prime of length 160.
     */
    key->q = primegen(160, 2, 2, NULL, 1, pfn, pfnparam, qfirst);
    /*
     * Now generate p: a prime of length `bits', such that p-1 is
     * divisible by q.
     */
    key->p = primegen(bits-160, 2, 2, key->q, 2, pfn, pfnparam, pfirst);

    /*
     * Next we need g. Raise 2 to the power (p-1)/q modulo p, and
     * if that comes out to one then try 3, then 4 and so on. As
     * soon as we hit a non-unit (and non-zero!) one, that'll do
     * for g.
     */
    power = bigdiv(key->p, key->q);    /* this is floor(p/q) == (p-1)/q */
    h = bignum_from_long(1);
    progress = 0;
    while (1) {
	pfn(pfnparam, PROGFN_PROGRESS, 3, ++progress);
	g = modpow(h, power, key->p);
	if (bignum_cmp(g, One) > 0)
	    break;		       /* got one */
	tmp = h;
	h = bignum_add_long(h, 1);
	freebn(tmp);
    }
    key->g = g;
    freebn(h);

    /*
     * Now we're nearly done. All we need now is our private key x,
     * which should be a number between 1 and q-1 exclusive, and
     * our public key y = g^x mod p.
     */
    qm1 = copybn(key->q);
    decbn(qm1);
    progress = 0;
    while (1) {
	int i, v, byte, bitsleft;
	Bignum x;

	pfn(pfnparam, PROGFN_PROGRESS, 4, ++progress);
	x = bn_power_2(159);
	byte = 0;
	bitsleft = 0;

	for (i = 0; i < 160; i++) {
	    if (bitsleft <= 0)
		bitsleft = 8, byte = random_byte();
	    v = byte & 1;
	    byte >>= 1;
	    bitsleft--;
	    bignum_set_bit(x, i, v);
	}

	if (bignum_cmp(x, One) <= 0 || bignum_cmp(x, qm1) >= 0) {
	    freebn(x);
	    continue;
	} else {
	    key->x = x;
	    break;
	}
    }
    freebn(qm1);

    key->y = modpow(key->g, key->x, key->p);

    return 1;
}
Пример #14
0
static char *make_dirname(const char *pi_name, char **logtext)
{
    char *name, *parentdirname, *dirname, *err;

    /*
     * First, create the top-level directory for all shared PuTTY
     * connections owned by this user.
     */
    parentdirname = make_parentdir_name();
    if ((err = make_dir_and_check_ours(parentdirname)) != NULL) {
        *logtext = err;
        sfree(parentdirname);
        return NULL;
    }

    /*
     * Transform the platform-independent version of the connection
     * identifier into the name we'll actually use for the directory
     * containing the Unix socket.
     *
     * We do this by hashing the identifier with some user-specific
     * secret information, to avoid the privacy leak of having
     * "user@host" strings show up in 'netstat -x'. (Irritatingly, the
     * full pathname of a Unix-domain socket _does_ show up in the
     * 'netstat -x' output, at least on Linux, even if that socket is
     * in a directory not readable to the user running netstat. You'd
     * think putting things inside an 0700 directory would hide their
     * names from other users, but no.)
     *
     * The secret information we use to salt the hash lives in a file
     * inside the top-level directory we just created, so we must
     * first create that file (with some fresh random data in it) if
     * it's not already been done by a previous PuTTY.
     */
    {
        unsigned char saltbuf[SALT_SIZE];
        char *saltname;
        int saltfd, i, ret;

        saltname = dupprintf("%s/%s", parentdirname, SALT_FILENAME);
        saltfd = open(saltname, O_RDONLY);
        if (saltfd < 0) {
            char *tmpname;
            int pid;

            if (errno != ENOENT) {
                *logtext = dupprintf("%s: open: %s", saltname,
                                     strerror(errno));
                sfree(saltname);
                sfree(parentdirname);
                return NULL;
            }

            /*
             * The salt file doesn't already exist, so try to create
             * it. Another process may be attempting the same thing
             * simultaneously, so we must do this carefully: we write
             * a salt file under a different name, then hard-link it
             * into place, which guarantees that we won't change the
             * contents of an existing salt file.
             */
            pid = getpid();
            for (i = 0;; i++) {
                tmpname = dupprintf("%s/%s.tmp.%d.%d",
                                    parentdirname, SALT_FILENAME, pid, i);
                saltfd = open(tmpname, O_WRONLY | O_EXCL | O_CREAT, 0400);
                if (saltfd >= 0)
                    break;
                if (errno != EEXIST) {
                    *logtext = dupprintf("%s: open: %s", tmpname,
                                         strerror(errno));
                    sfree(tmpname);
                    sfree(saltname);
                    sfree(parentdirname);
                    return NULL;
                }
                sfree(tmpname);        /* go round and try again with i+1 */
            }
            /*
             * Invent some random data.
             */
            for (i = 0; i < SALT_SIZE; i++) {
                saltbuf[i] = random_byte();
            }
            ret = write(saltfd, saltbuf, SALT_SIZE);
            /* POSIX atomicity guarantee: because we wrote less than
             * PIPE_BUF bytes, the write either completed in full or
             * failed. */
            assert(SALT_SIZE < PIPE_BUF);
            assert(ret < 0 || ret == SALT_SIZE);
            if (ret < 0) {
                close(saltfd);
                *logtext = dupprintf("%s: write: %s", tmpname,
                                     strerror(errno));
                sfree(tmpname);
                sfree(saltname);
                sfree(parentdirname);
                return NULL;
            }
            if (close(saltfd) < 0) {
                *logtext = dupprintf("%s: close: %s", tmpname,
                                     strerror(errno));
                sfree(tmpname);
                sfree(saltname);
                sfree(parentdirname);
                return NULL;
            }

            /*
             * Now attempt to hard-link our temp file into place. We
             * tolerate EEXIST as an outcome, because that just means
             * another PuTTY got their attempt in before we did (and
             * we only care that there is a valid salt file we can
             * agree on, no matter who created it).
             */
            if (link(tmpname, saltname) < 0 && errno != EEXIST) {
                *logtext = dupprintf("%s: link: %s", saltname,
                                     strerror(errno));
                sfree(tmpname);
                sfree(saltname);
                sfree(parentdirname);
                return NULL;
            }

            /*
             * Whether that succeeded or not, get rid of our temp file.
             */
            if (unlink(tmpname) < 0) {
                *logtext = dupprintf("%s: unlink: %s", tmpname,
                                     strerror(errno));
                sfree(tmpname);
                sfree(saltname);
                sfree(parentdirname);
                return NULL;
            }

            /*
             * And now we've arranged for there to be a salt file, so
             * we can try to open it for reading again and this time
             * expect it to work.
             */
            sfree(tmpname);

            saltfd = open(saltname, O_RDONLY);
            if (saltfd < 0) {
                *logtext = dupprintf("%s: open: %s", saltname,
                                     strerror(errno));
                sfree(saltname);
                sfree(parentdirname);
                return NULL;
            }
        }

        for (i = 0; i < SALT_SIZE; i++) {
            ret = read(saltfd, saltbuf, SALT_SIZE);
            if (ret <= 0) {
                close(saltfd);
                *logtext = dupprintf("%s: read: %s", saltname,
                                     ret == 0 ? "unexpected EOF" :
                                     strerror(errno));
                sfree(saltname);
                sfree(parentdirname);
                return NULL;
            }
            assert(0 < ret && ret <= SALT_SIZE - i);
            i += ret;
        }

        close(saltfd);
        sfree(saltname);

        /*
         * Now we've got our salt, hash it with the connection
         * identifier to produce our actual socket name.
         */
        {
            SHA256_State sha;
            unsigned len;
            unsigned char lenbuf[4];
            unsigned char digest[32];
            char retbuf[65];

            SHA256_Init(&sha);
            PUT_32BIT(lenbuf, SALT_SIZE);
            SHA256_Bytes(&sha, lenbuf, 4);
            SHA256_Bytes(&sha, saltbuf, SALT_SIZE);
            len = strlen(pi_name);
            PUT_32BIT(lenbuf, len);
            SHA256_Bytes(&sha, lenbuf, 4);
            SHA256_Bytes(&sha, pi_name, len);
            SHA256_Final(&sha, digest);

            /*
             * And make it printable.
             */
            for (i = 0; i < 32; i++) {
                sprintf(retbuf + 2*i, "%02x", digest[i]);
                /* the last of those will also write the trailing NUL */
            }

            name = dupstr(retbuf);
        }

        smemclr(saltbuf, sizeof(saltbuf));
    }

    dirname = dupprintf("%s/%s", parentdirname, name);
    sfree(parentdirname);
    sfree(name);

    return dirname;
}
Пример #15
0
/*
 * Generate a prime. We arrange to select a prime with the property
 * (prime % modulus) != residue (to speed up use in RSA).
 */
Bignum primegen(int bits, int modulus, int residue,
                int phase, progfn_t pfn, void *pfnparam) {
    int i, k, v, byte, bitsleft, check, checks;
    unsigned long delta, moduli[NPRIMES+1], residues[NPRIMES+1];
    Bignum p, pm1, q, wqp, wqp2;
    int progress = 0;

    byte = 0; bitsleft = 0;

    STARTOVER:

    pfn(pfnparam, phase, ++progress);

    /*
     * Generate a k-bit random number with top and bottom bits set.
     */
    p = newbn((bits+15)/16);
    for (i = 0; i < bits; i++) {
        if (i == 0 || i == bits-1)
            v = 1;
        else {
            if (bitsleft <= 0)
                bitsleft = 8; byte = random_byte();
            v = byte & 1;
            byte >>= 1;
            bitsleft--;
        }
        bignum_set_bit(p, i, v);
    }

    /*
     * Ensure this random number is coprime to the first few
     * primes, by repeatedly adding 2 to it until it is.
     */
    for (i = 0; i < NPRIMES; i++) {
        moduli[i] = primes[i];
        residues[i] = bignum_mod_short(p, primes[i]);
    }
    moduli[NPRIMES] = modulus;
    residues[NPRIMES] = (bignum_mod_short(p, (unsigned short)modulus)
                         + modulus - residue);
    delta = 0;
    while (1) {
        for (i = 0; i < (sizeof(moduli) / sizeof(*moduli)); i++)
            if (!((residues[i] + delta) % moduli[i]))
                break;
        if (i < (sizeof(moduli) / sizeof(*moduli))) {/* we broke */
            delta += 2;
            if (delta < 2) {
                freebn(p);
                goto STARTOVER;
            }
            continue;
        }
        break;
    }
    q = p;
    p = bignum_add_long(q, delta);
    freebn(q);

    /*
     * Now apply the Miller-Rabin primality test a few times. First
     * work out how many checks are needed.
     */
    checks = 27;
    if (bits >= 150) checks = 18;
    if (bits >= 200) checks = 15;
    if (bits >= 250) checks = 12;
    if (bits >= 300) checks = 9;
    if (bits >= 350) checks = 8;
    if (bits >= 400) checks = 7;
    if (bits >= 450) checks = 6;
    if (bits >= 550) checks = 5;
    if (bits >= 650) checks = 4;
    if (bits >= 850) checks = 3;
    if (bits >= 1300) checks = 2;

    /*
     * Next, write p-1 as q*2^k.
     */
    for (k = 0; bignum_bit(p, k) == !k; k++);   /* find first 1 bit in p-1 */
    q = bignum_rshift(p, k);
    /* And store p-1 itself, which we'll need. */
    pm1 = copybn(p);
    decbn(pm1);

    /*
     * Now, for each check ...
     */
    for (check = 0; check < checks; check++) {
        Bignum w;

        /*
         * Invent a random number between 1 and p-1 inclusive.
         */
        while (1) {
            w = newbn((bits+15)/16);
            for (i = 0; i < bits; i++) {
                if (bitsleft <= 0)
                    bitsleft = 8; byte = random_byte();
                v = byte & 1;
                byte >>= 1;
                bitsleft--;
                bignum_set_bit(w, i, v);
            }
            if (bignum_cmp(w, p) >= 0 || bignum_cmp(w, Zero) == 0) {
                freebn(w);
                continue;
            }
            break;
        }

        pfn(pfnparam, phase, ++progress);

        /*
         * Compute w^q mod p.
         */
        wqp = modpow(w, q, p);
        freebn(w);

        /*
         * See if this is 1, or if it is -1, or if it becomes -1
         * when squared at most k-1 times.
         */
        if (bignum_cmp(wqp, One) == 0 || bignum_cmp(wqp, pm1) == 0) {
            freebn(wqp);
            continue;
        }
        for (i = 0; i < k-1; i++) {
            wqp2 = modmul(wqp, wqp, p);
            freebn(wqp);
            wqp = wqp2;
            if (bignum_cmp(wqp, pm1) == 0)
                break;
        }
        if (i < k-1) {
            freebn(wqp);
            continue;
        }

        /*
         * It didn't. Therefore, w is a witness for the
         * compositeness of p.
         */
        freebn(p);
        freebn(pm1);
        freebn(q);
        goto STARTOVER;
    }

    /*
     * We have a prime!
     */
    freebn(q);
    freebn(pm1);
    return p;
}