mirror of https://github.com/OpenIPC/firmware.git
88 lines
2.0 KiB
Diff
88 lines
2.0 KiB
Diff
diff -drupN a/security/fivm/fivm_crypto.c b/security/fivm/fivm_crypto.c
|
|
--- a/security/fivm/fivm_crypto.c 1970-01-01 03:00:00.000000000 +0300
|
|
+++ b/security/fivm/fivm_crypto.c 2022-06-12 05:28:14.000000000 +0300
|
|
@@ -0,0 +1,83 @@
|
|
+/*
|
|
+ * Copyright (C) 2014 Allwinner Ltd.
|
|
+ *
|
|
+ * Author:
|
|
+ * Ryan Chen <ryanchen@allwinnertech.com>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or
|
|
+ * modify it under the terms of the GNU General Public License as
|
|
+ * published by the Free Software Foundation, version 2 of the
|
|
+ * License.
|
|
+ *
|
|
+ * File: fivm_crypto.c
|
|
+ */
|
|
+
|
|
+#include <linux/kernel.h>
|
|
+#include <linux/file.h>
|
|
+#include <linux/crypto.h>
|
|
+#include <linux/scatterlist.h>
|
|
+#include <linux/err.h>
|
|
+#include <linux/slab.h>
|
|
+#include <linux/fs.h>
|
|
+#include "fivm.h"
|
|
+
|
|
+static char *fivm_hash = "sha256";
|
|
+static int init_desc(struct hash_desc *desc)
|
|
+{
|
|
+ int rc;
|
|
+
|
|
+ desc->tfm = crypto_alloc_hash(fivm_hash, 0, CRYPTO_ALG_ASYNC);
|
|
+ if (IS_ERR(desc->tfm)) {
|
|
+ pr_info("FIVM: failed to load %s transform: %ld\n",
|
|
+ fivm_hash, PTR_ERR(desc->tfm));
|
|
+ rc = PTR_ERR(desc->tfm);
|
|
+ return rc;
|
|
+ }
|
|
+ desc->flags = 0;
|
|
+ rc = crypto_hash_init(desc);
|
|
+ if (rc)
|
|
+ crypto_free_hash(desc->tfm);
|
|
+ return rc;
|
|
+}
|
|
+
|
|
+int fivm_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_path.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;
|
|
+}
|