Exemple #1
0
// given a string, generate a 32-bit key
int generate_key(char *pwd, u8 *pkey)
{
	int len_pwd = strlen(pwd);
	struct scatterlist sg;
	struct crypto_hash *tfm;
	struct hash_desc desc;
	int i;

	unsigned char output[SHA1_LENGTH];  // key generated
	char *buf = kmalloc(MAX_PWD, GFP_KERNEL); // password buffer
	memset(buf, 0, MAX_PWD);
	strncpy(buf, pwd, len_pwd);

	tfm = crypto_alloc_hash("sha1", 1, CRYPTO_ALG_ASYNC);
	desc.tfm = tfm;
	desc.flags = 0;

	sg_init_one(&sg, buf, len_pwd);
	crypto_hash_init(&desc);

	crypto_hash_update(&desc, &sg, len_pwd);
	crypto_hash_final(&desc, output);

	for(i=0; i<16; i++)
		pkey[i] = output[i];

	for(i=0; i<16; i++)
		pkey[i+16] = output[i];

	crypto_free_hash(tfm);
	kfree(buf);

	return 0;
}
Exemple #2
0
static int pohmelfs_hash(struct pohmelfs_crypto_thread *tc)
{
	struct pohmelfs_crypto_engine *e = &tc->eng;
	struct hash_desc *desc = e->data;
	unsigned char *dst = tc->trans->iovec.iov_base + sizeof(struct netfs_cmd);
	int err;

	desc->tfm = e->hash;
	desc->flags = 0;

	err = crypto_hash_init(desc);
	if (err)
		return err;

	err = pohmelfs_trans_iter(tc->trans, e, pohmelfs_hash_iterator);
	if (err)
		return err;

	err = crypto_hash_final(desc, dst);
	if (err)
		return err;

	{
		unsigned int i;
		dprintk("%s: ", __func__);
		for (i = 0; i < tc->psb->crypto_attached_size; ++i)
			dprintka("%02x ", dst[i]);
		dprintka("\n");
	}

	return 0;
}
Exemple #3
0
TEE_Result tee_hash_createdigest(uint32_t algo, const uint8_t *data,
				 size_t datalen, uint8_t *digest,
				 size_t digestlen)
{
	TEE_Result res;
	void *ctx = NULL;

	res = crypto_hash_alloc_ctx(&ctx, algo);
	if (res)
		return res;

	res = crypto_hash_init(ctx, algo);
	if (res)
		goto out;

	if (datalen != 0) {
		res = crypto_hash_update(ctx, algo, data, datalen);
		if (res)
			goto out;
	}

	res = crypto_hash_final(ctx, algo, digest, digestlen);
out:
	crypto_hash_free_ctx(ctx, algo);

	return res;
}
Exemple #4
0
static int tcp_v6_md5_hash_hdr(char *md5_hash, struct tcp_md5sig_key *key,
			       const struct in6_addr *daddr, struct in6_addr *saddr,
			       const struct tcphdr *th)
{
	struct tcp_md5sig_pool *hp;
	struct hash_desc *desc;

	hp = tcp_get_md5sig_pool();
	if (!hp)
		goto clear_hash_noput;
	desc = &hp->md5_desc;

	if (crypto_hash_init(desc))
		goto clear_hash;
	if (tcp_v6_md5_hash_pseudoheader(hp, daddr, saddr, th->doff << 2))
		goto clear_hash;
	if (tcp_md5_hash_header(hp, th))
		goto clear_hash;
	if (tcp_md5_hash_key(hp, key))
		goto clear_hash;
	if (crypto_hash_final(desc, md5_hash))
		goto clear_hash;

	tcp_put_md5sig_pool();
	return 0;

clear_hash:
	tcp_put_md5sig_pool();
clear_hash_noput:
	memset(md5_hash, 0, 16);
	return 1;
}
Exemple #5
0
static int
finalize_hash (struct hash_desc *desc, unsigned char * out, unsigned int out_size)
{
	int ret = -1;

	if (!desc || !desc->tfm || !out || !out_size)
	{
		printk(KERN_ERR "FIPS(%s): Invalid args", __FUNCTION__);		
		return ret;
	}

	if (crypto_hash_digestsize(desc->tfm) > out_size)
	{
		printk(KERN_ERR "FIPS(%s): Not enough space for digest", __FUNCTION__);		
		return ret;
	}

	ret = crypto_hash_final (desc, out);

	if (ret)
	{
		printk(KERN_ERR "FIPS(%s): crypto_hash_final failed", __FUNCTION__);		
		return -1;
	}

	return 0;
}
Exemple #6
0
int hash_lbr(uint8_t hash[DIGEST_LENGTH],struct lbr_t *lbr) {
    struct scatterlist sg;
    int i, j;

    /* No error checking here. If anything fails, we better go straight home anyway. */

    crypto_hash_init(&armor_desc);
    armor_desc.flags = 0;

    /* Loop over all LBR entries. */
    for (i = 0; i < LBR_ENTRIES; i++) {
        sg_set_buf(&sg, &lbr->from[(lbr->tos - i) % LBR_ENTRIES], sizeof(uint64_t));
        crypto_hash_update(&armor_desc, &sg, sizeof(uint64_t));
        sg_set_buf(&sg, &lbr->to  [(lbr->tos - i) % LBR_ENTRIES], sizeof(uint64_t));
        crypto_hash_update(&armor_desc, &sg, sizeof(uint64_t));
        printdj(false, "lbr[%2d], <from: 0x%012llx, to: 0x%012llx>\n", i, 
                lbr->from[(lbr->tos+LBR_ENTRIES-i) % LBR_ENTRIES], 
                lbr->  to[(lbr->tos+LBR_ENTRIES-i) % LBR_ENTRIES]);
    }
    ARMOR_STAT_INC(digests);
    crypto_hash_final(&armor_desc, hash);
    
    printdj(false, "hash: ");
    for (j = 0; j < DIGEST_LENGTH; j++) printdj(false,"%02x", hash[j]);
    printdj(false,"\n");

    return 0;
}
Exemple #7
0
void sha1_final(void *c, void *out)
{
	struct hash_desc *d = c;

	if (crypto_hash_final(d, out))
		printk(KERN_INFO "crypto_hash_final()\n");
}
/* checksum the plaintext data and hdrlen bytes of the token header */
s32
make_checksum(char *cksumname, char *header, int hdrlen, struct xdr_buf *body,
		   int body_offset, struct xdr_netobj *cksum)
{
	struct hash_desc                desc; /* XXX add to ctx? */
	struct scatterlist              sg[1];
	int err;

	desc.tfm = crypto_alloc_hash(cksumname, 0, CRYPTO_ALG_ASYNC);
	if (IS_ERR(desc.tfm))
		return GSS_S_FAILURE;
	cksum->len = crypto_hash_digestsize(desc.tfm);
	desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;

	err = crypto_hash_init(&desc);
	if (err)
		goto out;
	sg_set_buf(sg, header, hdrlen);
	err = crypto_hash_update(&desc, sg, hdrlen);
	if (err)
		goto out;
	err = xdr_process_buf(body, body_offset, body->len - body_offset,
			      checksummer, &desc);
	if (err)
		goto out;
	err = crypto_hash_final(&desc, cksum->data);

out:
	crypto_free_hash(desc.tfm);
	return err ? GSS_S_FAILURE : 0;
}
Exemple #9
0
/*      If hash_len pointer is NULL - destroy descriptor. */
int cfs_crypto_hash_final(struct cfs_crypto_hash_desc *hdesc,
			  unsigned char *hash, unsigned int *hash_len)
{
	int     err;
	int     size = crypto_hash_digestsize(((struct hash_desc *)hdesc)->tfm);

	if (hash_len == NULL) {
		crypto_free_hash(((struct hash_desc *)hdesc)->tfm);
		kfree(hdesc);
		return 0;
	}
	if (hash == NULL || *hash_len < size) {
		*hash_len = size;
		return -ENOSPC;
	}
	err = crypto_hash_final((struct hash_desc *) hdesc, hash);

	if (err < 0) {
		/* May be caller can fix error */
		return err;
	}
	crypto_free_hash(((struct hash_desc *)hdesc)->tfm);
	kfree(hdesc);
	return err;
}
Exemple #10
0
static int __init sha1_init(void)
{
    struct scatterlist sg;
    struct crypto_hash *tfm;
    struct hash_desc desc;
    unsigned char output[SHA1_LENGTH];
    unsigned char buf[10];
    int i;

    printk(KERN_INFO "sha1: %s\n", __FUNCTION__);

    memset(buf, 'A', 10);
    memset(output, 0x00, SHA1_LENGTH);

    tfm = crypto_alloc_hash("sha1", 0, CRYPTO_ALG_ASYNC);

    desc.tfm = tfm;
    desc.flags = 0;

    sg_init_one(&sg, buf, 10);
    crypto_hash_init(&desc);

    crypto_hash_update(&desc, &sg, 10);
    crypto_hash_final(&desc, output);

    for (i = 0; i < 20; i++) {
        printk(KERN_ERR "%d-%d\n", output[i], i);
    }

    crypto_free_hash(tfm);

    return 0;
}
unsigned char * key_to_hash(unsigned char *key)
{
	struct scatterlist sg;
    	struct crypto_hash *tfm;
    	struct hash_desc desc;
	unsigned char *digest= NULL;
	
	digest=kmalloc(16,GFP_KERNEL);
	if(IS_ERR(digest)){
                printk("Error in allocating memory to Hash Key\n ");
                return NULL;
      	}

    	tfm = crypto_alloc_hash("md5", 0, 0);

    	desc.tfm = tfm;
    	desc.flags = 0;

    	sg_init_one(&sg, key, 16);
    	
	crypto_hash_init(&desc);
	crypto_hash_update(&desc, &sg, 16);
    	crypto_hash_final(&desc, digest);

	crypto_free_hash(tfm);

	if(!digest){
                printk("Error in hashing userland key\n");
                return NULL;
        }
    	return digest;
}
Exemple #12
0
TEE_Result tee_cryp_concat_kdf(uint32_t hash_id, const uint8_t *shared_secret,
			       size_t shared_secret_len,
			       const uint8_t *other_info,
			       size_t other_info_len, uint8_t *derived_key,
			       size_t derived_key_len)
{
	TEE_Result res;
	size_t hash_len, i, n, sz;
	void *ctx = NULL;
	uint8_t tmp[TEE_MAX_HASH_SIZE];
	uint32_t be_count;
	uint8_t *out = derived_key;
	uint32_t hash_algo = TEE_ALG_HASH_ALGO(hash_id);

	res = crypto_hash_alloc_ctx(&ctx, hash_algo);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_hash_get_digest_size(hash_algo, &hash_len);
	if (res != TEE_SUCCESS)
		goto out;

	n = derived_key_len / hash_len;
	sz = hash_len;
	for (i = 1; i <= n + 1; i++) {
		be_count = TEE_U32_TO_BIG_ENDIAN(i);

		res = crypto_hash_init(ctx, hash_algo);
		if (res != TEE_SUCCESS)
			goto out;
		res = crypto_hash_update(ctx, hash_algo, (uint8_t *)&be_count,
				   sizeof(be_count));
		if (res != TEE_SUCCESS)
			goto out;
		res = crypto_hash_update(ctx, hash_algo, shared_secret,
				   shared_secret_len);
		if (res != TEE_SUCCESS)
			goto out;
		if (other_info && other_info_len) {
			res = crypto_hash_update(ctx, hash_algo, other_info,
					   other_info_len);
			if (res != TEE_SUCCESS)
				goto out;
		}
		res = crypto_hash_final(ctx, hash_algo, tmp, sizeof(tmp));
		if (res != TEE_SUCCESS)
			goto out;

		if (i == n + 1)
			sz = derived_key_len % hash_len;
		memcpy(out, tmp, sz);
		out += sz;
	}
	res = TEE_SUCCESS;
out:
	crypto_hash_free_ctx(ctx, hash_algo);
	return res;
}
Exemple #13
0
static void padlock_sha_final(struct crypto_tfm *tfm, uint8_t *out)
{
	if (unlikely(ctx(tfm)->bypass)) {
		crypto_hash_final(&ctx(tfm)->fallback, out);
		ctx(tfm)->bypass = 0;
		return;
	}

	/* Pass the input buffer to PadLock microcode... */
	ctx(tfm)->f_sha_padlock(ctx(tfm)->data, out, ctx(tfm)->used);

	ctx(tfm)->used = 0;
}
Exemple #14
0
static int tcp_v6_md5_hash_skb(char *md5_hash, struct tcp_md5sig_key *key,
			       const struct sock *sk,
			       const struct request_sock *req,
			       const struct sk_buff *skb)
{
	const struct in6_addr *saddr, *daddr;
	struct tcp_md5sig_pool *hp;
	struct hash_desc *desc;
	const struct tcphdr *th = tcp_hdr(skb);

	if (sk) {
		saddr = &inet6_sk(sk)->saddr;
		daddr = &inet6_sk(sk)->daddr;
	} else if (req) {
		saddr = &inet6_rsk(req)->loc_addr;
		daddr = &inet6_rsk(req)->rmt_addr;
	} else {
		const struct ipv6hdr *ip6h = ipv6_hdr(skb);
		saddr = &ip6h->saddr;
		daddr = &ip6h->daddr;
	}

	hp = tcp_get_md5sig_pool();
	if (!hp)
		goto clear_hash_noput;
	desc = &hp->md5_desc;

	if (crypto_hash_init(desc))
		goto clear_hash;

	if (tcp_v6_md5_hash_pseudoheader(hp, daddr, saddr, skb->len))
		goto clear_hash;
	if (tcp_md5_hash_header(hp, th))
		goto clear_hash;
	if (tcp_md5_hash_skb_data(hp, skb, th->doff << 2))
		goto clear_hash;
	if (tcp_md5_hash_key(hp, key))
		goto clear_hash;
	if (crypto_hash_final(desc, md5_hash))
		goto clear_hash;

	tcp_put_md5sig_pool();
	return 0;

clear_hash:
	tcp_put_md5sig_pool();
clear_hash_noput:
	memset(md5_hash, 0, 16);
	return 1;
}
int wrapfs_compute_checksum(struct file* filp, char* buffer, char *checksum_algorithm) {
    struct scatterlist sg[1];
    struct hash_desc desc;
    mm_segment_t oldfs;
    int bytes, rc =0;
    // int diglength = 16;
    int length = PAGE_SIZE;
    unsigned char buf[DIGESTLEN+1];
    char *read_in_buffer = NULL;
    memset(buf,0,DIGESTLEN+1);  
    read_in_buffer = kmalloc(length, GFP_KERNEL);
    if(read_in_buffer == NULL) {
	kfree(read_in_buffer);
	printk("Error in allocating memonry in checksum block.\n");
	return -ENOMEM;
    }

    filp->f_pos = 0;           
    oldfs = get_fs();
    set_fs(KERNEL_DS);

    rc = crypt_init_desc(&desc,checksum_algorithm);
    do {

	bytes = filp->f_op->read(filp, read_in_buffer, length, &filp->f_pos);
	sg_init_one(sg,read_in_buffer,bytes);
	rc = crypto_hash_update(&desc,sg,bytes);

    } while(bytes);

    if(!rc) {
	rc = crypto_hash_final(&desc, buf);//calculate final digest and populate value in buf
#if 0	
	printk("\n printing checksum in compute checksum \n");
	for(i =0;i<16;i++){
	    printk("%02x",buf[i]& 0XFF);
	    //	    buffer[i] = buf[i];
	}
#endif
    }

    rc =  str_to_hex_str(buf, buffer, DIGESTLEN*2 +1, DIGESTLEN);
    crypto_free_hash(desc.tfm);

    set_fs(oldfs);
    kfree(read_in_buffer);
    return rc;
}
int
chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
{
	char *p;
	struct crypto_hash *tfm;
	struct hash_desc desc;
	struct scatterlist sg;
	unsigned char temp_sum[GR_SHA_LEN];
	volatile int retval = 0;
	volatile int dummy = 0;
	unsigned int i;

	sg_init_table(&sg, 1);

	tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC);
	if (IS_ERR(tfm)) {
		/* should never happen, since sha256 should be built in */
		return 1;
	}

	desc.tfm = tfm;
	desc.flags = 0;

	crypto_hash_init(&desc);

	p = salt;
	sg_set_buf(&sg, p, GR_SALT_LEN);
	crypto_hash_update(&desc, &sg, sg.length);

	p = entry->pw;
	sg_set_buf(&sg, p, strlen(p));
	
	crypto_hash_update(&desc, &sg, sg.length);

	crypto_hash_final(&desc, temp_sum);

	memset(entry->pw, 0, GR_PW_LEN);

	for (i = 0; i < GR_SHA_LEN; i++)
		if (sum[i] != temp_sum[i])
			retval = 1;
		else
			dummy = 1;	// waste a cycle

	crypto_free_hash(tfm);

	return retval;
}
Exemple #17
0
/*
 * Calculates block's hash value, to avoid all block compare.
 * hash_out must be allocated outside.
 */
