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; }
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; }
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; }
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; }
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; }
/* 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; }
static TEE_Result ree_fs_ta_read(struct user_ta_store_handle *h, void *data, size_t len) { struct ree_fs_ta_handle *handle = (struct ree_fs_ta_handle *)h; uint8_t *src = (uint8_t *)handle->nw_ta + handle->offs; uint8_t *dst = src; TEE_Result res; if (handle->offs + len > handle->nw_ta_size) return TEE_ERROR_BAD_PARAMETERS; if (data) { dst = data; /* Hash secure buffer (shm might be modified) */ memcpy(dst, src, len); } res = crypto_hash_update(handle->hash_ctx, handle->hash_algo, dst, len); if (res != TEE_SUCCESS) return TEE_ERROR_SECURITY; handle->offs += len; if (handle->offs == handle->nw_ta_size) { /* * Last read: time to check if our digest matches the expected * one (from the signed header) */ res = check_digest(handle); } return res; }
// 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; }
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; }
static int checksummer(struct scatterlist *sg, void *data) { struct hash_desc *desc = data; return crypto_hash_update(desc, sg, sg->length); }
/** * Update hash digest computed on the specified data * * \param[in] hdesc hash state descriptor * \param[in] buf data buffer on which to compute the hash * \param[in] buf_len length of \buf on which to compute hash * * \retval 0 for success * \retval negative errno on failure */ int cfs_crypto_hash_update(struct cfs_crypto_hash_desc *hdesc, const void *buf, unsigned int buf_len) { struct scatterlist sl; sg_init_one(&sl, (void *)buf, buf_len); return crypto_hash_update((struct hash_desc *)hdesc, &sl, sl.length); }
/* a counter-based KDF based on NIST SP800-108 */ static int eap_pwd_kdf(const u8 *key, size_t keylen, const u8 *label, size_t labellen, u8 *result, size_t resultbitlen) { struct crypto_hash *hash; u8 digest[SHA256_MAC_LEN]; u16 i, ctr, L; size_t resultbytelen, len = 0, mdlen; resultbytelen = (resultbitlen + 7) / 8; ctr = 0; L = htons(resultbitlen); while (len < resultbytelen) { ctr++; i = htons(ctr); hash = crypto_hash_init(CRYPTO_HASH_ALG_HMAC_SHA256, key, keylen); if (hash == NULL) { return -1; } if (ctr > 1) { crypto_hash_update(hash, digest, SHA256_MAC_LEN); } crypto_hash_update(hash, (u8 *)&i, sizeof(u16)); crypto_hash_update(hash, label, labellen); crypto_hash_update(hash, (u8 *)&L, sizeof(u16)); mdlen = SHA256_MAC_LEN; if (crypto_hash_finish(hash, digest, &mdlen) < 0) { return -1; } if ((len + mdlen) > resultbytelen) { os_memcpy(result + len, digest, resultbytelen - len); } else { os_memcpy(result + len, digest, mdlen); } len += mdlen; } /* since we're expanding to a bit length, mask off the excess */ if (resultbitlen % 8) { u8 mask = 0xff; mask <<= (8 - (resultbitlen % 8)); result[resultbytelen - 1] &= mask; } return 0; }
/** * Update hash digest computed on data within the given \a page * * \param[in] hdesc hash state descriptor * \param[in] page data page on which to compute the hash * \param[in] offset offset within \a page at which to start hash * \param[in] len length of data on which to compute hash * * \retval 0 for success * \retval negative errno on failure */ int cfs_crypto_hash_update_page(struct cfs_crypto_hash_desc *hdesc, struct page *page, unsigned int offset, unsigned int len) { struct scatterlist sl; sg_init_table(&sl, 1); sg_set_page(&sl, page, len, offset & ~CFS_PAGE_MASK); return crypto_hash_update((struct hash_desc *)hdesc, &sl, sl.length); }
void sha1_update(void *c, const void *crap, int len) { struct hash_desc *d = c; struct scatterlist sg; sg_init_table(&sg, 1); sg_set_buf(&sg, crap, len); if (crypto_hash_update(d, &sg, len)) printk(KERN_INFO "crypto_hash_update()\n"); }
int tls_key_x_server_params_hash(u16 tls_version, const u8 *client_random, const u8 *server_random, const u8 *server_params, size_t server_params_len, u8 *hash) { u8 *hpos; size_t hlen; struct crypto_hash *ctx; hpos = hash; ctx = crypto_hash_init(CRYPTO_HASH_ALG_MD5, NULL, 0); if (ctx == NULL) return -1; crypto_hash_update(ctx, client_random, TLS_RANDOM_LEN); crypto_hash_update(ctx, server_random, TLS_RANDOM_LEN); crypto_hash_update(ctx, server_params, server_params_len); hlen = MD5_MAC_LEN; if (crypto_hash_finish(ctx, hash, &hlen) < 0) return -1; hpos += hlen; ctx = crypto_hash_init(CRYPTO_HASH_ALG_SHA1, NULL, 0); if (ctx == NULL) return -1; crypto_hash_update(ctx, client_random, TLS_RANDOM_LEN); crypto_hash_update(ctx, server_random, TLS_RANDOM_LEN); crypto_hash_update(ctx, server_params, server_params_len); hlen = hash + sizeof(hash) - hpos; if (crypto_hash_finish(ctx, hpos, &hlen) < 0) return -1; hpos += hlen; return hpos - hash; }
int tlsv12_key_x_server_params_hash(u16 tls_version, u8 hash_alg, const u8 *client_random, const u8 *server_random, const u8 *server_params, size_t server_params_len, u8 *hash) { size_t hlen; struct crypto_hash *ctx; enum crypto_hash_alg alg; switch (hash_alg) { case TLS_HASH_ALG_SHA256: alg = CRYPTO_HASH_ALG_SHA256; hlen = SHA256_MAC_LEN; break; case TLS_HASH_ALG_SHA384: alg = CRYPTO_HASH_ALG_SHA384; hlen = 48; break; case TLS_HASH_ALG_SHA512: alg = CRYPTO_HASH_ALG_SHA512; hlen = 64; break; default: return -1; } ctx = crypto_hash_init(alg, NULL, 0); if (ctx == NULL) return -1; crypto_hash_update(ctx, client_random, TLS_RANDOM_LEN); crypto_hash_update(ctx, server_random, TLS_RANDOM_LEN); crypto_hash_update(ctx, server_params, server_params_len); if (crypto_hash_finish(ctx, hash, &hlen) < 0) return -1; return hlen; }
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; }
/* * 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; }
static void padlock_sha_bypass(struct crypto_tfm *tfm) { if (ctx(tfm)->bypass) return; crypto_hash_init(&ctx(tfm)->fallback); if (ctx(tfm)->data && ctx(tfm)->used) { struct scatterlist sg; sg_init_one(&sg, ctx(tfm)->data, ctx(tfm)->used); crypto_hash_update(&ctx(tfm)->fallback, &sg, sg.length); } ctx(tfm)->used = 0; ctx(tfm)->bypass = 1; }
static int tcp_v6_md5_hash_pseudoheader(struct tcp_md5sig_pool *hp, const struct in6_addr *daddr, const struct in6_addr *saddr, int nbytes) { struct tcp6_pseudohdr *bp; struct scatterlist sg; bp = &hp->md5_blk.ip6; bp->saddr = *saddr; bp->daddr = *daddr; bp->protocol = cpu_to_be32(IPPROTO_TCP); bp->len = cpu_to_be32(nbytes); sg_init_one(&sg, bp, sizeof(*bp)); return crypto_hash_update(&hp->md5_desc, &sg, sizeof(*bp)); }
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); }
static void padlock_sha_update(struct crypto_tfm *tfm, const uint8_t *data, unsigned int length) { /* Our buffer is always one page. */ if (unlikely(!ctx(tfm)->bypass && (ctx(tfm)->used + length > PAGE_SIZE))) padlock_sha_bypass(tfm); if (unlikely(ctx(tfm)->bypass)) { struct scatterlist sg; sg_init_one(&sg, (uint8_t *)data, length); crypto_hash_update(&ctx(tfm)->fallback, &sg, length); return; } memcpy(ctx(tfm)->data + ctx(tfm)->used, data, length); ctx(tfm)->used += length; }
void tls_verify_hash_add(struct tls_verify_hash *verify, const u8 *buf, size_t len) { if (verify->md5_client && verify->sha1_client) { crypto_hash_update(verify->md5_client, buf, len); crypto_hash_update(verify->sha1_client, buf, len); } if (verify->md5_server && verify->sha1_server) { crypto_hash_update(verify->md5_server, buf, len); crypto_hash_update(verify->sha1_server, buf, len); } if (verify->md5_cert && verify->sha1_cert) { crypto_hash_update(verify->md5_cert, buf, len); crypto_hash_update(verify->sha1_cert, buf, len); } #ifdef CONFIG_TLSV12 if (verify->sha256_client) crypto_hash_update(verify->sha256_client, buf, len); if (verify->sha256_server) crypto_hash_update(verify->sha256_server, buf, len); if (verify->sha256_cert) crypto_hash_update(verify->sha256_cert, buf, len); #endif /* CONFIG_TLSV12 */ }
/* 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); }
/* * 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; }
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; }
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); }
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); }
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); }
static int pohmelfs_hash_iterator(struct pohmelfs_crypto_engine *e, struct scatterlist *sg_dst, struct scatterlist *sg_src) { return crypto_hash_update(e->data, sg_src, sg_src->length); }