blob: 421e448077b3d19f446e8de413c1f65160fbb1c6 [file] [log] [blame]
/*
* MNH Firmware for firmware authentication
*
* Copyright 2017 Google Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#include <linux/device.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/string.h>
#include "mnh-crypto.h"
#define MISC_DEVICE_NAME "mnh_crypto"
static ssize_t verify_img_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count);
static void mnh_crypto_decode_error(struct device *dev, int err);
/* Device attributes */
DEVICE_ATTR_WO(verify_img);
static struct attribute *mnh_crypto_attrs[] = {
&dev_attr_verify_img.attr,
NULL
};
ATTRIBUTE_GROUPS(mnh_crypto);
static struct miscdevice mnh_crypto_miscdevice = {
.minor = MISC_DYNAMIC_MINOR,
.name = MISC_DEVICE_NAME,
.groups = mnh_crypto_groups,
};
/* echo -n "easel/Image">verify_img */
static ssize_t verify_img_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
int err;
err = mnh_crypto_verify_fw(dev, buf);
if (!err) {
dev_info(dev, "%s: Signature verfied OK\n", __func__);
return count;
}
mnh_crypto_decode_error(dev, err);
return err;
}
/* create sysfs group */
int mnh_crypto_config_sysfs(void)
{
int err;
struct device *dev;
err = misc_register(&mnh_crypto_miscdevice);
if (err) {
pr_err("%s: failed to create misc device (%d)\n",
__func__, err);
return err;
}
dev = mnh_crypto_miscdevice.this_device;
return 0;
}
EXPORT_SYMBOL_GPL(mnh_crypto_config_sysfs);
static void mnh_crypto_decode_error(struct device *dev, int err)
{
/* Decode return code information */
if (err == -ENOKEY)
dev_err(dev, "%s: Required key not available\n", __func__);
else if (err == -EKEYEXPIRED)
dev_err(dev, "%s: Key has expired\n", __func__);
else if (err == -EKEYREVOKED)
dev_err(dev, "%s: Key has been revoked\n", __func__);
else if (err == -EKEYREJECTED)
dev_err(dev, "%s: Key was rejected by service\n", __func__);
else if (err == -ENOMEM)
dev_err(dev, "%s: Out of memory\n", __func__);
else if (err == -ECANCELED)
dev_err(dev, "%s: Operation canceled\n", __func__);
else
dev_err(dev, "%s: Unknown error code %d\n", __func__, err);
}