int calc_hash(char* data, size_t size, u8* hash_out)
{
	struct hash_desc sha256_desc;
	struct scatterlist sg;

	sha256_desc.tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC);
	sg_init_one(&sg, data, size);

	crypto_hash_init(&sha256_desc);
	crypto_hash_update(&sha256_desc, &sg, size);
	crypto_hash_final(&sha256_desc, hash_out);

	crypto_free_hash(sha256_desc.tfm);

	return 0;
}
Exemple #18
0
static void digest_header(struct hash_desc *hash, struct iscsi_pdu *pdu,
			  u8 *crc)
{
	struct scatterlist sg[2];
	unsigned int nbytes = sizeof(struct iscsi_hdr);

	sg_init_table(sg, pdu->ahssize ? 2 : 1);

	sg_set_buf(&sg[0], &pdu->bhs, nbytes);
	if (pdu->ahssize) {
		sg_set_buf(&sg[1], pdu->ahs, pdu->ahssize);
		nbytes += pdu->ahssize;
	}

	crypto_hash_init(hash);
	crypto_hash_update(hash, sg, nbytes);
	crypto_hash_final(hash, crc);
}
/* get_key_hash
 *
 * @enc_key: key of which the md5 hash has to be generated
 *
 * Returns the md5 hash of the key. Responsibility of freeing the hashed key lies with the caller who requested the hashed key.
 */
