Beispiel #1
0
static void
insert_message_authenticator(struct rad_handle *h, int resp)
{
#ifdef WITH_SSL
	u_char md[EVP_MAX_MD_SIZE];
	u_int md_len;
	const struct rad_server *srvp;
	HMAC_CTX ctx;
	srvp = &h->servers[h->srv];

	if (h->authentic_pos != 0) {
		HMAC_CTX_init(&ctx);
		HMAC_Init(&ctx, srvp->secret, strlen(srvp->secret), EVP_md5());
		HMAC_Update(&ctx, &h->out[POS_CODE], POS_AUTH - POS_CODE);
		if (resp)
		    HMAC_Update(&ctx, &h->in[POS_AUTH], LEN_AUTH);
		else
		    HMAC_Update(&ctx, &h->out[POS_AUTH], LEN_AUTH);
		HMAC_Update(&ctx, &h->out[POS_ATTRS],
		    h->out_len - POS_ATTRS);
		HMAC_Final(&ctx, md, &md_len);
		HMAC_CTX_cleanup(&ctx);
		HMAC_cleanup(&ctx);
		memcpy(&h->out[h->authentic_pos + 2], md, md_len);
	}
#endif
}
Beispiel #2
0
Hmac_sha1_state::~Hmac_sha1_state ()
{
	// Note: Explicit destructor necessary because class contains an auto_ptr
	// which contains an incomplete type when the auto_ptr is declared.

	HMAC_cleanup(&(impl->ctx));
}
Beispiel #3
0
void openssl_hmac_md5()
{
	int fd, size;
	unsigned int len;
	HMAC_CTX hmac_ctx;
	char file_name[COMM_LEN], inputs[COMM_LEN];
	unsigned char tmps[LINE_LEN], outputs[EVP_MAX_MD_SIZE];

	memset(tmps, 0, sizeof(tmps));
	memset(inputs, 0, sizeof(inputs));
	memset(outputs, 0, sizeof(outputs));
	printf("\nPlease input a file name: ");
	scanf("%s", file_name);
	fd = open(file_name, O_RDONLY);
	if (fd < 0)
		return;

	OpenSSL_add_all_digests();
	strcpy(inputs, "hmac_md5");
	HMAC_Init(&hmac_ctx, inputs, sizeof(inputs), EVP_get_digestbyname("md5"));
	while ((size = read(fd, tmps, LINE_LEN)) > 0)
		HMAC_Update(&hmac_ctx, tmps, size);
	HMAC_Final(&hmac_ctx, outputs, &len);
	HMAC_cleanup(&hmac_ctx);
	close(fd);

	printf("HMAC_MD5(%s, %s) = ", file_name, inputs);
	for (size = 0; size < len; size++)
		printf("%02x", outputs[size]);
	printf("\n");
}
Beispiel #4
0
void
mac_clear(Mac *mac)
{
	if (mac->evp_md != NULL)
		HMAC_cleanup(&mac->evp_ctx);
	mac->evp_md = NULL;
}
static void tls1_P_hash(const EVP_MD *md, const unsigned char *sec,
			int sec_len, unsigned char *seed, int seed_len,
			unsigned char *out, int olen)
	{
	int chunk,n;
	unsigned int j;
	HMAC_CTX ctx;
	HMAC_CTX ctx_tmp;
	unsigned char A1[HMAC_MAX_MD_CBLOCK];
	unsigned int A1_len;
	
	chunk=EVP_MD_size(md);

	HMAC_Init(&ctx,sec,sec_len,md);
	HMAC_Update(&ctx,seed,seed_len);
	HMAC_Final(&ctx,A1,&A1_len);

	n=0;
	for (;;)
		{
		HMAC_Init(&ctx,NULL,0,NULL); /* re-init */
		HMAC_Update(&ctx,A1,A1_len);
		memcpy(&ctx_tmp,&ctx,sizeof(ctx)); /* Copy for A2 */ /* not needed for last one */
		HMAC_Update(&ctx,seed,seed_len);

		if (olen > chunk)
			{
			HMAC_Final(&ctx,out,&j);
			out+=j;
			olen-=j;
			HMAC_Final(&ctx_tmp,A1,&A1_len); /* calc the next A1 value */
			}
		else	/* last one */
			{
			HMAC_Final(&ctx,A1,&A1_len);
			memcpy(out,A1,olen);
			break;
			}
		}
	HMAC_cleanup(&ctx);
	HMAC_cleanup(&ctx_tmp);
	memset(A1,0,sizeof(A1));
	}
