[PATCH 7/9 v2] crypto: atmel-ecc: Print out serial number

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This reads out the serial number of the crypto chip and prints it,
also toss this into the entropy pool as it is device-unique data.

Signed-off-by: Linus Walleij <linus.walleij@xxxxxxxxxx>
---
ChangeLog v1->v2:
- kfree(cmd) was missed. Fix it with a goto construction.
- Coding style fixes.
---
 drivers/crypto/atmel-ecc.c | 60 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/drivers/crypto/atmel-ecc.c b/drivers/crypto/atmel-ecc.c
index f3322fae454e..659cb3cf37a9 100644
--- a/drivers/crypto/atmel-ecc.c
+++ b/drivers/crypto/atmel-ecc.c
@@ -26,6 +26,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
+#include <linux/random.h>
 #include <linux/scatterlist.h>
 #include <linux/slab.h>
 #include <linux/workqueue.h>
@@ -610,6 +611,61 @@ static inline size_t atmel_ecc_wake_token_sz(u32 bus_clk_rate)
 	return DIV_ROUND_UP(no_of_bits, 8);
 }
 
+static int atmel_ecc_get_serial(struct i2c_client *client)
+{
+	struct atmel_ecc_cmd *cmd;
+	int ret;
+	int i;
+	u8 serial[9];
+
+	cmd = kmalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+
+	atmel_ecc_init_read_config_word(cmd, CONFIG_ZONE_SERIAL_0_3);
+	ret = atmel_ecc_send_receive(client, cmd);
+	if (ret) {
+		dev_err(&client->dev,
+			"failed to read serial byte 0-3\n");
+		goto out_free_cmd;
+	}
+	for (i = 0; i < 4; i++)
+		serial[i] = cmd->data[RSP_DATA_IDX + i];
+
+	atmel_ecc_init_read_config_word(cmd, CONFIG_ZONE_SERIAL_4_7);
+	ret = atmel_ecc_send_receive(client, cmd);
+	if (ret) {
+		dev_err(&client->dev,
+			"failed to read serial byte 4-7\n");
+		goto out_free_cmd;
+	}
+	for (i = 0; i < 4; i++)
+		serial[4 + i] = cmd->data[RSP_DATA_IDX + i];
+
+
+	atmel_ecc_init_read_config_word(cmd, CONFIG_ZONE_SERIAL_8_I2CEN);
+	ret = atmel_ecc_send_receive(client, cmd);
+	if (ret) {
+		kfree(cmd);
+		dev_err(&client->dev,
+			"failed to read serial byte 8\n");
+		goto out_free_cmd;
+	}
+	serial[8] = cmd->data[RSP_DATA_IDX];
+
+	/* This is device-unique data so it goes into the entropy pool */
+	add_device_randomness(serial, sizeof(serial));
+
+	dev_info(&client->dev,
+		 "serial number: %02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
+		 serial[0], serial[1], serial[2], serial[3], serial[4],
+		 serial[5], serial[6], serial[7], serial[8]);
+
+out_free_cmd:
+	kfree(cmd);
+	return ret;
+}
+
 static int device_sanity_check(struct i2c_client *client)
 {
 	struct atmel_ecc_cmd *cmd;
@@ -692,6 +748,10 @@ static int atmel_ecc_probe(struct i2c_client *client,
 	if (ret)
 		return ret;
 
+	ret = atmel_ecc_get_serial(client);
+	if (ret)
+		return ret;
+
 	spin_lock(&driver_data.i2c_list_lock);
 	list_add_tail(&i2c_priv->i2c_client_list_node,
 		      &driver_data.i2c_client_list);
-- 
2.17.0




[Index of Archives]     [Kernel]     [Gnu Classpath]     [Gnu Crypto]     [DM Crypt]     [Netfilter]     [Bugtraq]

  Powered by Linux