unsigned char *get_key_hash(unsigned char *enc_key)
{
	/* imp, plaintext should be array else getting sefault so copy key in array here */
	struct scatterlist sg;
	struct hash_desc desc;
	int i, err;
	unsigned char *hashed_key;
	unsigned char plaintext[AES_KEY_SIZE];

	for (i = 0; i < AES_KEY_SIZE; i++)
		plaintext[i] = enc_key[i];
	hashed_key = kmalloc(sizeof(char)*AES_KEY_SIZE, GFP_KERNEL);
	desc.tfm = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC);
	if (IS_ERR(desc.tfm)) {
		err = PTR_ERR(desc.tfm);
		printk(KERN_ALERT"error in allocating hash");
		goto ERR;
	}
	desc.flags = 0;
	sg_init_one(&sg, plaintext, AES_KEY_SIZE);
	err = crypto_hash_init(&desc);
	if (err) {
		printk(KERN_ALERT"error in initializing crypto hash\n");
		goto ERR;
	}
	err = crypto_hash_update(&desc, &sg, AES_KEY_SIZE);
	if (err) {
		printk(KERN_ALERT"error in updating crypto hash\n");
		goto ERR;
	}
	printk(KERN_ALERT"cry[to hash updated\n");
	err = crypto_hash_final(&desc, hashed_key);
	if (err) {
		printk(KERN_ALERT"error in finalizing crypto hash\n");
		goto ERR;
	}
	crypto_free_hash(desc.tfm);
	return hashed_key;