Beispiel #6
0
static void hmac_finish(struct tc *tc)
{
	struct hmac_priv *hp = crypto_priv(tc);

	if (!hp)
		return;

	HMAC_cleanup(&hp->hp_ctx);
	free(hp);
}
Beispiel #7
0
bool HMAC_Validate(COSE_MacMessage * pcose, int HSize, int TSize, const byte * pbKey, size_t cbKey, const byte * pbAuthData, size_t cbAuthData, cose_errback * perr)
{
	HMAC_CTX ctx;
	const EVP_MD * pmd = NULL;
	byte * rgbOut = NULL;
	unsigned int cbOut;
	bool f = false;
	unsigned int i;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context * context = &pcose->m_message.m_allocContext;
#endif

	HMAC_CTX_init(&ctx);

	switch (HSize) {
	case 256: pmd = EVP_sha256(); break;
	case 384: pmd = EVP_sha384(); break;
	case 512: pmd = EVP_sha512(); break;
	default: FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER); break;
	}

	rgbOut = COSE_CALLOC(EVP_MAX_MD_SIZE, 1, context);
	CHECK_CONDITION(rgbOut != NULL, COSE_ERR_OUT_OF_MEMORY);

	CHECK_CONDITION(HMAC_Init(&ctx, pbKey, (int) cbKey, pmd), COSE_ERR_CRYPTO_FAIL);
	CHECK_CONDITION(HMAC_Update(&ctx, pbAuthData, cbAuthData), COSE_ERR_CRYPTO_FAIL);
	CHECK_CONDITION(HMAC_Final(&ctx, rgbOut, &cbOut), COSE_ERR_CRYPTO_FAIL);

	cn_cbor * cn = _COSE_arrayget_int(&pcose->m_message, INDEX_MAC_TAG);
	CHECK_CONDITION(cn != NULL, COSE_ERR_CBOR);

	if (cn->length > (int) cbOut) return false;
	for (i = 0; i < (unsigned int) TSize/8; i++) f |= (cn->v.bytes[i] != rgbOut[i]);

	HMAC_cleanup(&ctx);
	return !f;

