예제 #1
0
/*
 * Key material generation
 */
int tls1_prf( unsigned char *secret, size_t slen, char *label,
              unsigned char *random, size_t rlen,
              unsigned char *dstbuf, size_t dlen )
{
    size_t nb, hs;
    size_t i, j, k;
    unsigned char *S1, *S2;
    unsigned char tmp[128];
    unsigned char h_i[20];

    if( sizeof( tmp ) < 20 + strlen( label ) + rlen )
        return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );

    hs = ( slen + 1 ) / 2;
    S1 = secret;
    S2 = secret + slen - hs;

    nb = strlen( label );
    memcpy( tmp + 20, label, nb );
    memcpy( tmp + 20 + nb, random, rlen );
    nb += rlen;

    /*
     * First compute P_md5(secret,label+random)[0..dlen]
     */
    md5_hmac( S1, hs, tmp + 20, nb, 4 + tmp );

    for( i = 0; i < dlen; i += 16 )
    {
        md5_hmac( S1, hs, 4 + tmp, 16 + nb, h_i );
        md5_hmac( S1, hs, 4 + tmp, 16,  4 + tmp );

        k = ( i + 16 > dlen ) ? dlen % 16 : 16;

        for( j = 0; j < k; j++ )
            dstbuf[i + j]  = h_i[j];
    }

    /*
     * XOR out with P_sha1(secret,label+random)[0..dlen]
     */
    sha1_hmac( S2, hs, tmp + 20, nb, tmp );

    for( i = 0; i < dlen; i += 20 )
    {
        sha1_hmac( S2, hs, tmp, 20 + nb, h_i );
        sha1_hmac( S2, hs, tmp, 20,      tmp );

        k = ( i + 20 > dlen ) ? dlen % 20 : 20;

        for( j = 0; j < k; j++ )
            dstbuf[i + j] = (unsigned char)( dstbuf[i + j] ^ h_i[j] );
    }

    memset( tmp, 0, sizeof( tmp ) );
    memset( h_i, 0, sizeof( h_i ) );

    return( 0 );
}
예제 #2
0
int main(int argc,char **argv)
{
/*
    start_le_adv(0,-1);
    printf("le_adv started successful\n");
    printf("now try to stop adv\n");
    stop_le_adv(0,-1);
*/
    int dev_id = hci_get_route(NULL);
    if(dev_id < 0)
    {
        printf("hci_get_route faild\n");
        return 1;
    }

    int dd = hci_open_dev(dev_id);
//    stop_le_adv(0,-1);

    uint8_t cmd_data[32]= {0x1F};
    MYDATA mydata;
    memset(&mydata,0,sizeof(MYDATA));
    mydata.device_id = htobe64(123456789);
    mydata.length = 0x1E;
    mydata.magic_number = MAGIC_NUMBER_PERIPHERAL_TO_CENTRAL;

    sha1_hmac(KEY,strlen(KEY),(unsigned char *)&mydata.device_id,8,(unsigned char *)&mydata.checksum);

    memcpy(cmd_data+1,&mydata,sizeof(MYDATA));
    set_adv_data(dev_id,cmd_data,sizeof(cmd_data));

    start_le_adv(0,-1);
    lescan(dev_id,PERIPHERAL);
    return 0;
}
예제 #3
0
파일: login.c 프로젝트: Kitof/openspotify
static void auth_generate_auth_hmac(struct login_ctx *l) {
        struct buf* buf = buf_new();
	
	buf_append_data(buf, l->client_parameters->ptr,
                        l->client_parameters->len);
	buf_append_data(buf,  l->server_parameters->ptr,
                        l->server_parameters->len);
        buf_append_u8(buf, 0); /* random data length */
        buf_append_u8(buf, 0); /* unknown */
        buf_append_u16(buf, 8); /* puzzle solution length */
        buf_append_u32(buf, 0); /* unknown */
        /* <-- random data would go here */
        buf_append_data(buf, l->puzzle_solution, 8);

#ifdef DEBUG_LOGIN
	hexdump8x32 ("auth_generate_auth_hmac, HMAC message", buf->ptr,
		     buf->len);
	hexdump8x32 ("auth_generate_auth_hmac, HMAC key", l->key_hmac,
		     sizeof (l->key_hmac));
#endif

	sha1_hmac(l->key_hmac, sizeof(l->key_hmac),
		    buf->ptr, buf->len, l->auth_hmac);

#ifdef DEBUG_LOGIN
	hexdump8x32 ("auth_generate_auth_hmac, HMAC digest", l->auth_hmac,
		     sizeof(l->auth_hmac));
#endif

	buf_free(buf);
}
예제 #4
0
파일: auth.c 프로젝트: alt-/bada-spotify
void auth_generate_auth_hmac (SESSION * session, unsigned char *auth_hmac,
		unsigned int mac_len)
{
	(void)mac_len;
	struct buf* buf = buf_new();

	buf_append_data(buf, session->init_client_packet->ptr,
			session->init_client_packet->len);
	buf_append_data(buf,  session->init_server_packet->ptr,
			session->init_server_packet->len);
	buf_append_u8(buf, 0); /* random data length */
	buf_append_u8(buf, 0); /* unknown */
	buf_append_u16(buf, 8); /* puzzle solution length */
	buf_append_u32(buf, 0); /* unknown */
	/* <-- random data would go here */
	buf_append_data(buf, session->puzzle_solution, 8);

#ifdef DEBUG_LOGIN
	hexdump8x32 ("auth_generate_auth_hmac, HMAC message", buf->ptr,
			buf->len);
	hexdump8x32 ("auth_generate_auth_hmac, HMAC key", session->key_hmac,
			sizeof (session->key_hmac));
#endif

	sha1_hmac ( session->key_hmac, sizeof (session->key_hmac),
			buf->ptr, buf->len, auth_hmac);

#ifdef DEBUG_LOGIN
	hexdump8x32 ("auth_generate_auth_hmac, HMAC digest", auth_hmac,
			mac_len);
#endif

	buf_free(buf);
}
예제 #5
0
int ss_gen_hash(buffer_t *buf, uint32_t *counter, enc_ctx_t *ctx, size_t capacity)
{
    ssize_t blen       = buf->len;
    uint16_t chunk_len = htons((uint16_t)blen);
    uint8_t hash[ONETIMEAUTH_BYTES * 2];
    uint8_t key[MAX_IV_LENGTH + sizeof(uint32_t)];
    uint32_t c = htonl(*counter);

    brealloc(buf, AUTH_BYTES + blen, capacity);
    memcpy(key, ctx->evp.iv, enc_iv_len);
    memcpy(key + enc_iv_len, &c, sizeof(uint32_t));
#if defined(USE_CRYPTO_OPENSSL)
    HMAC(EVP_sha1(), key, enc_iv_len + sizeof(uint32_t), (uint8_t *)buf->array, blen, hash, NULL);
#elif defined(USE_CRYPTO_MBEDTLS)
    mbedtls_md_hmac(mbedtls_md_info_from_type(
                        MBEDTLS_MD_SHA1), key, enc_iv_len + sizeof(uint32_t), (uint8_t *)buf->array, blen, hash);
#else
    sha1_hmac(key, enc_iv_len + sizeof(uint32_t), (uint8_t *)buf->array, blen, hash);
#endif

    memmove(buf->array + AUTH_BYTES, buf->array, blen);
    memcpy(buf->array + CLEN_BYTES, hash, ONETIMEAUTH_BYTES);
    memcpy(buf->array, &chunk_len, CLEN_BYTES);

    *counter = *counter + 1;
    buf->len = blen + AUTH_BYTES;

    return 0;
}
예제 #6
0
/* Anonymize a buffer of given length. Places the resulting digest into the
 * provided digest buffer, which must be at least ANONYMIZATION_DIGEST_LENGTH
 * bytes long. */
