Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

crypto: atmel-ecc - introduce Microchip / Atmel ECC driver

Add ECDH support for ATECC508A (I2C) device.

The device features hardware acceleration for the NIST standard
P256 prime curve and supports the complete key life cycle from
private key generation to ECDH key agreement.

Random private key generation is supported internally within
the device to ensure that the private key can never be known
outside of the device. If the user wants to use its own private
keys, the driver will fallback to the ecdh software implementation.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Tudor-Dan Ambarus and committed by
Herbert Xu
11105693 66d3994c

+937
+13
Documentation/devicetree/bindings/crypto/atmel-crypto.txt
··· 66 66 dmas = <&dma1 2 17>; 67 67 dma-names = "tx"; 68 68 }; 69 + 70 + * Eliptic Curve Cryptography (I2C) 71 + 72 + Required properties: 73 + - compatible : must be "atmel,atecc508a". 74 + - reg: I2C bus address of the device. 75 + - clock-frequency: must be present in the i2c controller node. 76 + 77 + Example: 78 + atecc508a@C0 { 79 + compatible = "atmel,atecc508a"; 80 + reg = <0xC0>; 81 + };
+14
drivers/crypto/Kconfig
··· 525 525 To compile this driver as a module, choose M here: the module 526 526 will be called atmel-sha. 527 527 528 + config CRYPTO_DEV_ATMEL_ECC 529 + tristate "Support for Microchip / Atmel ECC hw accelerator" 530 + depends on ARCH_AT91 || COMPILE_TEST 531 + depends on I2C 532 + select CRYPTO_ECDH 533 + select CRC16 534 + help 535 + Microhip / Atmel ECC hw accelerator. 536 + Select this if you want to use the Microchip / Atmel module for 537 + ECDH algorithm. 538 + 539 + To compile this driver as a module, choose M here: the module 540 + will be called atmel-ecc. 541 + 528 542 config CRYPTO_DEV_CCP 529 543 bool "Support for AMD Cryptographic Coprocessor" 530 544 depends on ((X86 && PCI) || (ARM64 && (OF_ADDRESS || ACPI))) && HAS_IOMEM
+1
drivers/crypto/Makefile
··· 1 1 obj-$(CONFIG_CRYPTO_DEV_ATMEL_AES) += atmel-aes.o 2 2 obj-$(CONFIG_CRYPTO_DEV_ATMEL_SHA) += atmel-sha.o 3 3 obj-$(CONFIG_CRYPTO_DEV_ATMEL_TDES) += atmel-tdes.o 4 + obj-$(CONFIG_CRYPTO_DEV_ATMEL_ECC) += atmel-ecc.o 4 5 obj-$(CONFIG_CRYPTO_DEV_BFIN_CRC) += bfin_crc.o 5 6 obj-$(CONFIG_CRYPTO_DEV_CAVIUM_ZIP) += cavium/ 6 7 obj-$(CONFIG_CRYPTO_DEV_CCP) += ccp/
+781
drivers/crypto/atmel-ecc.c
··· 1 + /* 2 + * Microchip / Atmel ECC (I2C) driver. 3 + * 4 + * Copyright (c) 2017, Microchip Technology Inc. 5 + * Author: Tudor Ambarus <tudor.ambarus@microchip.com> 6 + * 7 + * This software is licensed under the terms of the GNU General Public 8 + * License version 2, as published by the Free Software Foundation, and 9 + * may be copied, distributed, and modified under those terms. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + */ 17 + 18 + #include <linux/bitrev.h> 19 + #include <linux/crc16.h> 20 + #include <linux/delay.h> 21 + #include <linux/device.h> 22 + #include <linux/err.h> 23 + #include <linux/errno.h> 24 + #include <linux/i2c.h> 25 + #include <linux/init.h> 26 + #include <linux/kernel.h> 27 + #include <linux/module.h> 28 + #include <linux/of_device.h> 29 + #include <linux/scatterlist.h> 30 + #include <linux/slab.h> 31 + #include <linux/workqueue.h> 32 + #include <crypto/internal/kpp.h> 33 + #include <crypto/ecdh.h> 34 + #include <crypto/kpp.h> 35 + #include "atmel-ecc.h" 36 + 37 + /* Used for binding tfm objects to i2c clients. */ 38 + struct atmel_ecc_driver_data { 39 + struct list_head i2c_client_list; 40 + spinlock_t i2c_list_lock; 41 + } ____cacheline_aligned; 42 + 43 + static struct atmel_ecc_driver_data driver_data; 44 + 45 + /** 46 + * atmel_ecc_i2c_client_priv - i2c_client private data 47 + * @client : pointer to i2c client device 48 + * @i2c_client_list_node: part of i2c_client_list 49 + * @lock : lock for sending i2c commands 50 + * @wake_token : wake token array of zeros 51 + * @wake_token_sz : size in bytes of the wake_token 52 + * @tfm_count : number of active crypto transformations on i2c client 53 + * 54 + * Reads and writes from/to the i2c client are sequential. The first byte 55 + * transmitted to the device is treated as the byte size. Any attempt to send 56 + * more than this number of bytes will cause the device to not ACK those bytes. 57 + * After the host writes a single command byte to the input buffer, reads are 58 + * prohibited until after the device completes command execution. Use a mutex 59 + * when sending i2c commands. 60 + */ 61 + struct atmel_ecc_i2c_client_priv { 62 + struct i2c_client *client; 63 + struct list_head i2c_client_list_node; 64 + struct mutex lock; 65 + u8 wake_token[WAKE_TOKEN_MAX_SIZE]; 66 + size_t wake_token_sz; 67 + atomic_t tfm_count ____cacheline_aligned; 68 + }; 69 + 70 + /** 71 + * atmel_ecdh_ctx - transformation context 72 + * @client : pointer to i2c client device 73 + * @fallback : used for unsupported curves or when user wants to use its own 74 + * private key. 75 + * @public_key : generated when calling set_secret(). It's the responsibility 76 + * of the user to not call set_secret() while 77 + * generate_public_key() or compute_shared_secret() are in flight. 78 + * @curve_id : elliptic curve id 79 + * @n_sz : size in bytes of the n prime 80 + * @do_fallback: true when the device doesn't support the curve or when the user 81 + * wants to use its own private key. 82 + */ 83 + struct atmel_ecdh_ctx { 84 + struct i2c_client *client; 85 + struct crypto_kpp *fallback; 86 + const u8 *public_key; 87 + unsigned int curve_id; 88 + size_t n_sz; 89 + bool do_fallback; 90 + }; 91 + 92 + /** 93 + * atmel_ecc_work_data - data structure representing the work 94 + * @ctx : transformation context. 95 + * @cbk : pointer to a callback function to be invoked upon completion of this 96 + * request. This has the form: 97 + * callback(struct atmel_ecc_work_data *work_data, void *areq, u8 status) 98 + * where: 99 + * @work_data: data structure representing the work 100 + * @areq : optional pointer to an argument passed with the original 101 + * request. 102 + * @status : status returned from the device. 103 + * @areq: optional pointer to a user argument for use at callback time. 104 + * @work: describes the task to be executed. 105 + * @cmd : structure used for communicating with the device. 106 + */ 107 + struct atmel_ecc_work_data { 108 + struct atmel_ecdh_ctx *ctx; 109 + void (*cbk)(struct atmel_ecc_work_data *work_data, void *areq, 110 + u8 status); 111 + void *areq; 112 + struct work_struct work; 113 + struct atmel_ecc_cmd cmd; 114 + }; 115 + 116 + static u16 atmel_ecc_crc16(u16 crc, const u8 *buffer, size_t len) 117 + { 118 + return cpu_to_le16(bitrev16(crc16(crc, buffer, len))); 119 + } 120 + 121 + /** 122 + * atmel_ecc_checksum() - Generate 16-bit CRC as required by ATMEL ECC. 123 + * CRC16 verification of the count, opcode, param1, param2 and data bytes. 124 + * The checksum is saved in little-endian format in the least significant 125 + * two bytes of the command. CRC polynomial is 0x8005 and the initial register 126 + * value should be zero. 127 + * 128 + * @cmd : structure used for communicating with the device. 129 + */ 130 + static void atmel_ecc_checksum(struct atmel_ecc_cmd *cmd) 131 + { 132 + u8 *data = &cmd->count; 133 + size_t len = cmd->count - CRC_SIZE; 134 + u16 *crc16 = (u16 *)(data + len); 135 + 136 + *crc16 = atmel_ecc_crc16(0, data, len); 137 + } 138 + 139 + static void atmel_ecc_init_read_cmd(struct atmel_ecc_cmd *cmd) 140 + { 141 + cmd->word_addr = COMMAND; 142 + cmd->opcode = OPCODE_READ; 143 + /* 144 + * Read the word from Configuration zone that contains the lock bytes 145 + * (UserExtra, Selector, LockValue, LockConfig). 146 + */ 147 + cmd->param1 = CONFIG_ZONE; 148 + cmd->param2 = DEVICE_LOCK_ADDR; 149 + cmd->count = READ_COUNT; 150 + 151 + atmel_ecc_checksum(cmd); 152 + 153 + cmd->msecs = MAX_EXEC_TIME_READ; 154 + cmd->rxsize = READ_RSP_SIZE; 155 + } 156 + 157 + static void atmel_ecc_init_genkey_cmd(struct atmel_ecc_cmd *cmd, u16 keyid) 158 + { 159 + cmd->word_addr = COMMAND; 160 + cmd->count = GENKEY_COUNT; 161 + cmd->opcode = OPCODE_GENKEY; 162 + cmd->param1 = GENKEY_MODE_PRIVATE; 163 + /* a random private key will be generated and stored in slot keyID */ 164 + cmd->param2 = cpu_to_le16(keyid); 165 + 166 + atmel_ecc_checksum(cmd); 167 + 168 + cmd->msecs = MAX_EXEC_TIME_GENKEY; 169 + cmd->rxsize = GENKEY_RSP_SIZE; 170 + } 171 + 172 + static int atmel_ecc_init_ecdh_cmd(struct atmel_ecc_cmd *cmd, 173 + struct scatterlist *pubkey) 174 + { 175 + size_t copied; 176 + 177 + cmd->word_addr = COMMAND; 178 + cmd->count = ECDH_COUNT; 179 + cmd->opcode = OPCODE_ECDH; 180 + cmd->param1 = ECDH_PREFIX_MODE; 181 + /* private key slot */ 182 + cmd->param2 = cpu_to_le16(DATA_SLOT_2); 183 + 184 + /* 185 + * The device only supports NIST P256 ECC keys. The public key size will 186 + * always be the same. Use a macro for the key size to avoid unnecessary 187 + * computations. 188 + */ 189 + copied = sg_copy_to_buffer(pubkey, 1, cmd->data, ATMEL_ECC_PUBKEY_SIZE); 190 + if (copied != ATMEL_ECC_PUBKEY_SIZE) 191 + return -EINVAL; 192 + 193 + atmel_ecc_checksum(cmd); 194 + 195 + cmd->msecs = MAX_EXEC_TIME_ECDH; 196 + cmd->rxsize = ECDH_RSP_SIZE; 197 + 198 + return 0; 199 + } 200 + 201 + /* 202 + * After wake and after execution of a command, there will be error, status, or 203 + * result bytes in the device's output register that can be retrieved by the 204 + * system. When the length of that group is four bytes, the codes returned are 205 + * detailed in error_list. 206 + */ 207 + static int atmel_ecc_status(struct device *dev, u8 *status) 208 + { 209 + size_t err_list_len = ARRAY_SIZE(error_list); 210 + int i; 211 + u8 err_id = status[1]; 212 + 213 + if (*status != STATUS_SIZE) 214 + return 0; 215 + 216 + if (err_id == STATUS_WAKE_SUCCESSFUL || err_id == STATUS_NOERR) 217 + return 0; 218 + 219 + for (i = 0; i < err_list_len; i++) 220 + if (error_list[i].value == err_id) 221 + break; 222 + 223 + /* if err_id is not in the error_list then ignore it */ 224 + if (i != err_list_len) { 225 + dev_err(dev, "%02x: %s:\n", err_id, error_list[i].error_text); 226 + return err_id; 227 + } 228 + 229 + return 0; 230 + } 231 + 232 + static int atmel_ecc_wakeup(struct i2c_client *client) 233 + { 234 + struct atmel_ecc_i2c_client_priv *i2c_priv = i2c_get_clientdata(client); 235 + u8 status[STATUS_RSP_SIZE]; 236 + int ret; 237 + 238 + /* 239 + * The device ignores any levels or transitions on the SCL pin when the 240 + * device is idle, asleep or during waking up. Don't check for error 241 + * when waking up the device. 242 + */ 243 + i2c_master_send(client, i2c_priv->wake_token, i2c_priv->wake_token_sz); 244 + 245 + /* 246 + * Wait to wake the device. Typical execution times for ecdh and genkey 247 + * are around tens of milliseconds. Delta is chosen to 50 microseconds. 248 + */ 249 + usleep_range(TWHI_MIN, TWHI_MAX); 250 + 251 + ret = i2c_master_recv(client, status, STATUS_SIZE); 252 + if (ret < 0) 253 + return ret; 254 + 255 + return atmel_ecc_status(&client->dev, status); 256 + } 257 + 258 + static int atmel_ecc_sleep(struct i2c_client *client) 259 + { 260 + u8 sleep = SLEEP_TOKEN; 261 + 262 + return i2c_master_send(client, &sleep, 1); 263 + } 264 + 265 + static void atmel_ecdh_done(struct atmel_ecc_work_data *work_data, void *areq, 266 + u8 status) 267 + { 268 + struct kpp_request *req = areq; 269 + struct atmel_ecdh_ctx *ctx = work_data->ctx; 270 + struct atmel_ecc_cmd *cmd = &work_data->cmd; 271 + size_t copied; 272 + size_t n_sz = ctx->n_sz; 273 + 274 + if (status) 275 + goto free_work_data; 276 + 277 + /* copy the shared secret */ 278 + copied = sg_copy_from_buffer(req->dst, 1, &cmd->data[RSP_DATA_IDX], 279 + n_sz); 280 + if (copied != n_sz) 281 + status = -EINVAL; 282 + 283 + /* fall through */ 284 + free_work_data: 285 + kzfree(work_data); 286 + kpp_request_complete(req, status); 287 + } 288 + 289 + /* 290 + * atmel_ecc_send_receive() - send a command to the device and receive its 291 + * response. 292 + * @client: i2c client device 293 + * @cmd : structure used to communicate with the device 294 + * 295 + * After the device receives a Wake token, a watchdog counter starts within the 296 + * device. After the watchdog timer expires, the device enters sleep mode 297 + * regardless of whether some I/O transmission or command execution is in 298 + * progress. If a command is attempted when insufficient time remains prior to 299 + * watchdog timer execution, the device will return the watchdog timeout error 300 + * code without attempting to execute the command. There is no way to reset the 301 + * counter other than to put the device into sleep or idle mode and then 302 + * wake it up again. 303 + */ 304 + static int atmel_ecc_send_receive(struct i2c_client *client, 305 + struct atmel_ecc_cmd *cmd) 306 + { 307 + struct atmel_ecc_i2c_client_priv *i2c_priv = i2c_get_clientdata(client); 308 + int ret; 309 + 310 + mutex_lock(&i2c_priv->lock); 311 + 312 + ret = atmel_ecc_wakeup(client); 313 + if (ret) 314 + goto err; 315 + 316 + /* send the command */ 317 + ret = i2c_master_send(client, (u8 *)cmd, cmd->count + WORD_ADDR_SIZE); 318 + if (ret < 0) 319 + goto err; 320 + 321 + /* delay the appropriate amount of time for command to execute */ 322 + msleep(cmd->msecs); 323 + 324 + /* receive the response */ 325 + ret = i2c_master_recv(client, cmd->data, cmd->rxsize); 326 + if (ret < 0) 327 + goto err; 328 + 329 + /* put the device into low-power mode */ 330 + ret = atmel_ecc_sleep(client); 331 + if (ret < 0) 332 + goto err; 333 + 334 + mutex_unlock(&i2c_priv->lock); 335 + return atmel_ecc_status(&client->dev, cmd->data); 336 + err: 337 + mutex_unlock(&i2c_priv->lock); 338 + return ret; 339 + } 340 + 341 + static void atmel_ecc_work_handler(struct work_struct *work) 342 + { 343 + struct atmel_ecc_work_data *work_data = 344 + container_of(work, struct atmel_ecc_work_data, work); 345 + struct atmel_ecc_cmd *cmd = &work_data->cmd; 346 + struct i2c_client *client = work_data->ctx->client; 347 + u8 status; 348 + 349 + status = atmel_ecc_send_receive(client, cmd); 350 + work_data->cbk(work_data, work_data->areq, status); 351 + } 352 + 353 + static void atmel_ecc_enqueue(struct atmel_ecc_work_data *work_data, 354 + void (*cbk)(struct atmel_ecc_work_data *work_data, 355 + void *areq, u8 status), 356 + void *areq) 357 + { 358 + work_data->cbk = (void *)cbk; 359 + work_data->areq = areq; 360 + 361 + INIT_WORK(&work_data->work, atmel_ecc_work_handler); 362 + schedule_work(&work_data->work); 363 + } 364 + 365 + static unsigned int atmel_ecdh_supported_curve(unsigned int curve_id) 366 + { 367 + if (curve_id == ECC_CURVE_NIST_P256) 368 + return ATMEL_ECC_NIST_P256_N_SIZE; 369 + 370 + return 0; 371 + } 372 + 373 + /* 374 + * A random private key is generated and stored in the device. The device 375 + * returns the pair public key. 376 + */ 377 + static int atmel_ecdh_set_secret(struct crypto_kpp *tfm, const void *buf, 378 + unsigned int len) 379 + { 380 + struct atmel_ecdh_ctx *ctx = kpp_tfm_ctx(tfm); 381 + struct atmel_ecc_cmd *cmd; 382 + void *public_key; 383 + struct ecdh params; 384 + int ret = -ENOMEM; 385 + 386 + /* free the old public key, if any */ 387 + kfree(ctx->public_key); 388 + /* make sure you don't free the old public key twice */ 389 + ctx->public_key = NULL; 390 + 391 + if (crypto_ecdh_decode_key(buf, len, &params) < 0) { 392 + dev_err(&ctx->client->dev, "crypto_ecdh_decode_key failed\n"); 393 + return -EINVAL; 394 + } 395 + 396 + ctx->n_sz = atmel_ecdh_supported_curve(params.curve_id); 397 + if (!ctx->n_sz || params.key_size) { 398 + /* fallback to ecdh software implementation */ 399 + ctx->do_fallback = true; 400 + return crypto_kpp_set_secret(ctx->fallback, buf, len); 401 + } 402 + 403 + cmd = kmalloc(sizeof(*cmd), GFP_KERNEL); 404 + if (!cmd) 405 + return -ENOMEM; 406 + 407 + /* 408 + * The device only supports NIST P256 ECC keys. The public key size will 409 + * always be the same. Use a macro for the key size to avoid unnecessary 410 + * computations. 411 + */ 412 + public_key = kmalloc(ATMEL_ECC_PUBKEY_SIZE, GFP_KERNEL); 413 + if (!public_key) 414 + goto free_cmd; 415 + 416 + ctx->do_fallback = false; 417 + ctx->curve_id = params.curve_id; 418 + 419 + atmel_ecc_init_genkey_cmd(cmd, DATA_SLOT_2); 420 + 421 + ret = atmel_ecc_send_receive(ctx->client, cmd); 422 + if (ret) 423 + goto free_public_key; 424 + 425 + /* save the public key */ 426 + memcpy(public_key, &cmd->data[RSP_DATA_IDX], ATMEL_ECC_PUBKEY_SIZE); 427 + ctx->public_key = public_key; 428 + 429 + kfree(cmd); 430 + return 0; 431 + 432 + free_public_key: 433 + kfree(public_key); 434 + free_cmd: 435 + kfree(cmd); 436 + return ret; 437 + } 438 + 439 + static int atmel_ecdh_generate_public_key(struct kpp_request *req) 440 + { 441 + struct crypto_kpp *tfm = crypto_kpp_reqtfm(req); 442 + struct atmel_ecdh_ctx *ctx = kpp_tfm_ctx(tfm); 443 + size_t copied; 444 + int ret = 0; 445 + 446 + if (ctx->do_fallback) { 447 + kpp_request_set_tfm(req, ctx->fallback); 448 + return crypto_kpp_generate_public_key(req); 449 + } 450 + 451 + /* public key was saved at private key generation */ 452 + copied = sg_copy_from_buffer(req->dst, 1, ctx->public_key, 453 + ATMEL_ECC_PUBKEY_SIZE); 454 + if (copied != ATMEL_ECC_PUBKEY_SIZE) 455 + ret = -EINVAL; 456 + 457 + return ret; 458 + } 459 + 460 + static int atmel_ecdh_compute_shared_secret(struct kpp_request *req) 461 + { 462 + struct crypto_kpp *tfm = crypto_kpp_reqtfm(req); 463 + struct atmel_ecdh_ctx *ctx = kpp_tfm_ctx(tfm); 464 + struct atmel_ecc_work_data *work_data; 465 + gfp_t gfp; 466 + int ret; 467 + 468 + if (ctx->do_fallback) { 469 + kpp_request_set_tfm(req, ctx->fallback); 470 + return crypto_kpp_compute_shared_secret(req); 471 + } 472 + 473 + gfp = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? GFP_KERNEL : 474 + GFP_ATOMIC; 475 + 476 + work_data = kmalloc(sizeof(*work_data), gfp); 477 + if (!work_data) 478 + return -ENOMEM; 479 + 480 + work_data->ctx = ctx; 481 + 482 + ret = atmel_ecc_init_ecdh_cmd(&work_data->cmd, req->src); 483 + if (ret) 484 + goto free_work_data; 485 + 486 + atmel_ecc_enqueue(work_data, atmel_ecdh_done, req); 487 + 488 + return -EINPROGRESS; 489 + 490 + free_work_data: 491 + kfree(work_data); 492 + return ret; 493 + } 494 + 495 + struct i2c_client *atmel_ecc_i2c_client_alloc(void) 496 + { 497 + struct atmel_ecc_i2c_client_priv *i2c_priv, *min_i2c_priv = NULL; 498 + struct i2c_client *client = ERR_PTR(-ENODEV); 499 + int min_tfm_cnt = INT_MAX; 500 + int tfm_cnt; 501 + 502 + spin_lock(&driver_data.i2c_list_lock); 503 + 504 + if (list_empty(&driver_data.i2c_client_list)) { 505 + spin_unlock(&driver_data.i2c_list_lock); 506 + return ERR_PTR(-ENODEV); 507 + } 508 + 509 + list_for_each_entry(i2c_priv, &driver_data.i2c_client_list, 510 + i2c_client_list_node) { 511 + tfm_cnt = atomic_read(&i2c_priv->tfm_count); 512 + if (tfm_cnt < min_tfm_cnt) { 513 + min_tfm_cnt = tfm_cnt; 514 + min_i2c_priv = i2c_priv; 515 + } 516 + if (!min_tfm_cnt) 517 + break; 518 + } 519 + 520 + if (min_i2c_priv) { 521 + atomic_inc(&min_i2c_priv->tfm_count); 522 + client = min_i2c_priv->client; 523 + } 524 + 525 + spin_unlock(&driver_data.i2c_list_lock); 526 + 527 + return client; 528 + } 529 + 530 + void atmel_ecc_i2c_client_free(struct i2c_client *client) 531 + { 532 + struct atmel_ecc_i2c_client_priv *i2c_priv = i2c_get_clientdata(client); 533 + 534 + atomic_dec(&i2c_priv->tfm_count); 535 + } 536 + 537 + static int atmel_ecdh_init_tfm(struct crypto_kpp *tfm) 538 + { 539 + const char *alg = kpp_alg_name(tfm); 540 + struct crypto_kpp *fallback; 541 + struct atmel_ecdh_ctx *ctx = kpp_tfm_ctx(tfm); 542 + 543 + ctx->client = atmel_ecc_i2c_client_alloc(); 544 + if (IS_ERR(ctx->client)) { 545 + pr_err("tfm - i2c_client binding failed\n"); 546 + return PTR_ERR(ctx->client); 547 + } 548 + 549 + fallback = crypto_alloc_kpp(alg, 0, CRYPTO_ALG_NEED_FALLBACK); 550 + if (IS_ERR(fallback)) { 551 + dev_err(&ctx->client->dev, "Failed to allocate transformation for '%s': %ld\n", 552 + alg, PTR_ERR(fallback)); 553 + return PTR_ERR(fallback); 554 + } 555 + 556 + crypto_kpp_set_flags(fallback, crypto_kpp_get_flags(tfm)); 557 + 558 + dev_info(&ctx->client->dev, "Using '%s' as fallback implementation.\n", 559 + crypto_tfm_alg_driver_name(crypto_kpp_tfm(fallback))); 560 + 561 + ctx->fallback = fallback; 562 + 563 + return 0; 564 + } 565 + 566 + static void atmel_ecdh_exit_tfm(struct crypto_kpp *tfm) 567 + { 568 + struct atmel_ecdh_ctx *ctx = kpp_tfm_ctx(tfm); 569 + 570 + kfree(ctx->public_key); 571 + crypto_free_kpp(ctx->fallback); 572 + atmel_ecc_i2c_client_free(ctx->client); 573 + } 574 + 575 + static unsigned int atmel_ecdh_max_size(struct crypto_kpp *tfm) 576 + { 577 + struct atmel_ecdh_ctx *ctx = kpp_tfm_ctx(tfm); 578 + 579 + if (ctx->fallback) 580 + return crypto_kpp_maxsize(ctx->fallback); 581 + 582 + /* 583 + * The device only supports NIST P256 ECC keys. The public key size will 584 + * always be the same. Use a macro for the key size to avoid unnecessary 585 + * computations. 586 + */ 587 + return ATMEL_ECC_PUBKEY_SIZE; 588 + } 589 + 590 + static struct kpp_alg atmel_ecdh = { 591 + .set_secret = atmel_ecdh_set_secret, 592 + .generate_public_key = atmel_ecdh_generate_public_key, 593 + .compute_shared_secret = atmel_ecdh_compute_shared_secret, 594 + .init = atmel_ecdh_init_tfm, 595 + .exit = atmel_ecdh_exit_tfm, 596 + .max_size = atmel_ecdh_max_size, 597 + .base = { 598 + .cra_flags = CRYPTO_ALG_NEED_FALLBACK, 599 + .cra_name = "ecdh", 600 + .cra_driver_name = "atmel-ecdh", 601 + .cra_priority = ATMEL_ECC_PRIORITY, 602 + .cra_module = THIS_MODULE, 603 + .cra_ctxsize = sizeof(struct atmel_ecdh_ctx), 604 + }, 605 + }; 606 + 607 + static inline size_t atmel_ecc_wake_token_sz(u32 bus_clk_rate) 608 + { 609 + u32 no_of_bits = DIV_ROUND_UP(TWLO_USEC * bus_clk_rate, USEC_PER_SEC); 610 + 611 + /* return the size of the wake_token in bytes */ 612 + return DIV_ROUND_UP(no_of_bits, 8); 613 + } 614 + 615 + static int device_sanity_check(struct i2c_client *client) 616 + { 617 + struct atmel_ecc_cmd *cmd; 618 + int ret; 619 + 620 + cmd = kmalloc(sizeof(*cmd), GFP_KERNEL); 621 + if (!cmd) 622 + return -ENOMEM; 623 + 624 + atmel_ecc_init_read_cmd(cmd); 625 + 626 + ret = atmel_ecc_send_receive(client, cmd); 627 + if (ret) 628 + goto free_cmd; 629 + 630 + /* 631 + * It is vital that the Configuration, Data and OTP zones be locked 632 + * prior to release into the field of the system containing the device. 633 + * Failure to lock these zones may permit modification of any secret 634 + * keys and may lead to other security problems. 635 + */ 636 + if (cmd->data[LOCK_CONFIG_IDX] || cmd->data[LOCK_VALUE_IDX]) { 637 + dev_err(&client->dev, "Configuration or Data and OTP zones are unlocked!\n"); 638 + ret = -ENOTSUPP; 639 + } 640 + 641 + /* fall through */ 642 + free_cmd: 643 + kfree(cmd); 644 + return ret; 645 + } 646 + 647 + static int atmel_ecc_probe(struct i2c_client *client, 648 + const struct i2c_device_id *id) 649 + { 650 + struct atmel_ecc_i2c_client_priv *i2c_priv; 651 + struct device *dev = &client->dev; 652 + int ret; 653 + u32 bus_clk_rate; 654 + 655 + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 656 + dev_err(dev, "I2C_FUNC_I2C not supported\n"); 657 + return -ENODEV; 658 + } 659 + 660 + ret = of_property_read_u32(client->adapter->dev.of_node, 661 + "clock-frequency", &bus_clk_rate); 662 + if (ret) { 663 + dev_err(dev, "of: failed to read clock-frequency property\n"); 664 + return ret; 665 + } 666 + 667 + if (bus_clk_rate > 1000000L) { 668 + dev_err(dev, "%d exceeds maximum supported clock frequency (1MHz)\n", 669 + bus_clk_rate); 670 + return -EINVAL; 671 + } 672 + 673 + i2c_priv = devm_kmalloc(dev, sizeof(*i2c_priv), GFP_KERNEL); 674 + if (!i2c_priv) 675 + return -ENOMEM; 676 + 677 + i2c_priv->client = client; 678 + mutex_init(&i2c_priv->lock); 679 + 680 + /* 681 + * WAKE_TOKEN_MAX_SIZE was calculated for the maximum bus_clk_rate - 682 + * 1MHz. The previous bus_clk_rate check ensures us that wake_token_sz 683 + * will always be smaller than or equal to WAKE_TOKEN_MAX_SIZE. 684 + */ 685 + i2c_priv->wake_token_sz = atmel_ecc_wake_token_sz(bus_clk_rate); 686 + 687 + memset(i2c_priv->wake_token, 0, sizeof(i2c_priv->wake_token)); 688 + 689 + atomic_set(&i2c_priv->tfm_count, 0); 690 + 691 + i2c_set_clientdata(client, i2c_priv); 692 + 693 + ret = device_sanity_check(client); 694 + if (ret) 695 + return ret; 696 + 697 + spin_lock(&driver_data.i2c_list_lock); 698 + list_add_tail(&i2c_priv->i2c_client_list_node, 699 + &driver_data.i2c_client_list); 700 + spin_unlock(&driver_data.i2c_list_lock); 701 + 702 + ret = crypto_register_kpp(&atmel_ecdh); 703 + if (ret) { 704 + spin_lock(&driver_data.i2c_list_lock); 705 + list_del(&i2c_priv->i2c_client_list_node); 706 + spin_unlock(&driver_data.i2c_list_lock); 707 + 708 + dev_err(dev, "%s alg registration failed\n", 709 + atmel_ecdh.base.cra_driver_name); 710 + } else { 711 + dev_info(dev, "atmel ecc algorithms registered in /proc/crypto\n"); 712 + } 713 + 714 + return ret; 715 + } 716 + 717 + static int atmel_ecc_remove(struct i2c_client *client) 718 + { 719 + struct atmel_ecc_i2c_client_priv *i2c_priv = i2c_get_clientdata(client); 720 + 721 + /* Return EBUSY if i2c client already allocated. */ 722 + if (atomic_read(&i2c_priv->tfm_count)) { 723 + dev_err(&client->dev, "Device is busy\n"); 724 + return -EBUSY; 725 + } 726 + 727 + crypto_unregister_kpp(&atmel_ecdh); 728 + 729 + spin_lock(&driver_data.i2c_list_lock); 730 + list_del(&i2c_priv->i2c_client_list_node); 731 + spin_unlock(&driver_data.i2c_list_lock); 732 + 733 + return 0; 734 + } 735 + 736 + #ifdef CONFIG_OF 737 + static const struct of_device_id atmel_ecc_dt_ids[] = { 738 + { 739 + .compatible = "atmel,atecc508a", 740 + }, { 741 + /* sentinel */ 742 + } 743 + }; 744 + MODULE_DEVICE_TABLE(of, atmel_ecc_dt_ids); 745 + #endif 746 + 747 + static const struct i2c_device_id atmel_ecc_id[] = { 748 + { "atecc508a", 0 }, 749 + { } 750 + }; 751 + MODULE_DEVICE_TABLE(i2c, atmel_ecc_id); 752 + 753 + static struct i2c_driver atmel_ecc_driver = { 754 + .driver = { 755 + .name = "atmel-ecc", 756 + .of_match_table = of_match_ptr(atmel_ecc_dt_ids), 757 + }, 758 + .probe = atmel_ecc_probe, 759 + .remove = atmel_ecc_remove, 760 + .id_table = atmel_ecc_id, 761 + }; 762 + 763 + static int __init atmel_ecc_init(void) 764 + { 765 + spin_lock_init(&driver_data.i2c_list_lock); 766 + INIT_LIST_HEAD(&driver_data.i2c_client_list); 767 + return i2c_add_driver(&atmel_ecc_driver); 768 + } 769 + 770 + static void __exit atmel_ecc_exit(void) 771 + { 772 + flush_scheduled_work(); 773 + i2c_del_driver(&atmel_ecc_driver); 774 + } 775 + 776 + module_init(atmel_ecc_init); 777 + module_exit(atmel_ecc_exit); 778 + 779 + MODULE_AUTHOR("Tudor Ambarus <tudor.ambarus@microchip.com>"); 780 + MODULE_DESCRIPTION("Microchip / Atmel ECC (I2C) driver"); 781 + MODULE_LICENSE("GPL v2");
+128
drivers/crypto/atmel-ecc.h
··· 1 + /* 2 + * Copyright (c) 2017, Microchip Technology Inc. 3 + * Author: Tudor Ambarus <tudor.ambarus@microchip.com> 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License version 2 as 7 + * published by the Free Software Foundation. 8 + * 9 + * This program is distributed in the hope that it will be useful, but WITHOUT 10 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 + * more details. 13 + * 14 + * You should have received a copy of the GNU General Public License along with 15 + * this program. If not, see <http://www.gnu.org/licenses/>. 16 + * 17 + */ 18 + 19 + #ifndef __ATMEL_ECC_H__ 20 + #define __ATMEL_ECC_H__ 21 + 22 + #define ATMEL_ECC_PRIORITY 300 23 + 24 + #define COMMAND 0x03 /* packet function */ 25 + #define SLEEP_TOKEN 0x01 26 + #define WAKE_TOKEN_MAX_SIZE 8 27 + 28 + /* Definitions of Data and Command sizes */ 29 + #define WORD_ADDR_SIZE 1 30 + #define COUNT_SIZE 1 31 + #define CRC_SIZE 2 32 + #define CMD_OVERHEAD_SIZE (COUNT_SIZE + CRC_SIZE) 33 + 34 + /* size in bytes of the n prime */ 35 + #define ATMEL_ECC_NIST_P256_N_SIZE 32 36 + #define ATMEL_ECC_PUBKEY_SIZE (2 * ATMEL_ECC_NIST_P256_N_SIZE) 37 + 38 + #define STATUS_RSP_SIZE 4 39 + #define ECDH_RSP_SIZE (32 + CMD_OVERHEAD_SIZE) 40 + #define GENKEY_RSP_SIZE (ATMEL_ECC_PUBKEY_SIZE + \ 41 + CMD_OVERHEAD_SIZE) 42 + #define READ_RSP_SIZE (4 + CMD_OVERHEAD_SIZE) 43 + #define MAX_RSP_SIZE GENKEY_RSP_SIZE 44 + 45 + /** 46 + * atmel_ecc_cmd - structure used for communicating with the device. 47 + * @word_addr: indicates the function of the packet sent to the device. This 48 + * byte should have a value of COMMAND for normal operation. 49 + * @count : number of bytes to be transferred to (or from) the device. 50 + * @opcode : the command code. 51 + * @param1 : the first parameter; always present. 52 + * @param2 : the second parameter; always present. 53 + * @data : optional remaining input data. Includes a 2-byte CRC. 54 + * @rxsize : size of the data received from i2c client. 55 + * @msecs : command execution time in milliseconds 56 + */ 57 + struct atmel_ecc_cmd { 58 + u8 word_addr; 59 + u8 count; 60 + u8 opcode; 61 + u8 param1; 62 + u16 param2; 63 + u8 data[MAX_RSP_SIZE]; 64 + u8 msecs; 65 + u16 rxsize; 66 + } __packed; 67 + 68 + /* Status/Error codes */ 69 + #define STATUS_SIZE 0x04 70 + #define STATUS_NOERR 0x00 71 + #define STATUS_WAKE_SUCCESSFUL 0x11 72 + 73 + static const struct { 74 + u8 value; 75 + const char *error_text; 76 + } error_list[] = { 77 + { 0x01, "CheckMac or Verify miscompare" }, 78 + { 0x03, "Parse Error" }, 79 + { 0x05, "ECC Fault" }, 80 + { 0x0F, "Execution Error" }, 81 + { 0xEE, "Watchdog about to expire" }, 82 + { 0xFF, "CRC or other communication error" }, 83 + }; 84 + 85 + /* Definitions for eeprom organization */ 86 + #define CONFIG_ZONE 0 87 + 88 + /* Definitions for Indexes common to all commands */ 89 + #define RSP_DATA_IDX 1 /* buffer index of data in response */ 90 + #define DATA_SLOT_2 2 /* used for ECDH private key */ 91 + 92 + /* Definitions for the device lock state */ 93 + #define DEVICE_LOCK_ADDR 0x15 94 + #define LOCK_VALUE_IDX (RSP_DATA_IDX + 2) 95 + #define LOCK_CONFIG_IDX (RSP_DATA_IDX + 3) 96 + 97 + /* 98 + * Wake High delay to data communication (microseconds). SDA should be stable 99 + * high for this entire duration. 100 + */ 101 + #define TWHI_MIN 1500 102 + #define TWHI_MAX 1550 103 + 104 + /* Wake Low duration */ 105 + #define TWLO_USEC 60 106 + 107 + /* Command execution time (milliseconds) */ 108 + #define MAX_EXEC_TIME_ECDH 58 109 + #define MAX_EXEC_TIME_GENKEY 115 110 + #define MAX_EXEC_TIME_READ 1 111 + 112 + /* Command opcode */ 113 + #define OPCODE_ECDH 0x43 114 + #define OPCODE_GENKEY 0x40 115 + #define OPCODE_READ 0x02 116 + 117 + /* Definitions for the READ Command */ 118 + #define READ_COUNT 7 119 + 120 + /* Definitions for the GenKey Command */ 121 + #define GENKEY_COUNT 7 122 + #define GENKEY_MODE_PRIVATE 0x04 123 + 124 + /* Definitions for the ECDH Command */ 125 + #define ECDH_COUNT 71 126 + #define ECDH_PREFIX_MODE 0x00 127 + 128 + #endif /* __ATMEL_ECC_H__ */