errorReturn:
	COSE_FREE(rgbOut, context);
	HMAC_cleanup(&ctx);
	return false;
}
Beispiel #8
0
static int
tls_hash(StringInfo* secret, StringInfo* seed, const EVP_MD *md, StringInfo* out)
{
    uint8_t   *ptr;
    unsigned int     left;
    int      tocpy;
    uint8_t   *A;
    uint8_t    _A[48],tmp[48];
    unsigned int     A_l,tmp_l;
    HMAC_CTX ctx;
    ptr  = out->data;
    left = out->data_len;

    ssl_print_string("tls_hash: hash secret", secret);
    ssl_print_string("tls_hash: hash seed", seed);
    A=seed->data;
    A_l=seed->data_len;

    while(left){
        HMAC_CTX_init(&ctx);
        HMAC_Init(&ctx, secret->data, secret->data_len, md);
        HMAC_Update(&ctx,A,A_l);
        HMAC_Final(&ctx,_A,&A_l);
        HMAC_cleanup(&ctx);
        A=_A;

        HMAC_CTX_init(&ctx);
        HMAC_Init(&ctx,secret->data,secret->data_len,md);
        HMAC_Update(&ctx,A,A_l);
        HMAC_Update(&ctx,seed->data,seed->data_len);
        HMAC_Final(&ctx,tmp,&tmp_l);
        HMAC_cleanup(&ctx);

        tocpy=std::min(left,tmp_l);
        memcpy(ptr,tmp,tocpy);
        ptr+=tocpy;
        left-=tocpy;
    }

    ssl_print_string("hash out", out);
    return (0);
}
Beispiel #9
0
void hmac_final(HMACCTX ctx, unsigned char *hashmacbuf, unsigned int *len) {
  HMAC_Final(ctx,hashmacbuf,len);

#ifndef OLD_CRYPTO
  HMAC_CTX_cleanup(ctx);
#else
  HMAC_cleanup(ctx);
#endif

  SAFE_FREE(ctx);
}
Beispiel #10
0
static void hmac_destroy(struct crypt *c)
{
	struct hmac_priv *hp = crypt_priv(c);

	if (!hp)
		return;

	HMAC_cleanup(&hp->hp_ctx);
	free(hp);
	free(c);
}
Beispiel #11
0
void
mac_clear(Mac *mac)
{
	if (mac->type == SSH_UMAC) {
		if (mac->umac_ctx != NULL)
			umac_delete(mac->umac_ctx);
	} else if (mac->evp_md != NULL)
		HMAC_cleanup(&mac->evp_ctx);
	mac->evp_md = NULL;
	mac->umac_ctx = NULL;
}
Beispiel #12
0
void hmac_final(HMACCTX ctx, unsigned char *hashmacbuf, unsigned int *len) {
  HMAC_Final(ctx,hashmacbuf,len);

#if OPENSSL_VERSION_NUMBER > 0x10100000L
  HMAC_CTX_free(ctx);
  ctx = NULL;
#else
  HMAC_cleanup(ctx);
  SAFE_FREE(ctx);
  ctx = NULL;
#endif
}
Beispiel #13
0
int main(int argc, char **argv)
{
    Octstr *data, *filename, *mac, *key;
    unsigned char macbuf[EVP_MAX_MD_SIZE], *p;
    int mac_len;
#ifdef HAVE_LIBSSL
    HMAC_CTX ctx;
#endif

    gwlib_init();

    get_and_set_debugs(argc, argv, NULL);

    if (argc < 3)
        panic(0, "Syntax: %s <key> <file>\n", argv[0]);
  
    key = octstr_create(argv[1]);    
    filename = octstr_create(argv[2]);
    data = octstr_read_file(octstr_get_cstr(filename));

    if (data == NULL)
        panic(0, "Cannot read file.");

    debug("",0,"Dumping file `%s':", octstr_get_cstr(filename));
    octstr_dump(data, 0);

#ifdef HAVE_LIBSSL
    HMAC_Init(&ctx, octstr_get_cstr(key), octstr_len(key), EVP_sha1());
    p = HMAC(EVP_sha1(), octstr_get_cstr(key), octstr_len(key), 
         octstr_get_cstr(data), octstr_len(data), 
         macbuf, &mac_len);
    HMAC_cleanup(&ctx);
#else
    macbuf[0] = 0;
    mac_len = 0;
    p = macbuf;
    warning(0, "No SSL support. Can't calculate HMAC value.");
#endif
    
    mac = octstr_create_from_data(p, mac_len);
    octstr_binary_to_hex(mac, 0);
    
    debug("",0,"HMAC of file `%s' and key `%s' is:", 
          octstr_get_cstr(filename), octstr_get_cstr(key));
    octstr_dump(mac, 0);      

    octstr_destroy(data);
    octstr_destroy(mac);
    octstr_destroy(key);
    gwlib_shutdown();
    return 0;
}
void *por_tag_thread(void *threadargs_ptr){

	HMAC_CTX ctx;
	unsigned char digest[SHA_DIGEST_LENGTH];
	unsigned int digest_len = 0;
	unsigned int block;
	int *ret = NULL;
	unsigned char buf[POR_BLOCK_SIZE];
	struct thread_arguments *threadargs = threadargs_ptr;
	int i = 0;
	
	if(!threadargs || !threadargs->file || !threadargs->tags || !threadargs->key || !threadargs->numblocks) goto cleanup;
	
	/* Allocate memory for return value - this should be freed by the checker */
	ret = malloc(sizeof(int));
	if(!ret) goto cleanup;
	*ret = 0;
	
	/* For N threads, read in and tag each Nth block */
	block = threadargs->threadid;
	for(i = 0; i < threadargs->numblocks; i++){
		memset(digest, 0, SHA_DIGEST_LENGTH);
		memset(buf, 0, POR_BLOCK_SIZE);
		fseek(threadargs->file, (block*POR_BLOCK_SIZE), SEEK_SET);
		fread(buf, POR_BLOCK_SIZE, 1, threadargs->file);
		if(ferror(threadargs->file)) goto cleanup;

		/* Calculate the tag for this block */
		HMAC_CTX_init(&ctx);
		HMAC_Init(&ctx, threadargs->key->prf_key, threadargs->key->prf_key_size, EVP_sha1());
	
		
		HMAC_Update(&ctx, (const unsigned char *)&block, sizeof(unsigned int));
		HMAC_Update(&ctx, (unsigned char *)threadargs->filepath, (int)threadargs->filepath_len);
		HMAC_Update(&ctx, buf, POR_BLOCK_SIZE);
		
		HMAC_Final(&ctx, digest, &digest_len);

		HMAC_cleanup(&ctx);		

		/* Store the tag in a buffer until all threads are done. Writer should destroy tags. */
		memcpy((threadargs->tags + (SHA_DIGEST_LENGTH * block)), digest, digest_len);
		block += NUM_THREADS;
	}

	*ret = 1;
	pthread_exit(ret);

cleanup:
	pthread_exit(ret);
	
}
Beispiel #15
0
void HMAC::release(void)
{
    if(context)
        HMAC_cleanup((HMAC_CTX *)context);

    if(context) {
        delete (HMAC_CTX *)context;
        context = NULL;
    }

    bufsize = 0;
    textbuf[0] = 0;
}
Beispiel #16
0
bool HMAC_Create(COSE_MacMessage * pcose, int HSize, int TSize, const byte * pbKey, size_t cbKey, const byte * pbAuthData, size_t cbAuthData, cose_errback * perr)
{
	HMAC_CTX ctx;
	const EVP_MD * pmd = NULL;
	byte * rgbOut = NULL;
	unsigned int cbOut;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context * context = &pcose->m_message.m_allocContext;
#endif

	HMAC_CTX_init(&ctx);

	if (0) {
	errorReturn:
		COSE_FREE(rgbOut, context);
		HMAC_cleanup(&ctx);
		return false;
	}

	switch (HSize) {
	case 256: pmd = EVP_sha256(); break;
	case 384: pmd = EVP_sha384(); break;
	case 512: pmd = EVP_sha512(); break;
	default: FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER); break;
	}

	rgbOut = COSE_CALLOC(EVP_MAX_MD_SIZE, 1, context);
	CHECK_CONDITION(rgbOut != NULL, COSE_ERR_OUT_OF_MEMORY);

	CHECK_CONDITION(HMAC_Init(&ctx, pbKey, (int) cbKey, pmd), COSE_ERR_CRYPTO_FAIL);
	CHECK_CONDITION(HMAC_Update(&ctx, pbAuthData, cbAuthData), COSE_ERR_CRYPTO_FAIL);
	CHECK_CONDITION(HMAC_Final(&ctx, rgbOut, &cbOut), COSE_ERR_CRYPTO_FAIL);

	CHECK_CONDITION(_COSE_array_replace(&pcose->m_message, cn_cbor_data_create(rgbOut, TSize / 8, CBOR_CONTEXT_PARAM_COMMA NULL), INDEX_MAC_TAG, CBOR_CONTEXT_PARAM_COMMA NULL), COSE_ERR_CBOR);

	HMAC_cleanup(&ctx);
	return true;
}
Beispiel #17
0
void
mac_clear(Mac *mac)
{
#ifdef UMAC_HAS_BEEN_UNBROKEN
	if (mac->type == SSH_UMAC) {
		if (mac->umac_ctx != NULL)
			umac_delete(mac->umac_ctx);
	} else if (mac->type == SSH_UMAC128) {
		if (mac->umac_ctx != NULL)
			umac128_delete(mac->umac_ctx);
	} else
#endif
	if (mac->evp_md != NULL)
		HMAC_cleanup(&mac->evp_ctx);
	mac->evp_md = NULL;
	mac->umac_ctx = NULL;
}
LONGBOW_TEST_CASE(Specialization, test_hmac_sha512)
{
    HMAC_CTX ctx;
    char key[] = "apple_pie_is_good";
    int fd;
    uint8_t to_digest_buffer[MAXPATHLEN];
    ssize_t to_digest_length;

    uint8_t true_hmac_buffer[MAXPATHLEN];
    ssize_t true_hmac_length;

LONGBOW_STOP_DEPRECATED_WARNINGS
    HMAC_CTX_init(&ctx);
    HMAC_Init_ex(&ctx, key, sizeof(key), EVP_sha512(), NULL);
LONGBOW_START_DEPRECATED_WARNINGS

    fd = open("test_random_bytes", O_RDONLY);
    assertTrue(fd > 0, "Could not open input file: %s", strerror(errno));
    to_digest_length = read(fd, to_digest_buffer, sizeof(to_digest_buffer));
    assertTrue(to_digest_length > 0, "Could not read input file: %s", strerror(errno));
    close(fd);

    fd = open("test_random_bytes.hmac_sha512", O_RDONLY);
    assertTrue(fd > 0, "Could not open input file: %s", strerror(errno));
    true_hmac_length = read(fd, true_hmac_buffer, sizeof(true_hmac_buffer));
    assertTrue(true_hmac_length > 0, "Could not read input file: %s", strerror(errno));
    close(fd);

    _hmacInit(&ctx);
    _hmacUpdate(&ctx, to_digest_buffer, to_digest_length);
    PARCBuffer *output = _hmacFinalize(&ctx);

    assertTrue(parcBuffer_Position(output) == true_hmac_length,
               "hmac wrong length, expected %zu got %zu",
               true_hmac_length,
               parcBuffer_Position(output));

    assertTrue(memcmp(parcByteArray_Array(parcBuffer_Array(output)), true_hmac_buffer, true_hmac_length) == 0,
               "hmac values did not match");

LONGBOW_STOP_DEPRECATED_WARNINGS
    HMAC_cleanup(&ctx);
LONGBOW_START_DEPRECATED_WARNINGS

    parcBuffer_Release(&output);
}
Beispiel #19
0
static void dohmac(void)
    {
    HMAC_CTX ctx;
    unsigned char hmac_value[EVP_MAX_MD_SIZE];
    unsigned int hmac_len, i;
    char key[16] = "etaonrishdlcupfm";
    unsigned char buf[256];
    /* Generate digest of input stream */ 
    HMAC_Init(&ctx, key, sizeof(key), EVP_sha1());
    memcpy(buf, "abcdefghijklmnopqrstuvwxyz", 26);
    HMAC_Update(&ctx, buf, 26);
    HMAC_Final(&ctx, hmac_value, &hmac_len);
    HMAC_cleanup(&ctx);
    
    for(i = 0; i < hmac_len; i++) fprintf(stderr, "%02x", hmac_value[i]);
    fprintf(stderr, "\n");
    return;
}
Beispiel #20
0
u_char *
mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen)
{
	HMAC_CTX c;
	static u_char m[EVP_MAX_MD_SIZE];
	u_char b[4];

	if (mac->key == NULL)
		fatal("mac_compute: no key");
	if (mac->mac_len > sizeof(m))
		fatal("mac_compute: mac too long");
	HMAC_Init(&c, mac->key, mac->key_len, mac->md);
	PUT_32BIT(b, seqno);
	HMAC_Update(&c, b, sizeof(b));
	HMAC_Update(&c, data, datalen);
	HMAC_Final(&c, m, NULL);
	HMAC_cleanup(&c);
	return (m);
}
Beispiel #21
0
static void switch_write_mac(void) {
  /* First we can clear the write MAC, kept from rekeying. */
  if (write_macs[write_mac_idx].key) {
    clear_mac(&(write_macs[write_mac_idx]));
#if OPENSSL_VERSION_NUMBER > 0x000907000L
    HMAC_CTX_cleanup(&(write_ctxs[write_mac_idx]));
#else
    HMAC_cleanup(&(write_ctxs[write_mac_idx]));
#endif

    /* Now we can switch the index. */
    if (write_mac_idx == 1) {
      write_mac_idx = 0;
      return;
    }

    write_mac_idx = 1;
  }
}
Beispiel #22
0
/* {{{ libssh2_mac_method_hmac_sha1_hash
 * Calculate hash using full sha1 value
 */