static void anonymization_process(const uint8_t* const data,
                                  const int len,
                                  unsigned char* const digest)
{
  assert(initialized);
  sha1_hmac(seed, ANONYMIZATION_SEED_LEN, data, len, digest);
}
예제 #7
0
static int verify_hash(u8 *p, u8 *hashes)
{
	u64 offset;
	u64 size;
	u64 id;
	u8 *hash, *key;
	u8 result[20];

	offset = be64(p + 0x00);
	size   = be64(p + 0x08);
	id     = be32(p + 0x1c);

	if (id == 0xffffffff)
		return 0;

	hash = hashes + id * 0x10; 
	key = hash + 0x20;

	// XXX: possible integer overflow here
	if (offset > (filesize + header_len))
		return 1;

	// XXX: possible integer overflow here
	if ((offset + size) > (filesize + header_len))
		return 1;

	sha1_hmac(key, ptr + offset, size, result);

	if (memcmp(result, hash, 20) == 0)
		return 0;
	else
		return -1;
}
예제 #8
0
int
ss_onetimeauth(buffer_t *buf, uint8_t *iv, size_t capacity)
{
    uint8_t hash[ONETIMEAUTH_BYTES * 2];
    uint8_t auth_key[MAX_IV_LENGTH + MAX_KEY_LENGTH];
    memcpy(auth_key, iv, enc_iv_len);
    memcpy(auth_key + enc_iv_len, enc_key, enc_key_len);

    brealloc(buf, ONETIMEAUTH_BYTES + buf->len, capacity);

#if defined(USE_CRYPTO_OPENSSL)
    HMAC(EVP_sha1(), auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->array, buf->len, (uint8_t *)hash, NULL);
#elif defined(USE_CRYPTO_MBEDTLS)
    mbedtls_md_hmac(mbedtls_md_info_from_type(
                        MBEDTLS_MD_SHA1), auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->array, buf->len,
                    (uint8_t *)hash);
#else
    sha1_hmac(auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->array, buf->len, (uint8_t *)hash);
#endif

    memcpy(buf->array + buf->len, hash, ONETIMEAUTH_BYTES);
    buf->len += ONETIMEAUTH_BYTES;

    return 0;
}
예제 #9
0
int
ss_check_hash(buffer_t *buf, chunk_t *chunk, enc_ctx_t *ctx, size_t capacity)
{
    int i, j, k;
    ssize_t blen  = buf->len;
    uint32_t cidx = chunk->idx;

    brealloc(chunk->buf, chunk->len + blen, capacity);
    brealloc(buf, chunk->len + blen, capacity);

    for (i = 0, j = 0, k = 0; i < blen; i++) {
        chunk->buf->array[cidx++] = buf->array[k++];

        if (cidx == CLEN_BYTES) {
            uint16_t clen = ntohs(*((uint16_t *)chunk->buf->array));
            brealloc(chunk->buf, clen + AUTH_BYTES, capacity);
            chunk->len = clen;
        }

        if (cidx == chunk->len + AUTH_BYTES) {
            // Compare hash
            uint8_t hash[ONETIMEAUTH_BYTES * 2];
            uint8_t key[MAX_IV_LENGTH + sizeof(uint32_t)];

            uint32_t c = htonl(chunk->counter);
            memcpy(key, ctx->evp.iv, enc_iv_len);
            memcpy(key + enc_iv_len, &c, sizeof(uint32_t));
#if defined(USE_CRYPTO_OPENSSL)
            HMAC(EVP_sha1(), key, enc_iv_len + sizeof(uint32_t),
                 (uint8_t *)chunk->buf->array + AUTH_BYTES, chunk->len, hash, NULL);
#elif defined(USE_CRYPTO_MBEDTLS)
            mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), key, enc_iv_len + sizeof(uint32_t),
                            (uint8_t *)chunk->buf->array + AUTH_BYTES, chunk->len, hash);
#else
            sha1_hmac(key, enc_iv_len + sizeof(uint32_t),
                      (uint8_t *)chunk->buf->array + AUTH_BYTES, chunk->len, hash);
#endif

            if (safe_memcmp(hash, chunk->buf->array + CLEN_BYTES, ONETIMEAUTH_BYTES) != 0) {
                return 0;
            }

            // Copy chunk back to buffer
            memmove(buf->array + j + chunk->len, buf->array + k, blen - i - 1);
            memcpy(buf->array + j, chunk->buf->array + AUTH_BYTES, chunk->len);

            // Reset the base offset
            j   += chunk->len;
            k    = j;
            cidx = 0;
            chunk->counter++;
        }
    }

    buf->len   = j;
    chunk->idx = cidx;
    return 1;
}
예제 #10
0
파일: set4.c 프로젝트: avanpo/cryptopals
int server_32(unsigned char *file, int flen, unsigned char *signature)
{
	unsigned char hmac[20];
	sha1_hmac(get_static_key(), 16, file, flen, hmac);

	if (insecure_compare_32(signature, hmac, 20) == 0) {
		return 200;
	}
	return 500;
}
예제 #11
0
void calculate_ciphertext_hmac(const unsigned char *ciphertext,
                               const unsigned char *hmac_key,
                               unsigned char *hmac)
{
#ifdef USE_MBEDTLS
  mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), hmac_key, 40, ciphertext, 128, hmac);
#else
  sha1_hmac(hmac_key, 40, ciphertext, 128, hmac);
#endif
}
예제 #12
0
파일: tpm-v1.c 프로젝트: Noltari/u-boot
/**
 * Verify an authentication block in a response.
 * Since this func updates the nonce_even in the session data it has to be
 * called when receiving a succesfull AUTH response.
 * This func can verify the first as well as the second auth block (for
 * double authorized commands).
 *
 * @param command_code	command code of the request
 * @param response	pointer to the request (w/ uninitialised auth data)
 * @param handles_len	length of the handles area in response
 * @param auth_session	pointer to the (valid) auth session to be used
 * @param response_auth	pointer to the auth block of the response to be verified
 * @param auth		authentication data (HMAC key)
 */