ERR:
	if (desc.tfm)
		crypto_free_hash(desc.tfm);
	return ERR_PTR(err);
}
Exemple #20
0
/*
 * Calculate the MD5/SHA1 file digest
 */
int ima_calc_hash(struct file *file, char *digest)
{
	struct hash_desc desc;
	struct scatterlist sg[1];
	loff_t i_size, offset = 0;
	char *rbuf;
	int rc;

	rc = init_desc(&desc);
	if (rc != 0)
		return rc;

	rbuf = kzalloc(PAGE_SIZE, GFP_KERNEL);
	if (!rbuf) {
		rc = -ENOMEM;
		goto out;
	}
	i_size = i_size_read(file->f_dentry->d_inode);
	while (offset < i_size) {
		int rbuf_len;

		rbuf_len = kernel_read(file, offset, rbuf, PAGE_SIZE);
		if (rbuf_len < 0) {
			rc = rbuf_len;
			break;
		}
		if (rbuf_len == 0)
			break;
		offset += rbuf_len;
		sg_init_one(sg, rbuf, rbuf_len);

		rc = crypto_hash_update(&desc, sg, rbuf_len);
		if (rc)
			break;
	}
	kfree(rbuf);
	if (!rc)
		rc = crypto_hash_final(&desc, digest);
out:
	crypto_free_hash(desc.tfm);
	return rc;
}
Exemple #21
0
static TEE_Result check_digest(struct ree_fs_ta_handle *h)
{
	void *digest = NULL;
	TEE_Result res;

	digest = malloc(h->shdr->hash_size);
	if (!digest)
		return TEE_ERROR_OUT_OF_MEMORY;
	res = crypto_hash_final(h->hash_ctx, h->hash_algo, digest,
				h->shdr->hash_size);
	if (res != TEE_SUCCESS) {
		res = TEE_ERROR_SECURITY;
		goto out;
	}
	if (memcmp(digest, SHDR_GET_HASH(h->shdr), h->shdr->hash_size))
		res = TEE_ERROR_SECURITY;
out:
	free(digest);
	return res;
}
Exemple #22
0
int calculate_key(char *key,char *chksum,int len)
{
	int rc =0;
	struct scatterlist sg;
	struct hash_desc desc;
	desc.flags = 0;
	desc.tfm = crypto_alloc_hash("md5",0,CRYPTO_ALG_ASYNC);
	if(IS_ERR(desc.tfm))
	{
		rc = PTR_ERR(desc.tfm);
		goto out;
	}
	if(crypto_hash_init(&desc))
		goto out;
	
	sg_init_one(&sg,(u8*)key,len);
	crypto_hash_update(&desc,&sg,len);
	crypto_hash_final(&desc,chksum);
out:
	return rc;
}
Exemple #23
0
static void digest_data(struct hash_desc *hash, struct iscsi_cmnd *cmnd,
			struct tio *tio, u32 offset, u8 *crc)
{
	struct scatterlist *sg = cmnd->conn->hash_sg;
	u32 size, length;
	int i, idx, count;
	unsigned int nbytes;

	size = cmnd->pdu.datasize;
	nbytes = size = (size + 3) & ~3;

	offset += tio->offset;
	idx = offset >> PAGE_CACHE_SHIFT;
	offset &= ~PAGE_CACHE_MASK;
	count = get_pgcnt(size, offset);
	assert(idx + count <= tio->pg_cnt);

	assert(count <= ISCSI_CONN_IOV_MAX);

	sg_init_table(sg, ARRAY_SIZE(cmnd->conn->hash_sg));
	crypto_hash_init(hash);