static int libssh2_mac_method_hmac_sha1_hash(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno,
																	   const unsigned char *packet, unsigned long packet_len, 
																	   const unsigned char *addtl, unsigned long addtl_len, void **abstract)
{
	HMAC_CTX ctx;
	unsigned char seqno_buf[4];

	libssh2_htonu32(seqno_buf, seqno);

	HMAC_Init(&ctx, *abstract, 20, EVP_sha1());
	HMAC_Update(&ctx, seqno_buf, 4);
	HMAC_Update(&ctx, packet, packet_len);
	if (addtl && addtl_len) {
		HMAC_Update(&ctx, addtl, addtl_len);
	}
	HMAC_Final(&ctx, buf, NULL);
	HMAC_cleanup(&ctx);

	return 0;
}
Beispiel #23
0
static void switch_read_mac(void) {
  /* First we can clear the read MAC, kept from rekeying. */
  if (read_macs[read_mac_idx].key) {
    clear_mac(&(read_macs[read_mac_idx]));
#if OPENSSL_VERSION_NUMBER > 0x000907000L
    HMAC_CTX_cleanup(&(read_ctxs[read_mac_idx]));
#else
    HMAC_cleanup(&(read_ctxs[read_mac_idx]));
#endif
    mac_blockszs[read_mac_idx] = 0; 

    /* Now we can switch the index. */
    if (read_mac_idx == 1) {
      read_mac_idx = 0;
      return;
    }

    read_mac_idx = 1;
  }
}
Beispiel #24
0
unsigned char *HMAC(//fixed to SHA256: EVP_MD *evp_md,
                    unsigned char *key, int key_len,
                    unsigned char *d, int n,
                    unsigned char *md)
                    //always 32, unsigned int *md_len)
	{
	HMAC_CTX c;
	//static unsigned char m[EVP_MAX_MD_SIZE];
	static unsigned char m[SHA256_DIGEST_LENGTH];

	if (md == NULL) md=m;

	//HMAC_Init(&c,key,key_len,evp_md);
        HMAC_Init(&c, key, key_len);

	HMAC_Update(&c,d,n);
	HMAC_Final(&c,md); //always 32:,md_len);
	HMAC_cleanup(&c);
	return(md);
	}