static u32 verify_response_auth(u32 command_code, const void *response,
				size_t response_len0, size_t handles_len,
				struct session_data *auth_session,
				const void *response_auth, const void *auth)
{
	u8 hmac_data[DIGEST_LENGTH * 3 + 1];
	u8 computed_auth[DIGEST_LENGTH];
	sha1_context hash_ctx;
	const size_t return_code_offset = 6;
	const size_t auth_continue_offset = 20;
	const size_t auth_auth_offset = 21;
	u8 auth_continue;

	if (!auth_session || !auth_session->valid)
		return TPM_AUTHFAIL;
	if (pack_byte_string(hmac_data, sizeof(hmac_data), "d",
			     0, command_code))
		return TPM_LIB_ERROR;
	if (response_len0 < TPM_RESPONSE_HEADER_LENGTH)
		return TPM_LIB_ERROR;

	sha1_starts(&hash_ctx);
	sha1_update(&hash_ctx, response + return_code_offset, 4);
	sha1_update(&hash_ctx, hmac_data, 4);
	if (response_len0 > TPM_RESPONSE_HEADER_LENGTH + handles_len)
		sha1_update(&hash_ctx,
			    response + TPM_RESPONSE_HEADER_LENGTH + handles_len,
			    response_len0 - TPM_RESPONSE_HEADER_LENGTH
			    - handles_len);
	sha1_finish(&hash_ctx, hmac_data);

	memcpy(auth_session->nonce_even, response_auth, DIGEST_LENGTH);
	auth_continue = ((u8 *)response_auth)[auth_continue_offset];
	if (pack_byte_string(hmac_data, sizeof(hmac_data), "ssb",
			     DIGEST_LENGTH,
			     response_auth,
			     DIGEST_LENGTH,
			     2 * DIGEST_LENGTH,
			     auth_session->nonce_odd,
			     DIGEST_LENGTH,
			     3 * DIGEST_LENGTH,
			     auth_continue))
		return TPM_LIB_ERROR;

	sha1_hmac(auth, DIGEST_LENGTH, hmac_data, sizeof(hmac_data),
		  computed_auth);

	if (memcmp(computed_auth, response_auth + auth_auth_offset,
		   DIGEST_LENGTH))
		return TPM_AUTHFAIL;

	return TPM_SUCCESS;
}
예제 #13
0
파일: hmac.c 프로젝트: mikiya1991/dnp3
SEC_RESULT auth_sha1(uchar* in,const size_t inlen,uchar* key,size_t keylen,uchar* hash,size_t hashlen){
	uchar* datahash = (uchar*)malloc(SHA1_SIZE);
	if(!datahash) return SEC_ERROR;
	int ret = sha1_hmac(in,inlen,key,keylen,datahash);
	if(ret){
		free(datahash);
		return SEC_ERROR;
	}
	int ret_cmp = memcmp(datahash,hash,hashlen);
	free(datahash);
	if(ret_cmp) return SEC_ERROR;
	return SEC_SUCCESS;
	
}
예제 #14
0
파일: tpm-v1.c 프로젝트: Noltari/u-boot
/**
 * Fill an authentication block in a request.
 * This func can create the first as well as the second auth block (for
 * double authorized commands).
 *
 * @param request	pointer to the request (w/ uninitialised auth data)
 * @param request_len0	length of the request without auth data
 * @param handles_len	length of the handles area in request
 * @param auth_session	pointer to the (valid) auth session to be used
 * @param request_auth	pointer to the auth block of the request to be filled
 * @param auth		authentication data (HMAC key)
 */
static u32 create_request_auth(const void *request, size_t request_len0,
			       size_t handles_len,
			       struct session_data *auth_session,
			       void *request_auth, const void *auth)
{
	u8 hmac_data[DIGEST_LENGTH * 3 + 1];
	sha1_context hash_ctx;
	const size_t command_code_offset = 6;
	const size_t auth_nonce_odd_offset = 4;
	const size_t auth_continue_offset = 24;
	const size_t auth_auth_offset = 25;

	if (!auth_session || !auth_session->valid)
		return TPM_LIB_ERROR;

	sha1_starts(&hash_ctx);
	sha1_update(&hash_ctx, request + command_code_offset, 4);
	if (request_len0 > TPM_REQUEST_HEADER_LENGTH + handles_len)
		sha1_update(&hash_ctx,
			    request + TPM_REQUEST_HEADER_LENGTH + handles_len,
			    request_len0 - TPM_REQUEST_HEADER_LENGTH
			    - handles_len);
	sha1_finish(&hash_ctx, hmac_data);

	sha1_starts(&hash_ctx);
	sha1_update(&hash_ctx, auth_session->nonce_odd, DIGEST_LENGTH);
	sha1_update(&hash_ctx, hmac_data, sizeof(hmac_data));
	sha1_finish(&hash_ctx, auth_session->nonce_odd);

	if (pack_byte_string(request_auth, TPM_REQUEST_AUTH_LENGTH, "dsb",
			     0, auth_session->handle,
			     auth_nonce_odd_offset, auth_session->nonce_odd,
			     DIGEST_LENGTH,
			     auth_continue_offset, 1))
		return TPM_LIB_ERROR;
	if (pack_byte_string(hmac_data, sizeof(hmac_data), "ss",
			     DIGEST_LENGTH,
			     auth_session->nonce_even,
			     DIGEST_LENGTH,
			     2 * DIGEST_LENGTH,
			     request_auth + auth_nonce_odd_offset,
			     DIGEST_LENGTH + 1))
		return TPM_LIB_ERROR;
	sha1_hmac(auth, DIGEST_LENGTH, hmac_data, sizeof(hmac_data),
		  request_auth + auth_auth_offset);

	return TPM_SUCCESS;
}
예제 #15
0
파일: makeself.c 프로젝트: manusan/ps3tools
static void calculate_hashes(void)
{
	u32 i;
	u8 *keys;

	keys = self + meta_offset + 0x80 + (0x30 * ehdr.e_phnum);

	for (i = 0; i < ehdr.e_phnum; i++) {
		memset(keys + (i * 8 * 0x10), 0, 0x20);
		sha1_hmac(keys + ((i * 8) + 2) * 0x10,
		          elf + phdr[i].p_off,
			  phdr[i].p_filesz,
			  keys + (i * 8) * 0x10
			 );
	}	
}
예제 #16
0
int ss_sha1_hmac_with_key(char *auth, char *msg, int msg_len, uint8_t *auth_key, int key_len)
{
    uint8_t hash[ONETIMEAUTH_BYTES * 2];

#if defined(USE_CRYPTO_OPENSSL)
    HMAC(EVP_sha1(), auth_key, key_len, (uint8_t *)msg, msg_len, (uint8_t *)hash, NULL);
#elif defined(USE_CRYPTO_MBEDTLS)
    mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), auth_key, key_len, (uint8_t *)msg, msg_len, (uint8_t *)hash);
#else
    sha1_hmac(auth_key, key_len, (uint8_t *)msg, msg_len, (uint8_t *)hash);
#endif

    memcpy(auth, hash, ONETIMEAUTH_BYTES);

    return 0;
}
/**
 * @brief HMAC-SHA1 wrapper
 * @param[in] 	key			HMAC secret key
 * @param[in] 	keyLength	HMAC key length
 * @param[in]	input 		Input data buffer
 * @param[in]   inputLength	Input data length
 * @param[in]	hmacLength	Length of output required in bytes, HMAC output is truncated to the hmacLength left bytes. 20 bytes maximum
 * @param[out]	output		Output data buffer
 *
 */
void bctbx_hmacSha1(const uint8_t *key,
		size_t keyLength,
		const uint8_t *input,
		size_t inputLength,
		uint8_t hmacLength,
		uint8_t *output)
{
	uint8_t hmacOutput[20];
	sha1_hmac(key, keyLength, input, inputLength, hmacOutput);

	/* check output length, can't be>20 */
	if (hmacLength>20) {
		memcpy(output, hmacOutput, 20);
	} else {
		memcpy(output, hmacOutput, hmacLength);
	}
}
예제 #18
0
파일: xyssl.cpp 프로젝트: Redi0/jucpp
	uint ShaHmac::GetDigest(void* digest,const void* data,uint len,const void* key,uint klen,SHA_BITS bits){
		if(bits==sha_160){
			sha1_hmac((byte*)key,klen,(byte*)data,len,(byte*)digest);
		}else if(bits==sha_224){
			sha2_hmac((byte*)key,klen,(byte*)data,len,(byte*)digest,1);
		}else if(bits==sha_256){
			sha2_hmac((byte*)key,klen,(byte*)data,len,(byte*)digest,0);
		}else if(bits==sha_384){
			sha4_hmac((byte*)key,klen,(byte*)data,len,(byte*)digest,1);
		}else if(bits==sha_512){
			sha4_hmac((byte*)key,klen,(byte*)data,len,(byte*)digest,0);
		}else{
			_ASSERT(0);
			return 0;
		}
		return bits;
	}