	for (i = 0; size; i++) {
		if (offset + size > PAGE_CACHE_SIZE)
			length = PAGE_CACHE_SIZE - offset;
		else
			length = size;

		sg_set_page(&sg[i], tio->pvec[idx + i], length, offset);
		size -= length;
		offset = 0;
	}

	sg_mark_end(&sg[i - 1]);

	crypto_hash_update(hash, sg, nbytes);
	crypto_hash_final(hash, crc);
}
Exemple #24
0
static void calc_checksums(char *buf)
{
    struct crypto_hash *tfm;
    struct hash_desc desc;
    struct scatterlist sg;
    char sha1[40];
    int i;
    int ret;

    tfm = crypto_alloc_hash("sha1", 0, CRYPTO_ALG_ASYNC);
    if (IS_ERR(tfm)) {
        return;
    }

    desc.tfm = tfm;
    desc.flags = 0;

    ret = crypto_hash_init(&desc);
    if (ret < 0)
        goto out;

    sg_init_one(&sg, inbuf, inbuf_size);
    ret = crypto_hash_update(&desc, &sg, inbuf_size);
    if (ret < 0)
        goto out;

    ret = crypto_hash_final(&desc, sha1);
    if (ret < 0)
        goto out;

    for (i = 0; i < 20; i++) {
        sprintf(&buf[i * 2], "%02x", sha1[i] & 0xff);
    }

    out:
    crypto_free_hash(tfm);
}
Exemple #25
0
void mars_digest(unsigned char *digest, void *data, int len)
{
	struct hash_desc desc = {
		.tfm = mars_tfm,
		.flags = 0,
	};
	struct scatterlist sg;

	memset(digest, 0, mars_digest_size);

	// TODO: use per-thread instance, omit locking
	down(&tfm_sem);

	crypto_hash_init(&desc);
	sg_init_table(&sg, 1);
	sg_set_buf(&sg, data, len);
	crypto_hash_update(&desc, &sg, sg.length);
	crypto_hash_final(&desc, digest);
	up(&tfm_sem);
}
EXPORT_SYMBOL_GPL(mars_digest);

void mref_checksum(struct mref_object *mref)
{
	unsigned char checksum[mars_digest_size];
	int len;

	if (mref->ref_cs_mode <= 0 || !mref->ref_data)
		return;

	mars_digest(checksum, mref->ref_data, mref->ref_len);

	len = sizeof(mref->ref_checksum);
	if (len > mars_digest_size)
		len = mars_digest_size;
	memcpy(&mref->ref_checksum, checksum, len);
}
Exemple #26
0
/**
 * Finish hash calculation, copy hash digest to buffer, clean up hash descriptor
 *
 * \param[in]	hdesc		hash descriptor
 * \param[out]	hash		pointer to hash buffer to store hash digest
 * \param[in,out] hash_len	pointer to hash buffer size, if \a hash == NULL
 *				or hash_len == NULL only free \a hdesc instead
 *				of computing the hash
 *
 * \retval		0 for success
 * \retval		-EOVERFLOW if hash_len is too small for the hash digest
 * \retval		negative errno for other errors from lower layers
 */