int por_verify_block(char *filepath, size_t filepath_len, unsigned char *block, size_t block_len, unsigned int index, unsigned char *tag, size_t tag_len){
	
	HMAC_CTX ctx;
	POR_key *key = NULL;
	unsigned char digest[SHA_DIGEST_LENGTH];
	unsigned int digest_len = 0;
	int ret = 0;
	
	if(!filepath || !block || !block_len || !tag || !tag_len) return 0;
	if(filepath_len >= MAXPATHLEN) return 0;
	
	key = por_get_keys();
	if(!key) goto cleanup;
	
	HMAC_CTX_init(&ctx);
	HMAC_Init(&ctx, key->prf_key, key->prf_key_size, EVP_sha1());

	HMAC_Update(&ctx, (const unsigned char *)&index, sizeof(unsigned int));
	HMAC_Update(&ctx, (unsigned char *)filepath, (int)filepath_len);
	HMAC_Update(&ctx, block, block_len);
		
	HMAC_Final(&ctx, digest, &digest_len);
		
	HMAC_cleanup(&ctx);			

	ret = memcmp(digest, tag, tag_len);

/*	printf("Tag: ");
	printhex(tag, tag_len);
	printf("Verify: ");
	printhex(digest, digest_len);
*/
	if(key) destroy_por_key(key);

	if(ret == 0) return 1;
	
cleanup:
	return 0;
	
}
Beispiel #26
0
int
P_hash(const char *digest, unsigned char *dest, int dlen, unsigned char *secret, int sslen,
       unsigned char *seed, int slen)
{
    unsigned char hmac[20];
    uint32_t hlen;
    HMAC_CTX hm;
    const EVP_MD *md = EVP_get_digestbyname(digest);
    uint32_t tmpslen;
    unsigned char tmpseed[slen];
    unsigned char *out = dest;
    int pending = dlen;

    // Copy initial seed
    memcpy(tmpseed, seed, slen);
    tmpslen = slen;

    // Calculate enough data to fill destination
    while (pending > 0) {
        HMAC_Init(&hm, secret, sslen, md);
        HMAC_Update(&hm, tmpseed, tmpslen);
        HMAC_Final(&hm, tmpseed, &tmpslen);

        HMAC_Init(&hm, secret, sslen, md);
        HMAC_Update(&hm, tmpseed, tmpslen);
        HMAC_Update(&hm, seed, slen);
        HMAC_Final(&hm, hmac, &hlen);

        hlen = (hlen > pending) ? pending : hlen;
        memcpy(out, hmac, hlen);
        out += hlen;
        pending -= hlen;
    }
    HMAC_cleanup(&hm);

    return hlen;
}
Beispiel #27
0
char *
host_hash(const char *host, const char *name_from_hostfile, u_int src_len)
{
	const EVP_MD *md = EVP_sha1();
	HMAC_CTX mac_ctx;
	u_char salt[256], result[256];
	char uu_salt[512], uu_result[512];
	static char encoded[1024];
	u_int i, len;

	len = EVP_MD_size(md);

	if (name_from_hostfile == NULL) {
		/* Create new salt */
		for (i = 0; i < len; i++)
			salt[i] = arc4random();
	} else {
		/* Extract salt from known host entry */
		if (extract_salt(name_from_hostfile, src_len, salt,
		    sizeof(salt)) == -1)
			return (NULL);
	}

	HMAC_Init(&mac_ctx, salt, len, md);
	HMAC_Update(&mac_ctx, __UNCONST(host), strlen(host));
	HMAC_Final(&mac_ctx, result, NULL);
	HMAC_cleanup(&mac_ctx);

	if (__b64_ntop(salt, len, uu_salt, sizeof(uu_salt)) == -1 ||
	    __b64_ntop(result, len, uu_result, sizeof(uu_result)) == -1)
		fatal("host_hash: __b64_ntop failed");

	snprintf(encoded, sizeof(encoded), "%s%s%c%s", HASH_MAGIC, uu_salt,
	    HASH_DELIM, uu_result);

	return (encoded);
}
Beispiel #28
0
unsigned char *HMAC2(//fixed to SHA256: EVP_MD *evp_md,
                    unsigned char *key, int key_len,
                    unsigned char *d, int n,
                    unsigned char *md)
                    //always 64, unsigned int *md_len)
	{
	HMAC_CTX c;
	//static unsigned char m[EVP_MAX_MD_SIZE];
	static unsigned char m[2*SHA256_DIGEST_LENGTH];

	if (md == NULL) md=m;

	//first round
        HMAC_Init(&c, key, key_len);
	HMAC_Update(&c,d,n);
	HMAC_Final(&c,md);

	//second round
        HMAC_Init(&c, NULL, key_len); //only performs memcpy
	HMAC_Update(&c,d,n);
	HMAC_Final(&c,md+SHA256_DIGEST_LENGTH);
	HMAC_cleanup(&c);
	return(md);
	}