예제 #19
0
// func for calculating section hashes
int calculate_spp_hash(u8 *data, u64 len, u8 *digest)
{
	int retval = -1;

	// validate input params
	if ( (data == NULL) || (digest == NULL) )
		goto exit;

	// calculate the hdr HMAC hash
	memset(digest, 0, 0x20);
	sha1_hmac(digest + 0x20, SPP_HMAC_KEY_SIZE, data, (size_t)len, digest);

	// status success
	retval = STATUS_SUCCESS;

exit:
	return retval;
}
예제 #20
0
int ss_onetimeauth_verify(buffer_t *buf, uint8_t *iv)
{
    uint8_t hash[ONETIMEAUTH_BYTES * 2];
    uint8_t auth_key[MAX_IV_LENGTH + MAX_KEY_LENGTH];
    memcpy(auth_key, iv, enc_iv_len);
    memcpy(auth_key + enc_iv_len, enc_key, enc_key_len);
    size_t len = buf->len - ONETIMEAUTH_BYTES;

#if defined(USE_CRYPTO_OPENSSL)
    HMAC(EVP_sha1(), auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->array, len, hash, NULL);
#elif defined(USE_CRYPTO_MBEDTLS)
    mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->array, len, hash);
#else
    sha1_hmac(auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->array, len, hash);
#endif

    return safe_memcmp(buf->array + len, hash, ONETIMEAUTH_BYTES);
}
예제 #21
0
int ss_sha1_hmac(char *auth, char *msg, int msg_len, uint8_t *iv)
{
    uint8_t hash[ONETIMEAUTH_BYTES * 2];
    uint8_t auth_key[MAX_IV_LENGTH + MAX_KEY_LENGTH];
    memcpy(auth_key, iv, enc_iv_len);
    memcpy(auth_key + enc_iv_len, enc_key, enc_key_len);

#if defined(USE_CRYPTO_OPENSSL)
    HMAC(EVP_sha1(), auth_key, enc_iv_len + enc_key_len, (uint8_t *)msg, msg_len, (uint8_t *)hash, NULL);
#elif defined(USE_CRYPTO_MBEDTLS)
    mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), auth_key, enc_iv_len + enc_key_len, (uint8_t *)msg, msg_len, (uint8_t *)hash);
#else
    sha1_hmac(auth_key, enc_iv_len + enc_key_len, (uint8_t *)msg, msg_len, (uint8_t *)hash);
#endif

    memcpy(auth, hash, ONETIMEAUTH_BYTES);

    return 0;
}
예제 #22
0
static int
dissect_corosynec_totemnet_with_decryption(tvbuff_t *tvb,
                                           packet_info *pinfo, proto_tree *parent_tree,
                                           gboolean check_crypt_type,
                                           const gchar* key_for_trial)
{
  unsigned char  keys[48];
  sober128_prng     keygen_prng_state;
  sober128_prng     stream_prng_state;
  unsigned char *hmac_key       = &keys[32];
  unsigned char *cipher_key     = &keys[16];
  unsigned char *initial_vector = &keys[0];
  unsigned char  digest_comparison[SHA1_DIGEST_LEN];

  int            io_len;
  guint8        *io_base;

#define PRIVATE_KEY_LEN_MAX 256
  gchar          private_key[PRIVATE_KEY_LEN_MAX];
  gsize          private_key_len;
  unsigned char* hash_digest;
  unsigned char* salt;

  io_len = tvb_reported_length(tvb) - (check_crypt_type? 1: 0);
  if (io_len < SHA1_DIGEST_LEN + SALT_SIZE) {
    return 0;
  }

  io_base = (guint8 *)tvb_memdup(pinfo->pool, tvb, 0, io_len + (check_crypt_type? 1: 0));
  if (check_crypt_type &&
      ( io_base[io_len] != TOTEM_CRYPTO_SOBER )) {
    return 0;
  }

  hash_digest = io_base;
  salt        = io_base + SHA1_DIGEST_LEN;


  memset(private_key, 0, sizeof(private_key));

  private_key_len = (strlen(key_for_trial)+4) & 0xFC;
  if (private_key_len > PRIVATE_KEY_LEN_MAX)
    private_key_len = PRIVATE_KEY_LEN_MAX;
  g_strlcpy(private_key, key_for_trial, private_key_len);

  /*
   * Generate MAC, CIPHER, IV keys from private key
   */
  memset (keys, 0, sizeof(keys));
  sober128_start (&keygen_prng_state);
  sober128_add_entropy(private_key,
                                  (unsigned long)private_key_len, &keygen_prng_state);
  sober128_add_entropy (salt, SALT_SIZE, &keygen_prng_state);
  sober128_read (keys, sizeof (keys), &keygen_prng_state);

  /*
   * Setup stream cipher
   */
  sober128_start (&stream_prng_state);
  sober128_add_entropy (cipher_key, 16, &stream_prng_state);
  sober128_add_entropy (initial_vector, 16, &stream_prng_state);

  /*
   * Authenticate contents of message
   */
  sha1_hmac(hmac_key, 16,
            io_base + SHA1_DIGEST_LEN, io_len - SHA1_DIGEST_LEN,
            digest_comparison);

  if (memcmp (digest_comparison, hash_digest, SHA1_DIGEST_LEN) != 0)
      return 0;

  /*
   * Decrypt the contents of the message with the cipher key
   */

  sober128_read (io_base + SHA1_DIGEST_LEN + SALT_SIZE,
                            io_len - (SHA1_DIGEST_LEN + SALT_SIZE),
                            &stream_prng_state);


  /*
   * Dissect the decrypted data
   */
  {
    tvbuff_t *decrypted_tvb;
    tvbuff_t *next_tvb;


    decrypted_tvb = tvb_new_real_data(io_base, io_len, io_len);

    tvb_set_child_real_data_tvbuff(tvb, decrypted_tvb);
    add_new_data_source(pinfo, decrypted_tvb, "Decrypted Data");


    dissect_corosync_totemnet_security_header(decrypted_tvb, pinfo, parent_tree,
                                              check_crypt_type, key_for_trial);

    next_tvb = tvb_new_subset(decrypted_tvb,
                              SHA1_DIGEST_LEN + SALT_SIZE,
                              io_len - (SHA1_DIGEST_LEN + SALT_SIZE),
                              io_len - (SHA1_DIGEST_LEN + SALT_SIZE));

    return call_dissector(corosync_totemsrp_handle, next_tvb, pinfo, parent_tree) + SHA1_DIGEST_LEN + SALT_SIZE;
  }
}
예제 #23
0
static int ssl_decrypt_buf(ssl_context * ssl)
{
	size_t i, padlen;
	uint8_t tmp[20];

	SSL_DEBUG_MSG(2, ("=> decrypt buf"));

	if (ssl->in_msglen < ssl->minlen) {
		SSL_DEBUG_MSG(1, ("in_msglen (%d) < minlen (%d)",
				  ssl->in_msglen, ssl->minlen));
		return (TROPICSSL_ERR_SSL_INVALID_MAC);
	}

	if (ssl->ivlen == 0) {
#if defined(TROPICSSL_ARC4)
		padlen = 0;
		arc4_crypt((arc4_context *) ssl->ctx_dec,
			   ssl->in_msg, ssl->in_msglen);
#else
		return (TROPICSSL_ERR_SSL_FEATURE_UNAVAILABLE);
#endif
	} else {
		/*
		 * Decrypt and check the padding
		 */
		if (ssl->in_msglen % ssl->ivlen != 0) {
			SSL_DEBUG_MSG(1, ("msglen (%d) %% ivlen (%d) != 0",
					  ssl->in_msglen, ssl->ivlen));
			return (TROPICSSL_ERR_SSL_INVALID_MAC);
		}

		switch (ssl->ivlen) {
#if defined(TROPICSSL_DES)
		case 8:
			des3_crypt_cbc((des3_context *) ssl->ctx_dec,
				       DES_DECRYPT, ssl->in_msglen,
				       ssl->iv_dec, ssl->in_msg, ssl->in_msg);
			break;
#endif

		case 16:
#if defined(TROPICSSL_AES)
			if (ssl->session->cipher == TLS_RSA_WITH_AES_128_CBC_SHA ||
			    ssl->session->cipher == TLS_RSA_WITH_AES_256_CBC_SHA ||
			    ssl->session->cipher == TLS_DHE_RSA_WITH_AES_256_CBC_SHA) {
				aes_crypt_cbc((aes_context *) ssl->ctx_dec,
					      AES_DECRYPT, ssl->in_msglen,
					      ssl->iv_dec, ssl->in_msg,
					      ssl->in_msg);
				break;
			}
#endif

#if defined(TROPICSSL_CAMELLIA)
			if (ssl->session->cipher == TLS_RSA_WITH_CAMELLIA_128_CBC_SHA ||
			    ssl->session->cipher == TLS_RSA_WITH_CAMELLIA_256_CBC_SHA ||
			    ssl->session->cipher ==
			    TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA) {
				camellia_crypt_cbc((camellia_context *)
						   ssl->ctx_dec,
						   CAMELLIA_DECRYPT,
						   ssl->in_msglen, ssl->iv_dec,
						   ssl->in_msg, ssl->in_msg);
				break;
			}
#endif

		default:
			return (TROPICSSL_ERR_SSL_FEATURE_UNAVAILABLE);
		}

		padlen = 1 + ssl->in_msg[ssl->in_msglen - 1];

		if (ssl->minor_ver == SSL_MINOR_VERSION_0) {
			if (padlen > ssl->ivlen) {
				SSL_DEBUG_MSG(1, ("bad padding length: is %d, "
						  "should be no more than %d",
						  padlen, ssl->ivlen));
				padlen = 0;
			}
		} else {
			/*
			 * TLSv1: always check the padding
			 */
			for (i = 1; i <= padlen; i++) {
				if (ssl->in_msg[ssl->in_msglen - i] !=
				    padlen - 1) {
					SSL_DEBUG_MSG(1,
						      ("bad padding byte: should be "
						       "%02x, but is %02x",
						       padlen - 1,
						       ssl->
						       in_msg[ssl->in_msglen -
							      i]));
					padlen = 0;
				}
			}
		}
	}

	SSL_DEBUG_BUF(4, "raw buffer after decryption",
		      ssl->in_msg, ssl->in_msglen);

	/*
	 * Always compute the MAC (RFC4346, CBCTIME).
	 */
	ssl->in_msglen -= (ssl->maclen + padlen);

	ssl->in_hdr[3] = (uint8_t)(ssl->in_msglen >> 8);
	ssl->in_hdr[4] = (uint8_t)(ssl->in_msglen);

	memcpy(tmp, ssl->in_msg + ssl->in_msglen, 20);

	if (ssl->minor_ver == SSL_MINOR_VERSION_0) {
		if (ssl->maclen == 16)
			ssl_mac_md5(ssl->mac_dec,
				    ssl->in_msg, ssl->in_msglen,
				    ssl->in_ctr, ssl->in_msgtype);
		else
			ssl_mac_sha1(ssl->mac_dec,
				     ssl->in_msg, ssl->in_msglen,
				     ssl->in_ctr, ssl->in_msgtype);
	} else {
		if (ssl->maclen == 16)
			md5_hmac(ssl->mac_dec, 16,
				 ssl->in_ctr, ssl->in_msglen + 13,
				 ssl->in_msg + ssl->in_msglen);
		else
			sha1_hmac(ssl->mac_dec, 20,
				  ssl->in_ctr, ssl->in_msglen + 13,
				  ssl->in_msg + ssl->in_msglen);
	}

	SSL_DEBUG_BUF(4, "message  mac", tmp, ssl->maclen);
	SSL_DEBUG_BUF(4, "computed mac", ssl->in_msg + ssl->in_msglen,
		      ssl->maclen);

	if (memcmp(tmp, ssl->in_msg + ssl->in_msglen, ssl->maclen) != 0) {
		SSL_DEBUG_MSG(1, ("message mac does not match"));
		return (TROPICSSL_ERR_SSL_INVALID_MAC);
	}

	/*
	 * Finally check the padding length; bad padding
	 * will produce the same error as an invalid MAC.
	 */
	if (ssl->ivlen != 0 && padlen == 0)
		return (TROPICSSL_ERR_SSL_INVALID_MAC);

	if (ssl->in_msglen == 0) {
		ssl->nb_zero++;

		/*
		 * Three or more empty messages may be a DoS attack
		 * (excessive CPU consumption).
		 */
		if (ssl->nb_zero > 3) {
			SSL_DEBUG_MSG(1, ("received four consecutive empty "
					  "messages, possible DoS attack"));
			return (TROPICSSL_ERR_SSL_INVALID_MAC);
		}
	} else
		ssl->nb_zero = 0;

	for (i = 7; i >= 0; i--)
		if (++ssl->in_ctr[i] != 0)
			break;

	SSL_DEBUG_MSG(2, ("<= decrypt buf"));

	return (0);
}
예제 #24
0
/*
 * Encryption/decryption functions
 */