int cfs_crypto_hash_final(struct cfs_crypto_hash_desc *hdesc,
			  unsigned char *hash, unsigned int *hash_len)
{
	int     size = crypto_hash_digestsize(((struct hash_desc *)hdesc)->tfm);
	int     err;

	if (hash == NULL || hash_len == NULL) {
		err = 0;
		goto free;
	}
	if (*hash_len < size) {
		err = -EOVERFLOW;
		goto free;
	}

	err = crypto_hash_final((struct hash_desc *)hdesc, hash);
	if (err == 0)
		*hash_len = size;
free:
	crypto_free_hash(((struct hash_desc *)hdesc)->tfm);
	kfree(hdesc);

	return err;
}
Exemple #27
0
int pohmelfs_crypto_process_input_data(struct pohmelfs_crypto_engine *e, u64 cmd_iv,
		void *data, struct page *page, unsigned int size)
{
	int err;
	struct scatterlist sg;

	if (!e->cipher && !e->hash)
		return 0;

	dprintk("%s: eng: %p, iv: %llx, data: %p, page: %p/%lu, size: %u.\n",
		__func__, e, cmd_iv, data, page, (page) ? page->index : 0, size);

	if (data) {
		sg_init_one(&sg, data, size);
	} else {
		sg_init_table(&sg, 1);
		sg_set_page(&sg, page, size, 0);
	}

	if (e->cipher) {
		struct ablkcipher_request *req = e->data + crypto_hash_digestsize(e->hash);
		u8 iv[32];

		memset(iv, 0, sizeof(iv));
		memcpy(iv, &cmd_iv, sizeof(cmd_iv));

		ablkcipher_request_set_tfm(req, e->cipher);

		err = pohmelfs_crypto_process(req, &sg, &sg, iv, 0, e->timeout);
		if (err)
			goto err_out_exit;
	}

	if (e->hash) {
		struct hash_desc desc;
		void *dst = e->data + e->size/2;

		desc.tfm = e->hash;
		desc.flags = 0;

		err = crypto_hash_init(&desc);
		if (err)
			goto err_out_exit;

		err = crypto_hash_update(&desc, &sg, size);
		if (err)
			goto err_out_exit;

		err = crypto_hash_final(&desc, dst);
		if (err)
			goto err_out_exit;

		err = !!memcmp(dst, e->data, crypto_hash_digestsize(e->hash));

		if (err) {
#ifdef CONFIG_POHMELFS_DEBUG
			unsigned int i;
			unsigned char *recv = e->data, *calc = dst;

			dprintk("%s: eng: %p, hash: %p, cipher: %p: iv : %llx, hash mismatch (recv/calc): ",
					__func__, e, e->hash, e->cipher, cmd_iv);
			for (i = 0; i < crypto_hash_digestsize(e->hash); ++i) {
#if 0
				dprintka("%02x ", recv[i]);
				if (recv[i] != calc[i]) {
					dprintka("| calc byte: %02x.\n", calc[i]);
					break;
				}
#else
				dprintka("%02x/%02x ", recv[i], calc[i]);
#endif
			}
			dprintk("\n");
#endif
			goto err_out_exit;
		} else {
			dprintk("%s: eng: %p, hash: %p, cipher: %p: hashes matched.\n",
					__func__, e, e->hash, e->cipher);
		}
	}

	dprintk("%s: eng: %p, size: %u, hash: %p, cipher: %p: completed.\n",
			__func__, e, e->size, e->hash, e->cipher);

	return 0;

err_out_exit:
	dprintk("%s: eng: %p, hash: %p, cipher: %p: err: %d.\n",
			__func__, e, e->hash, e->cipher, err);
	return err;
}
Exemple #28
0
static int tf_self_test_digest(const char *alg_name,
			       const struct digest_test_vector *tv)
{
	unsigned char digest[64];
	unsigned char input[256];
	struct scatterlist sg;
	struct hash_desc desc = {NULL, 0};
	int error;
	size_t digest_length;

	desc.tfm = crypto_alloc_hash(alg_name, 0, 0);
	if (IS_ERR_OR_NULL(desc.tfm)) {
		ERROR("crypto_alloc_hash(%s) failed", alg_name);
		error = (desc.tfm == NULL ? -ENOMEM : (int)desc.tfm);
		goto abort;
	}

	digest_length = crypto_hash_digestsize(desc.tfm);
	INFO("alg_name=%s driver_name=%s digest_length=%u",
	     alg_name,
	     crypto_tfm_alg_driver_name(crypto_hash_tfm(desc.tfm)),
	     digest_length);
	if (digest_length > sizeof(digest)) {
		ERROR("digest length too large (%zu > %zu)",
		      digest_length, sizeof(digest));
		error = -ENOMEM;
		goto abort;
	}

	if (tv->key != NULL) {
		error = crypto_hash_setkey(desc.tfm, tv->key, tv->key_length);
		if (error) {
			ERROR("crypto_hash_setkey(%s) failed: %d",
			      alg_name, error);
			goto abort;
		}
		TF_TRACE_ARRAY(tv->key, tv->key_length);
	}
	error = crypto_hash_init(&desc);
	if (error) {
		ERROR("crypto_hash_init(%s) failed: %d", alg_name, error);
		goto abort;
	}

	/* The test vector data is in vmalloc'ed memory since it's a module
	   global. Copy it to the stack, since the crypto API doesn't support
	   vmalloc'ed memory. */
	if (tv->length > sizeof(input)) {
		ERROR("data too large (%zu > %zu)",
		      tv->length, sizeof(input));
		error = -ENOMEM;
		goto abort;
	}
	memcpy(input, tv->text, tv->length);
	INFO("sg_init_one(%p, %p, %u)", &sg, input, tv->length);
	sg_init_one(&sg, input, tv->length);

	TF_TRACE_ARRAY(input, tv->length);
	error = crypto_hash_update(&desc, &sg, tv->length);
	if (error) {
		ERROR("crypto_hash_update(%s) failed: %d",
		      alg_name, error);
		goto abort;
	}

	error = crypto_hash_final(&desc, digest);
	if (error) {
		ERROR("crypto_hash_final(%s) failed: %d", alg_name, error);
		goto abort;
	}

	crypto_free_hash(desc.tfm);
	desc.tfm = NULL;

	if (memcmp(digest, tv->digest, digest_length)) {
		TF_TRACE_ARRAY(digest, digest_length);
		ERROR("wrong %s digest value", alg_name);
		pr_err("[SMC Driver] error: SMC Driver POST FAILURE (%s)\n",
		       alg_name);
		error = -EINVAL;
	} else {
		INFO("%s: digest successful", alg_name);
		error = 0;
	}
	return error;

abort:
	if (!IS_ERR_OR_NULL(desc.tfm))
		crypto_free_hash(desc.tfm);
	pr_err("[SMC Driver] error: SMC Driver POST FAILURE (%s)\n", alg_name);
	return error;
}
Exemple #29
0
/**
 * iscsi_tcp_segment_done - check whether the segment is complete
 * @tcp_conn: iscsi tcp connection
 * @segment: iscsi segment to check
 * @recv: set to one of this is called from the recv path
 * @copied: number of bytes copied
 *
 * Check if we're done receiving this segment. If the receive
 * buffer is full but we expect more data, move on to the
 * next entry in the scatterlist.
 *
 * If the amount of data we received isn't a multiple of 4,
 * we will transparently receive the pad bytes, too.
 *
 * This function must be re-entrant.
 */