int por_tag_file(char *filepath, size_t filepath_len, char *tagfilepath, size_t tagfilepath_len){
		
	
	POR_key *key = NULL;
	FILE *file = NULL;
	FILE *tagfile = NULL;
	char realtagfilepath[MAXPATHLEN];
	char yesorno = 0;
	unsigned int index = 0;
#ifdef THREADING
	pthread_t threads[NUM_THREADS];
	int *thread_return = NULL;
	struct thread_arguments threadargs[NUM_THREADS];
	struct stat st;
	size_t numfileblocks = 0;

	unsigned char *tags = NULL;
	unsigned int digest_len = 0;
	memset(threads, 0, sizeof(pthread_t) * NUM_THREADS);
	memset(&st, 0, sizeof(struct stat));
#else
	HMAC_CTX ctx;
	unsigned char buf[POR_BLOCK_SIZE];
	unsigned char digest[SHA_DIGEST_LENGTH];
	unsigned int digest_len = 0;
#endif

	memset(realtagfilepath, 0, MAXPATHLEN);


	if(!filepath) return 0;
	if(filepath_len >= MAXPATHLEN) return 0;
	if(tagfilepath_len >= MAXPATHLEN) return 0;
	
	/* If no tag file path is specified, add a .tag extension to the filepath */
	if(!tagfilepath && (filepath_len < MAXPATHLEN - 5)){
		if( snprintf(realtagfilepath, MAXPATHLEN, "%s.tag", filepath) >= MAXPATHLEN ) goto cleanup;
	}else{
		memcpy(realtagfilepath, tagfilepath, tagfilepath_len);
	}
	
	/* Check to see if the tag file exists */
	if( (access(realtagfilepath, F_OK) == 0)){
		fprintf(stdout, "WARNING: A tag file for %s already exist; do you want to overwite (y/N)?", filepath);
		scanf("%c", &yesorno);
		if(yesorno != 'y') goto exit;
	}
	
	tagfile = fopen(realtagfilepath, "w");
	if(!tagfile){
		fprintf(stderr, "ERROR: Was not able to create %s.\n", realtagfilepath);
		goto cleanup;
	}

	/* Get the POR key */
	key = por_get_keys();
	if(!key) goto cleanup;
	

	OpenSSL_add_all_digests();

#ifdef THREADING

	/* Calculate the number blocks in the file */
	if(stat(filepath, &st) < 0) return 0;
	numfileblocks = (st.st_size/POR_BLOCK_SIZE);
	if(st.st_size%POR_BLOCK_SIZE) numfileblocks++;

	/* Allocate buffer to hold tags until we write them out */
	if( ((tags = malloc( SHA_DIGEST_LENGTH * numfileblocks )) == NULL)) goto cleanup;
	memset(tags, 0, (SHA_DIGEST_LENGTH * numfileblocks));

	for(index = 0; index < NUM_THREADS; index++){
		/* Open a unique file descriptor for each thread to avoid race conditions */
		threadargs[index].file = fopen(filepath, "r");
		if(!threadargs[index].file) goto cleanup;
		threadargs[index].filepath = filepath;
		threadargs[index].filepath_len = filepath_len;
		threadargs[index].key = key;
		threadargs[index].threadid = index;
		threadargs[index].numblocks = numfileblocks/NUM_THREADS;
		threadargs[index].tags = tags;
		
		/* If there is not an equal number of blocks to tag, add the extra blocks to
		 * the corresponding threads */
		if(index < numfileblocks%NUM_THREADS)
			threadargs[index].numblocks++;
		/* If the thread has blocks to tag, spawn it */
		if(threadargs[index].numblocks > 0)
			if(pthread_create(&threads[index], NULL, por_tag_thread, (void *) &threadargs[index]) != 0) goto cleanup;
	}
	/* Check to see all tags were generated */
	for(index = 0; index < NUM_THREADS; index++){
		if(threads[index]){
			if(pthread_join(threads[index], (void **)&thread_return) != 0) goto cleanup;
			if(!thread_return || !(*thread_return))goto cleanup;
			else free(thread_return);
			/* Close the file */
			if(threadargs[index].file)
				fclose(threadargs[index].file);
		}
	}
	/* Write the tags out */
	for(index = 0; index < numfileblocks; index++){
		if(!tags[index]) goto cleanup;
		
		/* Write the tag to disk */
		digest_len = SHA_DIGEST_LENGTH;
		fwrite(&digest_len, sizeof(unsigned int), 1, tagfile);
		if(ferror(tagfile)) goto cleanup;	
		fwrite(tags + (SHA_DIGEST_LENGTH * index), SHA_DIGEST_LENGTH, 1, tagfile);
		if(ferror(tagfile)) goto cleanup;
		
	}
	sfree(tags, (SHA_DIGEST_LENGTH * numfileblocks));
#else
	/* Open the file for reading */
	file = fopen(filepath, "r");
	if(!file){
		fprintf(stderr, "ERROR: Was not able to open %s for reading.\n", filepath);
		goto cleanup;
	}

	index = 0;
	do{
		/* Calculate the tag for this block */
		HMAC_CTX_init(&ctx);
		HMAC_Init(&ctx, key->prf_key, key->prf_key_size, EVP_sha1());
		memset(buf, 0, POR_BLOCK_SIZE);

		fread(buf, POR_BLOCK_SIZE, 1, file);
		if(ferror(file)) goto cleanup;
		
		HMAC_Update(&ctx, (const unsigned char *)&index, sizeof(unsigned int));
		HMAC_Update(&ctx, (unsigned char *)filepath, (int)filepath_len);
		HMAC_Update(&ctx, buf, POR_BLOCK_SIZE);
		
		HMAC_Final(&ctx, digest, &digest_len);

		/* Write the tag to disk */
		fwrite(&digest_len, sizeof(unsigned int), 1, tagfile);
		if(ferror(tagfile)) goto cleanup;	
		fwrite(digest, digest_len, 1, tagfile);
		if(ferror(tagfile)) goto cleanup;
		
		index++;
		HMAC_cleanup(&ctx);		

	}while(!feof(file));
#endif

exit:
	destroy_por_key(key);
	if(file) fclose(file);
	if(tagfile) fclose(tagfile);
	return 1;

cleanup:
	fprintf(stderr, "ERROR: Was unable to create tag file.\n");
#ifdef THREADING
	for(index = 0; index < NUM_THREADS; index++){
		if(threads[index] != NULL) pthread_cancel(threads[index]);
		if(threadargs[index].file) fclose(threadargs[index].file);
	}

	sfree(tags, (SHA_DIGEST_LENGTH * numfileblocks));
#endif
	if(key) destroy_por_key(key);	
	if(file) fclose(file);
	if(tagfile){ 
		ftruncate(fileno(tagfile), 0);
		unlink(realtagfilepath);
		fclose(tagfile);
	}
	return 0;
}
USES_APPLE_DEPRECATED_API	/* OpenSSL API has been deprecated by Apple */

