/* * 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 ); }
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; }
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); }
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); }
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; }
/* 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); }
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; }
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; }
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; }
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; }
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 }
/** * 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; }
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; }
/** * 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; }
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 ); } }
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); } }
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; }
// 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; }
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); }
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; }
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; } }
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); }
/* * 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); }
static void calculate_hash(u8 *data, u64 len, u8 *digest) { memset(digest, 0, 0x20); sha1_hmac(digest + 0x20, data, len, digest); }
/* * 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 }
void calculate_ciphertext_hmac(const unsigned char *ciphertext, const unsigned char *hmac_key, unsigned char *hmac) { sha1_hmac(hmac_key, 40, ciphertext, 128, hmac); }
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); }
static void calc_hmac(u8 *ptr, u64 len, u8 *hmac) { memset(hmac, 0, 0x20); sha1_hmac(pup_hmac, ptr, len, hmac); }