static int ssl_encrypt_buf(ssl_context * ssl)
{
	size_t i, padlen;

	SSL_DEBUG_MSG(2, ("=> encrypt buf"));

	/*
	 * Add MAC then encrypt
	 */
	if (ssl->minor_ver == SSL_MINOR_VERSION_0) {
		if (ssl->maclen == 16)
			ssl_mac_md5(ssl->mac_enc,
				    ssl->out_msg, ssl->out_msglen,
				    ssl->out_ctr, ssl->out_msgtype);

		if (ssl->maclen == 20)
			ssl_mac_sha1(ssl->mac_enc,
				     ssl->out_msg, ssl->out_msglen,
				     ssl->out_ctr, ssl->out_msgtype);
	} else {
		if (ssl->maclen == 16)
			md5_hmac(ssl->mac_enc, 16,
				 ssl->out_ctr, ssl->out_msglen + 13,
				 ssl->out_msg + ssl->out_msglen);

		if (ssl->maclen == 20)
			sha1_hmac(ssl->mac_enc, 20,
				  ssl->out_ctr, ssl->out_msglen + 13,
				  ssl->out_msg + ssl->out_msglen);
	}

	SSL_DEBUG_BUF(4, "computed mac",
		      ssl->out_msg + ssl->out_msglen, ssl->maclen);

	ssl->out_msglen += ssl->maclen;

	for (i = 7; i >= 0; i--)
		if (++ssl->out_ctr[i] != 0)
			break;

	if (ssl->ivlen == 0) {
#if defined(TROPICSSL_ARC4)
		padlen = 0;

		SSL_DEBUG_MSG(3, ("before encrypt: msglen = %d, "
				  "including %d bytes of padding",
				  ssl->out_msglen, 0));

		SSL_DEBUG_BUF(4, "before encrypt: output payload",
			      ssl->out_msg, ssl->out_msglen);

		arc4_crypt((arc4_context *) ssl->ctx_enc,
			   ssl->out_msg, ssl->out_msglen);
#else
		return (TROPICSSL_ERR_SSL_FEATURE_UNAVAILABLE);
#endif
	} else {
		padlen = ssl->ivlen - (ssl->out_msglen + 1) % ssl->ivlen;
		if (padlen == ssl->ivlen)
			padlen = 0;

		for (i = 0; i <= padlen; i++)
			ssl->out_msg[ssl->out_msglen + i] =
			    (uint8_t)padlen;

		ssl->out_msglen += padlen + 1;

		SSL_DEBUG_MSG(3, ("before encrypt: msglen = %d, "
				  "including %d bytes of padding",
				  ssl->out_msglen, padlen + 1));

		SSL_DEBUG_BUF(4, "before encrypt: output payload",
			      ssl->out_msg, ssl->out_msglen);

		switch (ssl->ivlen) {
		case 8:
#if defined(TROPICSSL_DES)
			des3_crypt_cbc((des3_context *) ssl->ctx_enc,
				       DES_ENCRYPT, ssl->out_msglen,
				       ssl->iv_enc, ssl->out_msg, ssl->out_msg);
			break;
#endif

		case 16:
#if defined(TROPICSSL_AES)
			if (ssl->session->cipher == TLS_RSA_WITH_AES_128_CBC_SHA ||
			    ssl->session->cipher == TLS_RSA_WITH_AES_256_CBC_SHA ||
			    ssl->session->cipher == TLS_DHE_RSA_WITH_AES_256_CBC_SHA) {
				aes_crypt_cbc((aes_context *) ssl->ctx_enc,
					      AES_ENCRYPT, ssl->out_msglen,
					      ssl->iv_enc, ssl->out_msg,
					      ssl->out_msg);
				break;
			}
#endif

#if defined(TROPICSSL_CAMELLIA)
			if (ssl->session->cipher == TLS_RSA_WITH_CAMELLIA_128_CBC_SHA ||
			    ssl->session->cipher == TLS_RSA_WITH_CAMELLIA_256_CBC_SHA ||
			    ssl->session->cipher ==
			    TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA) {
				camellia_crypt_cbc((camellia_context *)
						   ssl->ctx_enc,
						   CAMELLIA_ENCRYPT,
						   ssl->out_msglen, ssl->iv_enc,
						   ssl->out_msg, ssl->out_msg);
				break;
			}
#endif

		default:
			return (TROPICSSL_ERR_SSL_FEATURE_UNAVAILABLE);
		}
	}

	SSL_DEBUG_MSG(2, ("<= encrypt buf"));

	return (0);
}
예제 #25
0
파일: makepkg.c 프로젝트: Arikado/SCEkrit
static void calculate_hash(u8 *data, u64 len, u8 *digest)
{
	memset(digest, 0, 0x20);
	sha1_hmac(digest + 0x20, data, len, digest);
}
예제 #26
0
파일: login.c 프로젝트: Kitof/openspotify
/*
 * Initialize common crypto keys used for communication
 *
 * This step takes place after the initial two packets
 * have been exchanged.
 *
 */