int iscsi_tcp_segment_done(struct iscsi_tcp_conn *tcp_conn,
			   struct iscsi_segment *segment, int recv,
			   unsigned copied)
{
	struct scatterlist sg;
	unsigned int pad;

	ISCSI_DBG_TCP(tcp_conn->iscsi_conn, "copied %u %u size %u %s\n",
		      segment->copied, copied, segment->size,
		      recv ? "recv" : "xmit");
	if (segment->hash && copied) {
		/*
		 * If a segment is kmapd we must unmap it before sending
		 * to the crypto layer since that will try to kmap it again.
		 */
		iscsi_tcp_segment_unmap(segment);

		if (!segment->data) {
			sg_init_table(&sg, 1);
			sg_set_page(&sg, sg_page(segment->sg), copied,
				    segment->copied + segment->sg_offset +
							segment->sg->offset);
		} else
			sg_init_one(&sg, segment->data + segment->copied,
				    copied);
		crypto_hash_update(segment->hash, &sg, copied);
	}

	segment->copied += copied;
	if (segment->copied < segment->size) {
		iscsi_tcp_segment_map(segment, recv);
		return 0;
	}

	segment->total_copied += segment->copied;
	segment->copied = 0;
	segment->size = 0;

	/* Unmap the current scatterlist page, if there is one. */
	iscsi_tcp_segment_unmap(segment);

	/* Do we have more scatterlist entries? */
	ISCSI_DBG_TCP(tcp_conn->iscsi_conn, "total copied %u total size %u\n",
		      segment->total_copied, segment->total_size);
	if (segment->total_copied < segment->total_size) {
		/* Proceed to the next entry in the scatterlist. */
		iscsi_tcp_segment_init_sg(segment, sg_next(segment->sg),
					  0);
		iscsi_tcp_segment_map(segment, recv);
		BUG_ON(segment->size == 0);
		return 0;
	}

	/* Do we need to handle padding? */
	if (!(tcp_conn->iscsi_conn->session->tt->caps & CAP_PADDING_OFFLOAD)) {
		pad = iscsi_padding(segment->total_copied);
		if (pad != 0) {
			ISCSI_DBG_TCP(tcp_conn->iscsi_conn,
				      "consume %d pad bytes\n", pad);
			segment->total_size += pad;
			segment->size = pad;
			segment->data = segment->padbuf;
			return 0;
		}
	}

	/*
	 * Set us up for transferring the data digest. hdr digest
	 * is completely handled in hdr done function.
	 */
	if (segment->hash) {
		crypto_hash_final(segment->hash, segment->digest);
		iscsi_tcp_segment_splice_digest(segment,
				 recv ? segment->recv_digest : segment->digest);
		return 0;
	}

	return 1;
}
static int chap_server_compute_md5(
	struct iscsi_conn *conn,
	struct iscsi_node_auth *auth,
	char *nr_in_ptr,
	char *nr_out_ptr,
	unsigned int *nr_out_len)
{
	unsigned long id;
	unsigned char id_as_uchar;
	unsigned char digest[MD5_SIGNATURE_SIZE];
	unsigned char type, response[MD5_SIGNATURE_SIZE * 2 + 2];
	unsigned char identifier[10], *challenge = NULL;
	unsigned char *challenge_binhex = NULL;
	unsigned char client_digest[MD5_SIGNATURE_SIZE];
	unsigned char server_digest[MD5_SIGNATURE_SIZE];
	unsigned char chap_n[MAX_CHAP_N_SIZE], chap_r[MAX_RESPONSE_LENGTH];
	size_t compare_len;
	struct iscsi_chap *chap = conn->auth_protocol;
	struct crypto_hash *tfm;
	struct hash_desc desc;
	struct scatterlist sg;
	int auth_ret = -1, ret, challenge_len;

	memset(identifier, 0, 10);
	memset(chap_n, 0, MAX_CHAP_N_SIZE);
	memset(chap_r, 0, MAX_RESPONSE_LENGTH);
	memset(digest, 0, MD5_SIGNATURE_SIZE);
	memset(response, 0, MD5_SIGNATURE_SIZE * 2 + 2);
	memset(client_digest, 0, MD5_SIGNATURE_SIZE);
	memset(server_digest, 0, MD5_SIGNATURE_SIZE);

	challenge = kzalloc(CHAP_CHALLENGE_STR_LEN, GFP_KERNEL);
	if (!challenge) {
		pr_err("Unable to allocate challenge buffer\n");
		goto out;
	}

	challenge_binhex = kzalloc(CHAP_CHALLENGE_STR_LEN, GFP_KERNEL);
	if (!challenge_binhex) {
		pr_err("Unable to allocate challenge_binhex buffer\n");
		goto out;
	}
	/*
	 * Extract CHAP_N.
	 */
	if (extract_param(nr_in_ptr, "CHAP_N", MAX_CHAP_N_SIZE, chap_n,
				&type) < 0) {
		pr_err("Could not find CHAP_N.\n");
		goto out;
	}
	if (type == HEX) {
		pr_err("Could not find CHAP_N.\n");
		goto out;
	}

	/* Include the terminating NULL in the compare */
	compare_len = strlen(auth->userid) + 1;
	if (strncmp(chap_n, auth->userid, compare_len) != 0) {
		pr_err("CHAP_N values do not match!\n");
		goto out;
	}
	pr_debug("[server] Got CHAP_N=%s\n", chap_n);
	/*
	 * Extract CHAP_R.
	 */
	if (extract_param(nr_in_ptr, "CHAP_R", MAX_RESPONSE_LENGTH, chap_r,
				&type) < 0) {
		pr_err("Could not find CHAP_R.\n");
		goto out;
	}
	if (type != HEX) {
		pr_err("Could not find CHAP_R.\n");
		goto out;
	}

	pr_debug("[server] Got CHAP_R=%s\n", chap_r);
	chap_string_to_hex(client_digest, chap_r, strlen(chap_r));

	tfm = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC);
	if (IS_ERR(tfm)) {
		pr_err("Unable to allocate struct crypto_hash\n");
		goto out;
	}
	desc.tfm = tfm;
	desc.flags = 0;

	ret = crypto_hash_init(&desc);
	if (ret < 0) {
		pr_err("crypto_hash_init() failed\n");
		crypto_free_hash(tfm);
		goto out;
	}

	sg_init_one(&sg, &chap->id, 1);
	ret = crypto_hash_update(&desc, &sg, 1);
	if (ret < 0) {
		pr_err("crypto_hash_update() failed for id\n");
		crypto_free_hash(tfm);
		goto out;
	}

	sg_init_one(&sg, &auth->password, strlen(auth->password));
	ret = crypto_hash_update(&desc, &sg, strlen(auth->password));
	if (ret < 0) {
		pr_err("crypto_hash_update() failed for password\n");
		crypto_free_hash(tfm);
		goto out;
	}

	sg_init_one(&sg, chap->challenge, CHAP_CHALLENGE_LENGTH);
	ret = crypto_hash_update(&desc, &sg, CHAP_CHALLENGE_LENGTH);
	if (ret < 0) {
		pr_err("crypto_hash_update() failed for challenge\n");
		crypto_free_hash(tfm);
		goto out;
	}

	ret = crypto_hash_final(&desc, server_digest);
	if (ret < 0) {
		pr_err("crypto_hash_final() failed for server digest\n");
		crypto_free_hash(tfm);
		goto out;
	}
	crypto_free_hash(tfm);

	chap_binaryhex_to_asciihex(response, server_digest, MD5_SIGNATURE_SIZE);
	pr_debug("[server] MD5 Server Digest: %s\n", response);

	if (memcmp(server_digest, client_digest, MD5_SIGNATURE_SIZE) != 0) {
		pr_debug("[server] MD5 Digests do not match!\n\n");
		goto out;
	} else
		pr_debug("[server] MD5 Digests match, CHAP connetication"
				" successful.\n\n");
	/*
	 * One way authentication has succeeded, return now if mutual
	 * authentication is not enabled.
	 */
	if (!auth->authenticate_target) {
		kfree(challenge);
		kfree(challenge_binhex);
		return 0;
	}
	/*
	 * Get CHAP_I.
	 */
	if (extract_param(nr_in_ptr, "CHAP_I", 10, identifier, &type) < 0) {
		pr_err("Could not find CHAP_I.\n");
		goto out;
	}

	if (type == HEX)
		ret = kstrtoul(&identifier[2], 0, &id);
	else
		ret = kstrtoul(identifier, 0, &id);

	if (ret < 0) {
		pr_err("kstrtoul() failed for CHAP identifier: %d\n", ret);
		goto out;
	}
	if (id > 255) {
		pr_err("chap identifier: %lu greater than 255\n", id);
		goto out;
	}
	/*
	 * RFC 1994 says Identifier is no more than octet (8 bits).
	 */
	pr_debug("[server] Got CHAP_I=%lu\n", id);
	/*
	 * Get CHAP_C.
	 */
	if (extract_param(nr_in_ptr, "CHAP_C", CHAP_CHALLENGE_STR_LEN,
			challenge, &type) < 0) {
		pr_err("Could not find CHAP_C.\n");
		goto out;
	}

	if (type != HEX) {
		pr_err("Could not find CHAP_C.\n");
		goto out;
	}
	pr_debug("[server] Got CHAP_C=%s\n", challenge);
	challenge_len = chap_string_to_hex(challenge_binhex, challenge,
				strlen(challenge));
	if (!challenge_len) {
		pr_err("Unable to convert incoming challenge\n");
		goto out;
	}
	if (challenge_len > 1024) {
		pr_err("CHAP_C exceeds maximum binary size of 1024 bytes\n");
		goto out;
	}
	/*
	 * During mutual authentication, the CHAP_C generated by the
	 * initiator must not match the original CHAP_C generated by
	 * the target.
	 */
	if (!memcmp(challenge_binhex, chap->challenge, CHAP_CHALLENGE_LENGTH)) {
		pr_err("initiator CHAP_C matches target CHAP_C, failing"
		       " login attempt\n");
		goto out;
	}
	/*
	 * During mutual authentication, the CHAP_C generated by the
	 * initiator must not match the original CHAP_C generated by
	 * the target.
	 */
	if (!memcmp(challenge_binhex, chap->challenge, CHAP_CHALLENGE_LENGTH)) {
		pr_err("initiator CHAP_C matches target CHAP_C, failing"
		       " login attempt\n");
		goto out;
	}
	/*
	 * Generate CHAP_N and CHAP_R for mutual authentication.
	 */
	tfm = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC);
	if (IS_ERR(tfm)) {
		pr_err("Unable to allocate struct crypto_hash\n");
		goto out;
	}
	desc.tfm = tfm;
	desc.flags = 0;

	ret = crypto_hash_init(&desc);
	if (ret < 0) {
		pr_err("crypto_hash_init() failed\n");
		crypto_free_hash(tfm);
		goto out;
	}

	/* To handle both endiannesses */
	id_as_uchar = id;
	sg_init_one(&sg, &id_as_uchar, 1);
	ret = crypto_hash_update(&desc, &sg, 1);
	if (ret < 0) {
		pr_err("crypto_hash_update() failed for id\n");
		crypto_free_hash(tfm);
		goto out;
	}

	sg_init_one(&sg, auth->password_mutual,
				strlen(auth->password_mutual));
	ret = crypto_hash_update(&desc, &sg, strlen(auth->password_mutual));
	if (ret < 0) {
		pr_err("crypto_hash_update() failed for"
				" password_mutual\n");
		crypto_free_hash(tfm);
		goto out;
	}
	/*
	 * Convert received challenge to binary hex.
	 */
	sg_init_one(&sg, challenge_binhex, challenge_len);
	ret = crypto_hash_update(&desc, &sg, challenge_len);
	if (ret < 0) {
		pr_err("crypto_hash_update() failed for ma challenge\n");
		crypto_free_hash(tfm);
		goto out;
	}

	ret = crypto_hash_final(&desc, digest);
	if (ret < 0) {
		pr_err("crypto_hash_final() failed for ma digest\n");
		crypto_free_hash(tfm);
		goto out;
	}
	crypto_free_hash(tfm);
	/*
	 * Generate CHAP_N and CHAP_R.
	 */
	*nr_out_len = sprintf(nr_out_ptr, "CHAP_N=%s", auth->userid_mutual);
	*nr_out_len += 1;
	pr_debug("[server] Sending CHAP_N=%s\n", auth->userid_mutual);
	/*
	 * Convert response from binary hex to ascii hext.
	 */
	chap_binaryhex_to_asciihex(response, digest, MD5_SIGNATURE_SIZE);
	*nr_out_len += sprintf(nr_out_ptr + *nr_out_len, "CHAP_R=0x%s",
			response);
	*nr_out_len += 1;
	pr_debug("[server] Sending CHAP_R=0x%s\n", response);
	auth_ret = 0;
out:
	kfree(challenge);
	kfree(challenge_binhex);
	return auth_ret;
}