Beispiel #1
0
	void Sha::Update(const void* data,uint len){
		if(_bits==sha_160){
			sha1_update(tvcast<sha1_context>(_sha_ctx),(byte*)data,len);
		}else if(_bits==sha_224||_bits==sha_256){
			sha2_update(tvcast<sha2_context>(_sha_ctx),(byte*)data,len);
		}else if(_bits==sha_384||_bits==sha_512){
			sha4_update(tvcast<sha4_context>(_sha_ctx),(byte*)data,len);
		}else{
			_ASSERT(0);
		} 
	}
Beispiel #2
0
int entropy_func( void *data, unsigned char *output, size_t len )
{
    int ret, count = 0, i, reached;
    entropy_context *ctx = (entropy_context *) data;
    unsigned char buf[ENTROPY_BLOCK_SIZE];

    if( len > ENTROPY_BLOCK_SIZE )
        return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED );

    /*
     * Always gather extra entropy before a call
     */
    do
    {
        if( count++ > ENTROPY_MAX_LOOP )
            return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED );

        if( ( ret = entropy_gather( ctx ) ) != 0 )
            return( ret );

        reached = 0;

        for( i = 0; i < ctx->source_count; i++ )
            if( ctx->source[i].size >= ctx->source[i].threshold )
                reached++;
    }
    while( reached != ctx->source_count );

    memset( buf, 0, ENTROPY_BLOCK_SIZE );

    sha4_finish( &ctx->accumulator, buf );
                
    /*
     * Perform second SHA-512 on entropy
     */
    sha4( buf, ENTROPY_BLOCK_SIZE, buf, 0 );

    /*
     * Reset accumulator and counters and recycle existing entropy
     */
    memset( &ctx->accumulator, 0, sizeof( sha4_context ) );
    sha4_starts( &ctx->accumulator, 0 );
    sha4_update( &ctx->accumulator, buf, ENTROPY_BLOCK_SIZE );

    for( i = 0; i < ctx->source_count; i++ )
        ctx->source[i].size = 0;

    memcpy( output, buf, len );

    return( 0 );
}
Beispiel #3
0
/*
 * Entropy accumulator update
 */