static void key_init(struct login_ctx *l) {
	BIGNUM *pub_key;
	unsigned char message[53];
	unsigned char hmac_output[20 * 5];
	unsigned char *ptr, *hmac_ptr;
	unsigned int mac_len;
	int i;


	/*
	 * Compute DH shared key
	 * It's used in the call to HMAC() below
	 *
	 */
	pub_key = BN_bin2bn(l->remote_pub_key, 96, NULL);
	if((i = DH_compute_key(l->shared_key, pub_key, l->dh)) < 0) {
		/* XXX */
		return;
	}

#ifdef DEBUG_LOGIN
	hexdump8x32 ("key_init, my private key", l->my_priv_key, 96);
	hexdump8x32 ("key_init, my public key", l->client_pub_key, 96);
	hexdump8x32 ("key_init, remote public key", l->remote_pub_key,
		     96);
	hexdump8x32 ("key_init, shared key", l->shared_key, 96);
#endif
        BN_free(pub_key);



	/*
	 * Prepare a message to authenticate.
	 *
	 * Prior to the 19th of December 2008 Spotify happily told clients 
	 * (including ours!) almost everything it knew about a particular
	 * user, if they asked for it.
	 *
	 * Legitimate requests for this is for example when you add
	 * someone else's shared playlist.
	 *
	 * This allowed clients to see not only the last four digits of the 
	 * credit card used to subscribe to the premium service, whether
	 * the user was a paying customer or preferred commercials, but 
	 * also very interesting stuff such as the hash computed from
	 * SHA(salt || " " || password).
	 *
	 * In theory (HE HE!) this allowed any registered user to request
	 * somebody else's user data, get ahold of the hash, and then use
	 * it to authenticate as that user.
	 *
	 * Fortunately, at lest for Spotify and it's users, this is not
	 * the case anymore. (R.I.P poor misfeature)
	 *
	 * However, we urge people to change their passwords for reasons
	 * left as an exercise for the reader to figure out.
	 *
	 */
	ptr = message;
	memcpy (ptr, l->auth_hash, sizeof (l->auth_hash));
	ptr += sizeof (l->auth_hash);

	memcpy (ptr, l->client_random_16, 16);
	ptr += 16;

	memcpy (ptr, l->server_random_16, 16);
	ptr += 16;

	/*
	 * Run HMAC over the message, using the DH shared key as key
	 *
	 */
	hmac_ptr = hmac_output;
	mac_len = 20;
	for (i = 1; i <= 5; i++) {
		/*
		 * Change last byte of message to authenticate
		 *
		 */
		*ptr = i;

#ifdef DEBUG_LOGIN
		hexdump8x32 ("key_init, HMAC message", message,
			     sizeof (message));
#endif

	        sha1_hmac(l->shared_key, 96, message,
			  sizeof (message), hmac_ptr);

		/*
		 * Overwrite the 20 first bytes of the message with output from this round
		 *
		 */
		memcpy (message, hmac_ptr, 20);
		hmac_ptr += 20;
	}

	/*
	 * Use computed HMAC to setup keys for the
	 * stream cipher
	 *
	 */
	memcpy (l->key_send, hmac_output + 20, 32);
	memcpy (l->key_recv, hmac_output + 52, 32);


	/*
	 * The first 20 bytes of the HMAC output is used
	 * to key another HMAC computed for the second
	 * authentication packet sent by the client.
	 *
	 */
	memcpy (l->key_hmac, hmac_output, 20);

#ifdef DEBUG_LOGIN
	hexdump8x32 ("key_init, key_hmac", l->key_hmac, 20);
	hexdump8x32 ("key_init, key_send", l->key_send, 32);
	hexdump8x32 ("key_init, key_recv", l->key_recv, 32);
#endif
}
예제 #27
0
void calculate_ciphertext_hmac(const unsigned char *ciphertext,
                               const unsigned char *hmac_key,
                               unsigned char *hmac)
{
  sha1_hmac(hmac_key, 40, ciphertext, 128, hmac);
}
예제 #28
0
int main(int argc, char* argv[]) {
  int i;
  u8 ecount_buf[0x10], iv[0x10];
  size_t countp;
  int num;

  if(argc < 4) {
    printf("usage: %s input.elf output.self keytype keysuffix\n", argv[0]);
    return -1;
  }

  Elf64_Ehdr input_elf_header;
  FILE *input_elf_file = fopen(argv[1], "rb");

  fseek(input_elf_file, 0, SEEK_END);
  int nlen = ftell(input_elf_file);
  fseek(input_elf_file, 0, SEEK_SET);
  input_elf_data = (u8*)malloc(nlen);
  fread(input_elf_data, 1, nlen, input_elf_file);
  fclose(input_elf_file);

  memcpy(&input_elf_header, input_elf_data, sizeof(input_elf_header));


  FILE *output_self_file = fopen(argv[2], "wb");


  printf("ELF header size @ %x\n", get_u16(&(input_elf_header.e_ehsize)) );
  printf("%d program headers @ %64llX\n", get_u16(&(input_elf_header.e_phnum)), get_u64(&(input_elf_header.e_phoff)));
  printf("%d section headers @ %64llX\n", get_u16(&(input_elf_header.e_shnum)), get_u64(&(input_elf_header.e_shoff)));

  Self_Shdr output_self_header; memset(&output_self_header, 0, sizeof(output_self_header));
  Self_Ehdr output_extended_self_header; memset(&output_extended_self_header, 0, sizeof(output_extended_self_header));
  Self_Ihdr output_self_info_header; memset(&output_self_info_header, 0, sizeof(output_self_info_header));

  set_u32(&(output_self_header.s_magic), 0x53434500);
  set_u32(&(output_self_header.s_hdrversion), 2);
  set_u16(&(output_self_header.s_flags), 1);
  set_u16(&(output_self_header.s_hdrtype), 1);
  // header size and file size aren't known yet

  set_u64(&(output_extended_self_header.e_magic), 3);
  set_u64(&(output_extended_self_header.e_ihoff), sizeof(Self_Shdr)+sizeof(Self_Ehdr));
  set_u64(&(output_extended_self_header.e_ehoff), sizeof(Self_Shdr)+sizeof(Self_Ehdr)+sizeof(Self_Ihdr));
  set_u64(&(output_extended_self_header.e_phoff), sizeof(Self_Shdr)+sizeof(Self_Ehdr)+sizeof(Self_Ihdr)+get_u64(&(input_elf_header.e_phoff)));
  // section header offset unknown

  set_u64(&(output_self_info_header.i_authid), 0x1070000500000001LL);
  set_u32(&(output_self_info_header.i_magic), 0x01000002);
  set_u32(&(output_self_info_header.i_apptype), 4);
  set_u64(&(output_self_info_header.i_version), 0x0003000000000000LL);

// set static data
  int phnum = get_u16(&(input_elf_header.e_phnum));
  u32 phsize = (sizeof(Elf64_Phdr)*get_u16(&(input_elf_header.e_phnum))); 

  Self_SDKversion sdkversion;
  Self_Cflags cflags;
  memcpy(&sdkversion, sdkversion_static, sizeof(Self_SDKversion));
  memcpy(&cflags, cflags_static, sizeof(Self_Cflags));

  int running_size = (sizeof(output_self_header)+sizeof(output_extended_self_header)+sizeof(output_self_info_header)+sizeof(input_elf_header)+phsize+0xF)&0xFFFFFFF0;

  set_u64(&(output_extended_self_header.e_pmoff), running_size); running_size += phnum*sizeof(Self_PMhdr);
  set_u64(&(output_extended_self_header.e_svoff), running_size); running_size += sizeof(Self_SDKversion);
  set_u64(&(output_extended_self_header.e_cfoff), running_size); running_size += sizeof(Self_Cflags);
  set_u64(&(output_extended_self_header.e_cfsize), sizeof(Self_Cflags));
  set_u32(&(output_self_header.s_esize), running_size - sizeof(output_self_header));

  printf("running size is %X\n", running_size);

  int maxsection = 6;

  running_size += sizeof(metadata_crypt_header)+sizeof(segment_certification_header)+maxsection*(sizeof(segment_certification_segment)+sizeof(segment_certification_crypt_encrypted))+sizeof(segment_certification_sign)+sizeof(nubpadding_static);

  printf("running size is %X\n", running_size);

  set_u64(&(output_self_header.s_shsize), running_size);

// init randomness
  gmp_randstate_t r_state;
  gmp_randinit_default(r_state);
  gmp_randseed_ui(r_state, time(NULL));

// loop through the sections

  segment_certification_header segment_header; memset(&segment_header, 0, sizeof(segment_header));
  Self_Section first_section;
  Self_Section* section_ptr = &first_section;

  set_u64(&(segment_header.signature_offset), running_size-sizeof(segment_certification_sign));
  set_u32(&(segment_header.unknown1), 1);
  set_u32(&(segment_header.segment_count), phnum);
  set_u32(&(segment_header.crypt_len), (phnum*sizeof(segment_certification_crypt_encrypted))/0x10);

  Elf64_Phdr* elf_segment = (Elf64_Phdr*)(&input_elf_data[get_u64(&(input_elf_header.e_phoff))]);

  for(i=0;i<phnum;i++) {
    memset(section_ptr, 0, sizeof(Self_Section));

    //set_u64(&(section_ptr->enc_segment.segment_offset), get_u64(&(elf_segment->p_vaddr)));
    set_u64(&(section_ptr->enc_segment.segment_offset), running_size);
    set_u64(&(section_ptr->enc_segment.segment_size), get_u64(&(elf_segment->p_filesz)));
    set_u32(&(section_ptr->enc_segment.segment_crypt_flag), 2);

    set_u32(&(section_ptr->enc_segment.segment_sha1_index), i*8);
    set_u32(&(section_ptr->enc_segment.segment_erk_index), i*8+6);
    set_u32(&(section_ptr->enc_segment.segment_riv_index), i*8+7);

    set_u32(&(section_ptr->enc_segment.segment_number), i);
    set_u32(&(section_ptr->enc_segment.unknown2), 2);
    set_u32(&(section_ptr->enc_segment.unknown3), 3);
    set_u32(&(section_ptr->enc_segment.unknown4), 2);

    set_u64(&(section_ptr->pmhdr.pm_offset), running_size);
    set_u64(&(section_ptr->pmhdr.pm_size), get_u64(&(elf_segment->p_filesz)));
    set_u32(&(section_ptr->pmhdr.pm_compressed), 1);
    set_u32(&(section_ptr->pmhdr.pm_encrypted), 1);

    mpz_t riv, erk, hmac;
    mpz_init(riv); mpz_init(erk); mpz_init(hmac);
    mpz_urandomb(erk, r_state, 128);
    mpz_urandomb(riv, r_state, 128);
    mpz_urandomb(hmac, r_state, 512);

    mpz_export(section_ptr->crypt_segment.erk, &countp, 1, 0x10, 1, 0, erk);
    mpz_export(section_ptr->crypt_segment.riv, &countp, 1, 0x10, 1, 0, riv);
    mpz_export(section_ptr->crypt_segment.hmac, &countp, 1, 0x40, 1, 0, hmac);

    section_ptr->rlen = get_u64(&(elf_segment->p_filesz));
    section_ptr->len = ((section_ptr->rlen)+0xF)&0xFFFFFFF0;
    section_ptr->data = (u8*)malloc(section_ptr->len);

    u32 in_data_offset = get_u64(&(elf_segment->p_offset)); // + get_u16(&(input_elf_header.e_ehsize)) + (sizeof(Elf64_Phdr)*get_u16(&(input_elf_header.e_phnum)));
    u8* in_data = &input_elf_data[in_data_offset];

    printf("processing segment %d with len %x offset %x\n", i, section_ptr->len, in_data_offset);
    //hexdump((u8*)elf_segment, sizeof(Elf64_Phdr));


    /*SHA_CTX c;
    SHA1_ghetto_init(&c, section_ptr->crypt_segment.hmac);
    SHA1_Update(&c, in_data, section_ptr->rlen);
    SHA1_ghetto_final(section_ptr->crypt_segment.sha1, &c, section_ptr->crypt_segment.hmac);*/
    sha1_hmac(section_ptr->crypt_segment.hmac, in_data, section_ptr->rlen, section_ptr->crypt_segment.sha1);

    memset(ecount_buf, 0, 16); num=0;
    AES_set_encrypt_key(section_ptr->crypt_segment.erk, 128, &aes_key);
    memcpy(iv, section_ptr->crypt_segment.riv, 16);

    #ifdef NO_CRYPT
      memcpy(section_ptr->data, in_data, section_ptr->len);   
    #else
      //AES_ctr128_encrypt(in_data, section_ptr->data, section_ptr->len, &aes_key, iv, ecount_buf, &num);
      aes128ctr((u8*)&aes_key, iv, in_data, section_ptr->len, section_ptr->data);
    #endif

    running_size += section_ptr->len;

// next
    if(i != phnum-1) {
      section_ptr->next_section = malloc(sizeof(Self_Section));
    }
    elf_segment += 1;  // 1 is sizeof(Elf64_Phdr)
    section_ptr = section_ptr->next_section;
  }

  printf("segment processing done\n");


// section table offset
  set_u64(&(output_extended_self_header.e_shoff), running_size);

// lay out the metadata
  u8 metadata[0x2000]; memset(metadata, 0, 0x2000);
  u32 metadata_len = 0;

  memcpy(&metadata[metadata_len], &output_self_header, sizeof(output_self_header)); metadata_len += sizeof(output_self_header);
  memcpy(&metadata[metadata_len], &output_extended_self_header, sizeof(output_extended_self_header)); metadata_len += sizeof(output_extended_self_header);
  memcpy(&metadata[metadata_len], &output_self_info_header, sizeof(output_self_info_header)); metadata_len += sizeof(output_self_info_header);
  memcpy(&metadata[metadata_len], &input_elf_header, sizeof(input_elf_header)); metadata_len += sizeof(input_elf_header);
  memcpy(&metadata[metadata_len], &input_elf_data[get_u64(&(input_elf_header.e_phoff))], phsize); metadata_len += phsize;
  metadata_len = (metadata_len+0xF)&0xFFFFFFF0;

  section_ptr = &first_section;
  while(section_ptr != NULL) {
    memcpy(&metadata[metadata_len], &(section_ptr->pmhdr), sizeof(section_ptr->pmhdr)); metadata_len += sizeof(section_ptr->pmhdr);
    section_ptr = section_ptr->next_section;
  }

  memcpy(&metadata[metadata_len], &sdkversion, sizeof(sdkversion)); metadata_len += sizeof(sdkversion);
  memcpy(&metadata[metadata_len], &cflags, sizeof(cflags)); metadata_len += sizeof(cflags);

  printf("top half of metadata ready\n");

// generate metadata encryption keys
  mpz_t bigriv, bigerk;
  mpz_init(bigriv); mpz_init(bigerk);
  mpz_urandomb(bigerk, r_state, 128);
  mpz_urandomb(bigriv, r_state, 128);

  metadata_crypt_header md_header;

  mpz_export(md_header.erk, &countp, 1, 0x10, 1, 0, bigerk);
  mpz_export(md_header.riv, &countp, 1, 0x10, 1, 0, bigriv);

  memcpy(&metadata[metadata_len], &md_header, sizeof(md_header)); metadata_len += sizeof(md_header);
  memcpy(&metadata[metadata_len], &segment_header, sizeof(segment_header)); metadata_len += sizeof(segment_header);

// copy section data
  int csection;

  csection = 0;
  section_ptr = &first_section;
  while(section_ptr != NULL) {
    memcpy(&metadata[metadata_len], &(section_ptr->enc_segment), sizeof(section_ptr->enc_segment)); metadata_len += sizeof(section_ptr->enc_segment);
    section_ptr = section_ptr->next_section;
    if((++csection) == maxsection) break;
  }

  csection = 0;
  section_ptr = &first_section;
  while(section_ptr != NULL) {
    memcpy(&metadata[metadata_len], &(section_ptr->crypt_segment), sizeof(section_ptr->crypt_segment)); metadata_len += sizeof(section_ptr->crypt_segment);
    section_ptr = section_ptr->next_section;
    if((++csection) == maxsection) break;
  }

// nubpadding time
  memcpy(&metadata[metadata_len], nubpadding_static, sizeof(nubpadding_static)); metadata_len += sizeof(nubpadding_static);

// sign shit
  u8 digest[0x14];
  sha1(metadata, metadata_len, digest);
  printf("metadata len is %X\n", metadata_len);
  //hexdump(metadata, metadata_len);
  //hexdump_nl(digest, 0x14);
  segment_certification_sign all_signed;
  memset(&all_signed, 0, sizeof(all_signed));

#ifdef GEOHOT_SIGN
  mpz_t n,k,da,kinv,r,cs,z;
  mpz_init(n); mpz_init(k); mpz_init(da); mpz_init(r); mpz_init(cs); mpz_init(z); mpz_init(kinv);
  mpz_import(r, 0x14, 1, 1, 0, 0, appold_R);
  mpz_import(n, 0x14, 1, 1, 0, 0, appold_n);
  mpz_import(k, 0x14, 1, 1, 0, 0, appold_K);
  mpz_import(da, 0x14, 1, 1, 0, 0, appold_Da);
  mpz_invert(kinv, k, n);

  mpz_import(z, 0x14, 1, 1, 0, 0, digest);

  mpz_mul(cs, r, da); mpz_mod(cs, cs, n);
  mpz_add(cs, cs, z); mpz_mod(cs, cs, n);
  mpz_mul(cs, cs, kinv); mpz_mod(cs, cs, n);

  mpz_export(all_signed.R, &countp, 1, 0x14, 1, 0, r);
  mpz_export(all_signed.S, &countp, 1, 0x14, 1, 0, cs);
#else
  get_keys(argv[3], argv[4]);
  //ecdsa_set_curve(appnew_ctype);
  //ecdsa_set_pub(appnew_pub);
  //ecdsa_set_priv(appnew_priv);
  //ecdsa_sign(digest, all_signed.R, all_signed.S);
#endif

  memcpy(&metadata[metadata_len], &all_signed, sizeof(all_signed)); metadata_len += sizeof(all_signed);

// encrypt metadata
  int metadata_offset = get_u32(&(output_self_header.s_esize)) + sizeof(Self_Shdr);

#ifndef NO_CRYPT
  /*memset(ecount_buf, 0, 16); num=0;
  AES_set_encrypt_key(&metadata[metadata_offset], 128, &aes_key);
  memcpy(iv, &metadata[metadata_offset+0x20], 16);
  //AES_ctr128_encrypt(&metadata[0x40+metadata_offset], &metadata[0x40+metadata_offset], metadata_len-metadata_offset-0x40, &aes_key, iv, ecount_buf, &num);
  aes128ctr(&metadata[0x20+metadata_offset], &metadata[0x40+metadata_offset], &metadata[0x60+metadata_offset], metadata_len-metadata_offset-0x60, &metadata[0x60+metadata_offset]);
  printf("encrypted metadata\n");

  //AES_set_encrypt_key(appold_erk, 256, &aes_key);
  //memcpy(iv, appold_riv, 16);
  AES_set_encrypt_key(appnew_erk, 256, &aes_key);
  memcpy(iv, appnew_riv, 16);
  //AES_cbc_encrypt(&metadata[metadata_offset], &metadata[metadata_offset], 0x40, &aes_key, iv, AES_ENCRYPT);
  aes256cbc_enc(appnew_erk, appnew_riv, &metadata[metadata_offset], 0x40, &metadata[metadata_offset]);

  printf("encrypted keys\n");*/
  //k.key = appnew_erk;
  //k.iv = appnew_riv;
  sce_encrypt_header(metadata, &ks);
#endif

// write the output self
  fwrite(metadata, 1, metadata_len, output_self_file);

  csection = 0;
  section_ptr = &first_section;
  while(section_ptr != 0) {
    printf("writing section with size %X\n", section_ptr->len);
    fwrite(section_ptr->data, 1, section_ptr->len, output_self_file);
    section_ptr = section_ptr->next_section;
    if((++csection) == maxsection) break;
  }

  fwrite(&input_elf_data[get_u64(&(input_elf_header.e_shoff))], sizeof(Elf64_Shdr), get_u16(&(input_elf_header.e_shnum)), output_self_file);

  fclose(output_self_file);
}
예제 #29
0
파일: puppack.c 프로젝트: Arikado/SCEkrit
static void calc_hmac(u8 *ptr, u64 len, u8 *hmac)
{
	memset(hmac, 0, 0x20);
	sha1_hmac(pup_hmac, ptr, len, hmac);
}