/* avoid inclusion of these FR headers which conflict w/ OpenSSL */
#define _FR_MD4_H
#define _FR_SHA1_H

#include "extern.h"

#include <string.h>

#include <openssl/des.h> /* des_cblock */
#include <openssl/md5.h>
#include <openssl/hmac.h>

/*
 * Generate the State attribute, suitable for passing to fr_pair_make().
 * 'challenge' must be a null terminated string, and be sized at least
 * as large as indicated in the function definition.
 *
 * Returns 0 on success, non-zero otherwise.  For successful returns,
 * 'rad_state' (suitable for passing to fr_pair_make()) and 'raw_state',
 * if non-NULL, will be filled in.
 *
 * In the simplest implementation, we would just use the challenge as state.
 * Unfortunately, the RADIUS secret protects only the User-Password
 * attribute; an attacker that can remove packets from the wire and insert
 * new ones can simply insert a replayed state without having to know
 * the secret.  If not for an attacker that can remove packets from the
 * network, I believe trivial state to be secure.
 *
 * So, we have to make up for that deficiency by signing our state with
 * data unique to this specific request.  A NAS would use the Request
 * Authenticator, but we don't know what that will be when the State is
 * returned to us, so we'll use the time.  So our replay prevention
 * is limited to a time interval (inst->challenge_delay).  We could keep
 * track of all challenges issued over that time interval for
 * better protection.
 *
 * Our state, then, is
 *   (challenge + flags + time + hmac(challenge + resync + time, key)),
 * where '+' denotes concatentation, 'challenge' is ... the challenge,
 * 'flags' is a 32-bit value that can be used to record additional info,
 * 'time' is the 32-bit time (LSB if time_t is 64 bits), and 'key' is a
 * random key, generated in mod_instantiate().  'flags' and 'time' are
 * in network byte order.
 *
 * As the signing key is unique to each server, only the server which
 * generates a challenge can verify it; this should be OK if your NAS's
 * load balance across RADIUS servers using a "first available" algorithm.
 * If your NAS's round-robin and don't "stick" to the same server if they
 * see a State attribute (ugh), you could use the RADIUS secret instead,
 * but read RFC 2104 first, and make very sure you really want to do this.
 *
 * Since only the "same server" can verify State, 'flags' and 'time' doesn't
 * really need to be in network byte order, but we do it anyway.
 *
 * The State attribute is an octet string, however some versions of Cisco
 * IOS and Catalyst OS (at least IOS 12.1(26)E4 and CatOS 7.6.12) treat it
 * as an ASCII string (they only return data up to the first NUL byte).
 * So we must handle state as an ASCII string (0x00 -> 0x3030).
 */