int entropy_update( entropy_context *ctx, unsigned char source_id,
                    const unsigned char *data, size_t len )
{
    unsigned char header[2];
    unsigned char tmp[ENTROPY_BLOCK_SIZE];
    size_t use_len = len;
    const unsigned char *p = data;
   
    if( use_len > ENTROPY_BLOCK_SIZE )
    {
        sha4( data, len, tmp, 0 );

        p = tmp;
        use_len = ENTROPY_BLOCK_SIZE;
    }

    header[0] = source_id;
    header[1] = use_len & 0xFF;

    sha4_update( &ctx->accumulator, header, 2 );
    sha4_update( &ctx->accumulator, p, use_len );
    
    return( 0 );
}
Beispiel #4
0
// Process some data
void mintls_hash_update(
    mintls_hash_context *   ctx,            // (I/O) Context
    uint8_t const*          input,          // (I) Data
    size_t                  ilen            // (I) Length
)
{
    switch (ctx->type)
    {
    case MinTLS_SHA_160:
        sha1_update((struct sha1_ctx *)ctx,input,ilen);
        break;
    case MinTLS_SHA_256:
    case MinTLS_SHA_224:
        sha2_update((struct sha2_ctx *)ctx,input,ilen);
        break;
    case MinTLS_SHA_384:
    case MinTLS_SHA_512:
        sha4_update((struct sha4_ctx *)ctx,input,ilen);
        break;
    }
    return;
}
Beispiel #5
0
void sha512_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
{
    sha4_update( (sha4_context *) ctx, input, ilen );
}
Beispiel #6
0
int message_rsa_decrypt(VCRYPT_CTX *ctx, rsa_context *public_rsa,
		uint8_t *ciphertext, size_t len, char **decrypted)
{
	int ret = 0;
	int ret_len = 0;

	if (len < 5)
		return -ERR_DECRYPTION_ERROR;

	if (*ciphertext++ != VCRYPT_PROTOCOL_VERSION)
		return -ERR_DECRYPTION_ERROR;

	uint16_t encr_key_len = *((uint16_t*) ciphertext);
	ciphertext += 2;
	uint16_t sig_key_len = *((uint16_t*) ciphertext);
	ciphertext += 2;

	if (encr_key_len != ctx->ssl_req.rsa.len)
		return -ERR_DECRYPTION_ERROR;

	if ((len - 5 - sig_key_len) % encr_key_len)
		return -ERR_DECRYPTION_ERROR;

	int ciphertext_chunks = (len - 5 - sig_key_len) / encr_key_len;

	// maximum possible plaintext length
	int plain_len = ciphertext_chunks * ctx->ssl_req.rsa.len;

	if (ciphertext_chunks < 1)
		return -ERR_DECRYPTION_ERROR; // we need the signature too

	*decrypted = malloc(plain_len + 1); // 1 char for the null terminator
	if (!*decrypted)
		return -ERR_MALLOC;

	int chunk;
	size_t decrypted_len = 0;
	uint8_t *in = ciphertext, *out = (uint8_t*) *decrypted;

	for (chunk = 0; chunk < ciphertext_chunks;
			chunk++, out += decrypted_len, in += ctx->ssl_req.rsa.len) {
		if ((ret = rsa_pkcs1_decrypt(&ctx->ssl_req.rsa, RSA_PRIVATE,
				&decrypted_len, in, out, ctx->ssl_req.rsa.len)) != 0) {

			char err[256];
			error_strerror(ret, err, sizeof err);
			dolog(0,
					" failed\n  ! rsa_pkcs1_decrypt returned %d: %s (chunk: %d)\n",
					ret, err, chunk);

			free(*decrypted);
			return -ERR_DECRYPTION_ERROR;
		}

		ret_len += decrypted_len;
	}

	*out = 0;

	if (!public_rsa || !public_rsa->len) {
		return -ERR_SIGN_VERIFY_ERROR;
	}

	unsigned char hash[64];
	sha4_context sha_ctx;
	sha4_starts(&sha_ctx, 1);
	sha4_update(&sha_ctx, (uint8_t*) *decrypted, ret_len);
	sha4_finish(&sha_ctx, hash);

	if ((ret = rsa_pkcs1_verify(public_rsa, RSA_PUBLIC, public_rsa->hash_id,
			sizeof hash, hash, in)) != 0) {

		char err[256];
		error_strerror(ret, err, sizeof err);
		dolog(0,
				" failed\n  ! rsa_pkcs1_verify returned %d: %s\nmessage was: %s\n",
				ret, err, *decrypted);

		return -ERR_SIGN_VERIFY_ERROR;
	}

	return ret_len;
}
Beispiel #7
0
int message_rsa_encrypt(VCRYPT_CTX *ctx, rsa_context *public_rsa,
		const char *username, const char *message, VCRYPT_PACKET **packet)
{
	int ret;
	/*
	 * format:
	 * 1 byte protocol version
	 * 2 bytes encryption key size in bytes
	 * 2 bytes signature key size in bytes
	 * ciphertext
	 * signature
	 *
	 */

	if (!public_rsa->len)
		return -ERR_NO_PUBKEY;

	// we dont encrypt null terminating char, as this creates a vector of attack
	int plain_len = strlen(message);
	if (plain_len == 0)
		return -ERR_ENCRYPTION_ERROR;

	size_t plain_chunk_len = public_rsa->len - 11;
	// get packet size
	int plain_chunks = ceil(plain_len / (float) plain_chunk_len);
	int ciphertext_len = plain_chunks * public_rsa->len;

	// space for signature
	ciphertext_len += ctx->ssl_req.rsa.len;

	*packet = packet_new(DEST_CLIENT, username, REQ_MESSAGE_SEND,
			ciphertext_len + 5);
	if (!*packet)
		return -ERR_MALLOC;

	// TODO: add ciphertext stealing (form signature) to save bandwidth (i.e. use signature as padding)

	int chunk;
	int chunk_len;
	uint8_t *in = (uint8_t*) message, *out = (uint8_t*) (*packet)->payload;

	*out++ = VCRYPT_PROTOCOL_VERSION;
	*((uint16_t*) out) = public_rsa->len;
	out += 2;
	*((uint16_t*) out) = ctx->ssl_req.rsa.len;
	out += 2;

	for (chunk = 0; chunk < plain_chunks; chunk++, in += plain_chunk_len, out +=
			public_rsa->len) {

		// last usually has different length
		chunk_len =
				chunk == plain_chunks - 1 ?
						plain_len % plain_chunk_len : plain_chunk_len;

		if ((ret = rsa_pkcs1_encrypt(public_rsa, ctr_drbg_random,
				&ctx->ssl_req.ctr_drbg, RSA_PUBLIC, chunk_len, in, out) != 0)) {
			free(packet);
			return -ERR_ENCRYPTION_ERROR;
		}
	}

	unsigned char hash[64];
	sha4_context sha_ctx;
	sha4_starts(&sha_ctx, 1);
	sha4_update(&sha_ctx, (uint8_t*) message, plain_len);
	sha4_finish(&sha_ctx, hash);

	if ((ret = rsa_pkcs1_sign(&ctx->ssl_req.rsa, NULL, NULL, RSA_PRIVATE,
			ctx->ssl_req.rsa.hash_id, sizeof hash, hash, out) != 0)) {
		free(packet);
		return -ERR_SIGN_ERROR;
	}

	return 0;
}
Beispiel #8
0
char* crypt_sha512_r(const char *key, const char *salt, size_t rounds,
                     char *buffer, int buflen)
{
    uint8_t alt_result[64], temp_result[64];
    sha4_context ctx, alt_ctx;
    size_t salt_len, key_len, cnt;
    char *cp, *copied_key, *copied_salt, *p_bytes, *s_bytes;

    copied_key = NULL;
    copied_salt = NULL;

    salt_len = MIN(strcspn(salt, "$"), SALT_LEN_MAX);
    key_len = strlen(key);

    /* Prepare for the real work. */
    sha4_starts(&ctx, 0);

    /* Add the key string. */
    sha4_update(&ctx, (unsigned char*)key, key_len);

    /* The last part is the salt string. This must be at most 8
     * characters and it ends at the first `$' character (for
     * compatibility with existing implementations). */
    sha4_update(&ctx, (unsigned char*)salt, salt_len);

    /* Compute alternate SHA512 sum with input KEY, SALT, and KEY. The
     * final result will be added to the first context. */
    sha4_starts(&alt_ctx, 0);

    /* Add key. */
    sha4_update(&alt_ctx, (unsigned char*)key, key_len);

    /* Add salt. */
    sha4_update(&alt_ctx, (unsigned char*)salt, salt_len);

    /* Add key again. */
    sha4_update(&alt_ctx, (unsigned char*)key, key_len);

    /* Now get result of this (64 bytes) and add it to the other context. */
    sha4_finish(&alt_ctx, alt_result);

    /* Add for any character in the key one byte of the alternate sum. */
    for (cnt = key_len; cnt > 64; cnt -= 64)
        sha4_update(&ctx, (unsigned char*)alt_result, 64);
    sha4_update(&ctx, (unsigned char*)alt_result, cnt);

    /* Take the binary representation of the length of the key and for
     * every 1 add the alternate sum, for every 0 the key. */
    for (cnt = key_len; cnt > 0; cnt >>= 1)
        if ((cnt & 1) != 0)
            sha4_update(&ctx, (unsigned char*)alt_result, 64);
        else
            sha4_update(&ctx, (unsigned char*)key, key_len);

    /* Create intermediate result. */
    sha4_finish(&ctx, alt_result);

    /* Start computation of P byte sequence. */
    sha4_starts(&alt_ctx, 0);

    /* For every character in the password add the entire password. */
    for (cnt = 0; cnt < key_len; ++cnt)
        sha4_update(&alt_ctx, (unsigned char*)key, key_len);

    /* Finish the digest. */
    sha4_finish(&alt_ctx, temp_result);

    /* Create byte sequence P. */
    cp = p_bytes = alloca(key_len);
    for (cnt = key_len; cnt >= 64; cnt -= 64)
    {
        memcpy(cp, temp_result, 64);
        cp += 64;
    }
    memcpy(cp, temp_result, cnt);

    /* Start computation of S byte sequence. */
    sha4_starts(&alt_ctx, 0);

    /* For every character in the password add the entire password. */
    for (cnt = 0; cnt < 16 + alt_result[0]; ++cnt)
        sha4_update(&alt_ctx, (unsigned char*)salt, salt_len);

    /* Finish the digest. */
    sha4_finish(&alt_ctx, temp_result);

    /* Create byte sequence S. */
    cp = s_bytes = alloca(salt_len);
    for (cnt = salt_len; cnt >= 64; cnt -= 64)
    {
        memcpy(cp, temp_result, 64);
        cp += 64;
    }
    memcpy(cp, temp_result, cnt);

    /* Repeatedly run the collected hash value through SHA512 to burn CPU
     * cycles. */
    for (cnt = 0; cnt < rounds; ++cnt)
    {
        /* New context. */
        sha4_starts(&ctx, 0);

        /* Add key or last result. */
        if ((cnt & 1) != 0)
            sha4_update(&ctx, (unsigned char*)p_bytes, key_len);
        else
            sha4_update(&ctx, (unsigned char*)alt_result, 64);

        /* Add salt for numbers not divisible by 3. */
        if (cnt % 3 != 0)
            sha4_update(&ctx, (unsigned char*)s_bytes, salt_len);

        /* Add key for numbers not divisible by 7. */
        if (cnt % 7 != 0)
            sha4_update(&ctx, (unsigned char*)p_bytes, key_len);

        /* Add key or last result. */
        if ((cnt & 1) != 0)
            sha4_update(&ctx, (unsigned char*)alt_result, 64);
        else
            sha4_update(&ctx, (unsigned char*)p_bytes, key_len);

        /* Create intermediate result. */
        sha4_finish(&ctx, alt_result);
    }

    cp = buffer;
    b64_from_24bit(alt_result[0], alt_result[21], alt_result[42], 4,
                   &buflen, &cp);
    b64_from_24bit(alt_result[22], alt_result[43], alt_result[1], 4,
                   &buflen, &cp);
    b64_from_24bit(alt_result[44], alt_result[2], alt_result[23], 4,
                   &buflen, &cp);
    b64_from_24bit(alt_result[3], alt_result[24], alt_result[45], 4,
                   &buflen, &cp);
    b64_from_24bit(alt_result[25], alt_result[46], alt_result[4], 4,
                   &buflen, &cp);
    b64_from_24bit(alt_result[47], alt_result[5], alt_result[26], 4,
                   &buflen, &cp);
    b64_from_24bit(alt_result[6], alt_result[27], alt_result[48], 4,
                   &buflen, &cp);
    b64_from_24bit(alt_result[28], alt_result[49], alt_result[7], 4,
                   &buflen, &cp);
    b64_from_24bit(alt_result[50], alt_result[8], alt_result[29], 4,
                   &buflen, &cp);
    b64_from_24bit(alt_result[9], alt_result[30], alt_result[51], 4,
                   &buflen, &cp);
    b64_from_24bit(alt_result[31], alt_result[52], alt_result[10], 4,
                   &buflen, &cp);
    b64_from_24bit(alt_result[53], alt_result[11], alt_result[32], 4,
                   &buflen, &cp);
    b64_from_24bit(alt_result[12], alt_result[33], alt_result[54], 4,
                   &buflen, &cp);
    b64_from_24bit(alt_result[34], alt_result[55], alt_result[13], 4,
                   &buflen, &cp);
    b64_from_24bit(alt_result[56], alt_result[14], alt_result[35], 4,
                   &buflen, &cp);
    b64_from_24bit(alt_result[15], alt_result[36], alt_result[57], 4,
                   &buflen, &cp);
    b64_from_24bit(alt_result[37], alt_result[58], alt_result[16], 4,
                   &buflen, &cp);
    b64_from_24bit(alt_result[59], alt_result[17], alt_result[38], 4,
                   &buflen, &cp);
    b64_from_24bit(alt_result[18], alt_result[39], alt_result[60], 4,
                   &buflen, &cp);
    b64_from_24bit(alt_result[40], alt_result[61], alt_result[19], 4,
                   &buflen, &cp);
    b64_from_24bit(alt_result[62], alt_result[20], alt_result[41], 4,
                   &buflen, &cp);
    b64_from_24bit(0, 0, alt_result[63], 2, &buflen, &cp);

    if (buflen <= 0)
    {
        errno = ERANGE;
        buffer = NULL;
    }
    else
        *cp = '\0';

    return buffer;
}