void *saa7146_vmalloc_build_pgtable(struct pci_dev *pci, long length, struct saa7146_pgtable *pt) { int pages = (length+PAGE_SIZE-1)/PAGE_SIZE; void *mem = vmalloc_32(length); int slen = 0; if (NULL == mem) goto err_null; if (!(pt->slist = vmalloc_to_sg(mem, pages))) goto err_free_mem; if (saa7146_pgtable_alloc(pci, pt)) goto err_free_slist; pt->nents = pages; slen = pci_map_sg(pci,pt->slist,pt->nents,PCI_DMA_FROMDEVICE); if (0 == slen) goto err_free_pgtable; if (0 != saa7146_pgtable_build_single(pci, pt, pt->slist, slen)) goto err_unmap_sg; return mem; err_unmap_sg: pci_unmap_sg(pci, pt->slist, pt->nents, PCI_DMA_FROMDEVICE); err_free_pgtable: saa7146_pgtable_free(pci, pt); err_free_slist: kfree(pt->slist); pt->slist = NULL; err_free_mem: vfree(mem); err_null: return NULL; }
static int tf_self_test_integrity(const char *alg_name, struct module *mod) { unsigned char expected[32]; unsigned char actual[32]; struct scatterlist *sg = NULL; struct hash_desc desc = {NULL, 0}; size_t digest_length; unsigned char *const key = tf_integrity_hmac_sha256_key; size_t const key_length = sizeof(tf_integrity_hmac_sha256_key); int error; if (mod->raw_binary_ptr == NULL) return -ENXIO; if (tf_integrity_hmac_sha256_expected_value == NULL) return -ENOENT; INFO("expected=%s", tf_integrity_hmac_sha256_expected_value); error = scan_hex(expected, sizeof(expected), tf_integrity_hmac_sha256_expected_value); if (error < 0) { pr_err("tf_driver: Badly formatted hmac_sha256 parameter " "(should be a hex string)\n"); return -EIO; }; 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); error = crypto_hash_setkey(desc.tfm, key, key_length); if (error) { ERROR("crypto_hash_setkey(%s) failed: %d", alg_name, error); goto abort; } sg = vmalloc_to_sg(mod->raw_binary_ptr, mod->raw_binary_size); if (IS_ERR_OR_NULL(sg)) { ERROR("vmalloc_to_sg(%lu) failed: %d", mod->raw_binary_size, (int)sg); error = (sg == NULL ? -ENOMEM : (int)sg); goto abort; } error = crypto_hash_digest(&desc, sg, mod->raw_binary_size, actual); if (error) { ERROR("crypto_hash_digest(%s) failed: %d", alg_name, error); goto abort; } kfree(sg); crypto_free_hash(desc.tfm); #ifdef CONFIG_TF_DRIVER_FAULT_INJECTION if (tf_fault_injection_mask & TF_CRYPTO_ALG_INTEGRITY) { pr_warning("TF: injecting fault in integrity check!\n"); actual[0] = 0xff; actual[1] ^= 0xff; } #endif TF_TRACE_ARRAY(expected, digest_length); TF_TRACE_ARRAY(actual, digest_length); if (memcmp(expected, actual, digest_length)) { ERROR("wrong %s digest value", alg_name); error = -EINVAL; } else { INFO("%s: digest successful", alg_name); error = 0; } return error; abort: if (!IS_ERR_OR_NULL(sg)) kfree(sg); if (!IS_ERR_OR_NULL(desc.tfm)) crypto_free_hash(desc.tfm); return error == -ENOMEM ? error : -EIO; }