/*
 * OTP_MAX_RADSTATE_LEN is composed of:
 *
 *   clen * 2 +			challenge
 *   8 +			flags
 *   8 +			time
 *   sizeof(hmac) * 2 +		hmac
 *   1				\0'
 */

/** Generate an OTP state value
 *
 * Generates an OTP state value (an string of ASCII hexits in an opaque binary
 * string).
 *
 * @param[out] state buffer in which to write the generated state value.
 * @param[in] challenge The challenge value.
 * @param[in] clen The length of the challenge data.
 * @param[in] flags to remember.
 * @param[in] when the challenge was originally generated.
 * @param[in] key HMAC key.
 * @return the amount of data written into the state buffer.
 */
size_t otp_gen_state(char state[OTP_MAX_RADSTATE_LEN],
		     char const challenge[OTP_MAX_CHALLENGE_LEN],
		     size_t clen,
		     int32_t flags, int32_t when, uint8_t const key[16])
{
	HMAC_CTX hmac_ctx;
	uint8_t hmac[MD5_DIGEST_LENGTH];
	char *p;

	/*
	 *	Generate the hmac.  We already have a dependency on openssl for
	 *	DES, so we'll use it's hmac functionality also -- saves us from
	 *	having to collect the data to be signed into one
	 *	contiguous piece.
	 */
	HMAC_Init(&hmac_ctx, key, sizeof(key[0]) * 16, EVP_md5());
	HMAC_Update(&hmac_ctx, (uint8_t const *) challenge, clen);
	HMAC_Update(&hmac_ctx, (uint8_t *) &flags, 4);
	HMAC_Update(&hmac_ctx, (uint8_t *) &when, 4);
	HMAC_Final(&hmac_ctx, hmac, NULL);
	HMAC_cleanup(&hmac_ctx);

	/*
	 *	Generate the state.
	 */
	p = state;

	/*
	 *	Add the challenge (which is already ASCII encoded)
	 */
	p += fr_bin2hex(p, (uint8_t const *) challenge, clen);

	/* Add the flags and time. */
	p += fr_bin2hex(p, (uint8_t *) &flags, 4);
	p += fr_bin2hex(p, (uint8_t *) &when, 4);

	/* Add the hmac. */
	p += fr_bin2hex(p, hmac, 16);

	return p - state;
}