#include #include #include #include #include #include #include #include #include #if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE) #error "crypto and sha256 must be built into the kernel" #endif int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum) { struct crypto_ahash *tfm; struct ahash_request *req; struct scatterlist sg[2]; unsigned char temp_sum[GR_SHA_LEN]; unsigned long *tmpsumptr = (unsigned long *)temp_sum; unsigned long *sumptr = (unsigned long *)sum; int retval = 1; tfm = crypto_alloc_ahash("sha256", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(tfm)) goto out_wipe; sg_init_table(sg, 2); sg_set_buf(&sg[0], salt, GR_SALT_LEN); sg_set_buf(&sg[1], entry->pw, strlen((const char *)entry->pw)); req = ahash_request_alloc(tfm, GFP_KERNEL); if (!req) { crypto_free_ahash(tfm); goto out_wipe; } ahash_request_set_callback(req, 0, NULL, NULL); ahash_request_set_crypt(req, sg, temp_sum, GR_SALT_LEN + strlen((const char *)entry->pw)); if (crypto_ahash_digest(req)) goto out_free; if (!crypto_memneq(sumptr, tmpsumptr, GR_SHA_LEN)) retval = 0; out_free: ahash_request_free(req); crypto_free_ahash(tfm); out_wipe: memset(entry->pw, 0, GR_PW_LEN); return retval; }