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

Configure Feed

Select the types of activity you want to include in your feed.

at v4.5 542 lines 15 kB view raw
1/* 2 * sun4i-ss-cipher.c - hardware cryptographic accelerator for Allwinner A20 SoC 3 * 4 * Copyright (C) 2013-2015 Corentin LABBE <clabbe.montjoie@gmail.com> 5 * 6 * This file add support for AES cipher with 128,192,256 bits 7 * keysize in CBC and ECB mode. 8 * Add support also for DES and 3DES in CBC and ECB mode. 9 * 10 * You could find the datasheet in Documentation/arm/sunxi/README 11 * 12 * This program is free software; you can redistribute it and/or modify 13 * it under the terms of the GNU General Public License as published by 14 * the Free Software Foundation; either version 2 of the License, or 15 * (at your option) any later version. 16 */ 17#include "sun4i-ss.h" 18 19static int sun4i_ss_opti_poll(struct ablkcipher_request *areq) 20{ 21 struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(areq); 22 struct sun4i_tfm_ctx *op = crypto_ablkcipher_ctx(tfm); 23 struct sun4i_ss_ctx *ss = op->ss; 24 unsigned int ivsize = crypto_ablkcipher_ivsize(tfm); 25 struct sun4i_cipher_req_ctx *ctx = ablkcipher_request_ctx(areq); 26 u32 mode = ctx->mode; 27 /* when activating SS, the default FIFO space is SS_RX_DEFAULT(32) */ 28 u32 rx_cnt = SS_RX_DEFAULT; 29 u32 tx_cnt = 0; 30 u32 spaces; 31 u32 v; 32 int i, err = 0; 33 unsigned int ileft = areq->nbytes; 34 unsigned int oleft = areq->nbytes; 35 unsigned int todo; 36 struct sg_mapping_iter mi, mo; 37 unsigned int oi, oo; /* offset for in and out */ 38 39 if (areq->nbytes == 0) 40 return 0; 41 42 if (!areq->info) { 43 dev_err_ratelimited(ss->dev, "ERROR: Empty IV\n"); 44 return -EINVAL; 45 } 46 47 if (!areq->src || !areq->dst) { 48 dev_err_ratelimited(ss->dev, "ERROR: Some SGs are NULL\n"); 49 return -EINVAL; 50 } 51 52 spin_lock_bh(&ss->slock); 53 54 for (i = 0; i < op->keylen; i += 4) 55 writel(*(op->key + i / 4), ss->base + SS_KEY0 + i); 56 57 if (areq->info) { 58 for (i = 0; i < 4 && i < ivsize / 4; i++) { 59 v = *(u32 *)(areq->info + i * 4); 60 writel(v, ss->base + SS_IV0 + i * 4); 61 } 62 } 63 writel(mode, ss->base + SS_CTL); 64 65 sg_miter_start(&mi, areq->src, sg_nents(areq->src), 66 SG_MITER_FROM_SG | SG_MITER_ATOMIC); 67 sg_miter_start(&mo, areq->dst, sg_nents(areq->dst), 68 SG_MITER_TO_SG | SG_MITER_ATOMIC); 69 sg_miter_next(&mi); 70 sg_miter_next(&mo); 71 if (!mi.addr || !mo.addr) { 72 dev_err_ratelimited(ss->dev, "ERROR: sg_miter return null\n"); 73 err = -EINVAL; 74 goto release_ss; 75 } 76 77 ileft = areq->nbytes / 4; 78 oleft = areq->nbytes / 4; 79 oi = 0; 80 oo = 0; 81 do { 82 todo = min3(rx_cnt, ileft, (mi.length - oi) / 4); 83 if (todo > 0) { 84 ileft -= todo; 85 writesl(ss->base + SS_RXFIFO, mi.addr + oi, todo); 86 oi += todo * 4; 87 } 88 if (oi == mi.length) { 89 sg_miter_next(&mi); 90 oi = 0; 91 } 92 93 spaces = readl(ss->base + SS_FCSR); 94 rx_cnt = SS_RXFIFO_SPACES(spaces); 95 tx_cnt = SS_TXFIFO_SPACES(spaces); 96 97 todo = min3(tx_cnt, oleft, (mo.length - oo) / 4); 98 if (todo > 0) { 99 oleft -= todo; 100 readsl(ss->base + SS_TXFIFO, mo.addr + oo, todo); 101 oo += todo * 4; 102 } 103 if (oo == mo.length) { 104 sg_miter_next(&mo); 105 oo = 0; 106 } 107 } while (oleft > 0); 108 109 if (areq->info) { 110 for (i = 0; i < 4 && i < ivsize / 4; i++) { 111 v = readl(ss->base + SS_IV0 + i * 4); 112 *(u32 *)(areq->info + i * 4) = v; 113 } 114 } 115 116release_ss: 117 sg_miter_stop(&mi); 118 sg_miter_stop(&mo); 119 writel(0, ss->base + SS_CTL); 120 spin_unlock_bh(&ss->slock); 121 return err; 122} 123 124/* Generic function that support SG with size not multiple of 4 */ 125static int sun4i_ss_cipher_poll(struct ablkcipher_request *areq) 126{ 127 struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(areq); 128 struct sun4i_tfm_ctx *op = crypto_ablkcipher_ctx(tfm); 129 struct sun4i_ss_ctx *ss = op->ss; 130 int no_chunk = 1; 131 struct scatterlist *in_sg = areq->src; 132 struct scatterlist *out_sg = areq->dst; 133 unsigned int ivsize = crypto_ablkcipher_ivsize(tfm); 134 struct sun4i_cipher_req_ctx *ctx = ablkcipher_request_ctx(areq); 135 u32 mode = ctx->mode; 136 /* when activating SS, the default FIFO space is SS_RX_DEFAULT(32) */ 137 u32 rx_cnt = SS_RX_DEFAULT; 138 u32 tx_cnt = 0; 139 u32 v; 140 u32 spaces; 141 int i, err = 0; 142 unsigned int ileft = areq->nbytes; 143 unsigned int oleft = areq->nbytes; 144 unsigned int todo; 145 struct sg_mapping_iter mi, mo; 146 unsigned int oi, oo; /* offset for in and out */ 147 char buf[4 * SS_RX_MAX];/* buffer for linearize SG src */ 148 char bufo[4 * SS_TX_MAX]; /* buffer for linearize SG dst */ 149 unsigned int ob = 0; /* offset in buf */ 150 unsigned int obo = 0; /* offset in bufo*/ 151 unsigned int obl = 0; /* length of data in bufo */ 152 153 if (areq->nbytes == 0) 154 return 0; 155 156 if (!areq->info) { 157 dev_err_ratelimited(ss->dev, "ERROR: Empty IV\n"); 158 return -EINVAL; 159 } 160 161 if (!areq->src || !areq->dst) { 162 dev_err_ratelimited(ss->dev, "ERROR: Some SGs are NULL\n"); 163 return -EINVAL; 164 } 165 166 /* 167 * if we have only SGs with size multiple of 4, 168 * we can use the SS optimized function 169 */ 170 while (in_sg && no_chunk == 1) { 171 if ((in_sg->length % 4) != 0) 172 no_chunk = 0; 173 in_sg = sg_next(in_sg); 174 } 175 while (out_sg && no_chunk == 1) { 176 if ((out_sg->length % 4) != 0) 177 no_chunk = 0; 178 out_sg = sg_next(out_sg); 179 } 180 181 if (no_chunk == 1) 182 return sun4i_ss_opti_poll(areq); 183 184 spin_lock_bh(&ss->slock); 185 186 for (i = 0; i < op->keylen; i += 4) 187 writel(*(op->key + i / 4), ss->base + SS_KEY0 + i); 188 189 if (areq->info) { 190 for (i = 0; i < 4 && i < ivsize / 4; i++) { 191 v = *(u32 *)(areq->info + i * 4); 192 writel(v, ss->base + SS_IV0 + i * 4); 193 } 194 } 195 writel(mode, ss->base + SS_CTL); 196 197 sg_miter_start(&mi, areq->src, sg_nents(areq->src), 198 SG_MITER_FROM_SG | SG_MITER_ATOMIC); 199 sg_miter_start(&mo, areq->dst, sg_nents(areq->dst), 200 SG_MITER_TO_SG | SG_MITER_ATOMIC); 201 sg_miter_next(&mi); 202 sg_miter_next(&mo); 203 if (!mi.addr || !mo.addr) { 204 dev_err_ratelimited(ss->dev, "ERROR: sg_miter return null\n"); 205 err = -EINVAL; 206 goto release_ss; 207 } 208 ileft = areq->nbytes; 209 oleft = areq->nbytes; 210 oi = 0; 211 oo = 0; 212 213 while (oleft > 0) { 214 if (ileft > 0) { 215 /* 216 * todo is the number of consecutive 4byte word that we 217 * can read from current SG 218 */ 219 todo = min3(rx_cnt, ileft / 4, (mi.length - oi) / 4); 220 if (todo > 0 && ob == 0) { 221 writesl(ss->base + SS_RXFIFO, mi.addr + oi, 222 todo); 223 ileft -= todo * 4; 224 oi += todo * 4; 225 } else { 226 /* 227 * not enough consecutive bytes, so we need to 228 * linearize in buf. todo is in bytes 229 * After that copy, if we have a multiple of 4 230 * we need to be able to write all buf in one 231 * pass, so it is why we min() with rx_cnt 232 */ 233 todo = min3(rx_cnt * 4 - ob, ileft, 234 mi.length - oi); 235 memcpy(buf + ob, mi.addr + oi, todo); 236 ileft -= todo; 237 oi += todo; 238 ob += todo; 239 if (ob % 4 == 0) { 240 writesl(ss->base + SS_RXFIFO, buf, 241 ob / 4); 242 ob = 0; 243 } 244 } 245 if (oi == mi.length) { 246 sg_miter_next(&mi); 247 oi = 0; 248 } 249 } 250 251 spaces = readl(ss->base + SS_FCSR); 252 rx_cnt = SS_RXFIFO_SPACES(spaces); 253 tx_cnt = SS_TXFIFO_SPACES(spaces); 254 dev_dbg(ss->dev, "%x %u/%u %u/%u cnt=%u %u/%u %u/%u cnt=%u %u %u\n", 255 mode, 256 oi, mi.length, ileft, areq->nbytes, rx_cnt, 257 oo, mo.length, oleft, areq->nbytes, tx_cnt, 258 todo, ob); 259 260 if (tx_cnt == 0) 261 continue; 262 /* todo in 4bytes word */ 263 todo = min3(tx_cnt, oleft / 4, (mo.length - oo) / 4); 264 if (todo > 0) { 265 readsl(ss->base + SS_TXFIFO, mo.addr + oo, todo); 266 oleft -= todo * 4; 267 oo += todo * 4; 268 if (oo == mo.length) { 269 sg_miter_next(&mo); 270 oo = 0; 271 } 272 } else { 273 /* 274 * read obl bytes in bufo, we read at maximum for 275 * emptying the device 276 */ 277 readsl(ss->base + SS_TXFIFO, bufo, tx_cnt); 278 obl = tx_cnt * 4; 279 obo = 0; 280 do { 281 /* 282 * how many bytes we can copy ? 283 * no more than remaining SG size 284 * no more than remaining buffer 285 * no need to test against oleft 286 */ 287 todo = min(mo.length - oo, obl - obo); 288 memcpy(mo.addr + oo, bufo + obo, todo); 289 oleft -= todo; 290 obo += todo; 291 oo += todo; 292 if (oo == mo.length) { 293 sg_miter_next(&mo); 294 oo = 0; 295 } 296 } while (obo < obl); 297 /* bufo must be fully used here */ 298 } 299 } 300 if (areq->info) { 301 for (i = 0; i < 4 && i < ivsize / 4; i++) { 302 v = readl(ss->base + SS_IV0 + i * 4); 303 *(u32 *)(areq->info + i * 4) = v; 304 } 305 } 306 307release_ss: 308 sg_miter_stop(&mi); 309 sg_miter_stop(&mo); 310 writel(0, ss->base + SS_CTL); 311 spin_unlock_bh(&ss->slock); 312 313 return err; 314} 315 316/* CBC AES */ 317int sun4i_ss_cbc_aes_encrypt(struct ablkcipher_request *areq) 318{ 319 struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(areq); 320 struct sun4i_tfm_ctx *op = crypto_ablkcipher_ctx(tfm); 321 struct sun4i_cipher_req_ctx *rctx = ablkcipher_request_ctx(areq); 322 323 rctx->mode = SS_OP_AES | SS_CBC | SS_ENABLED | SS_ENCRYPTION | 324 op->keymode; 325 return sun4i_ss_cipher_poll(areq); 326} 327 328int sun4i_ss_cbc_aes_decrypt(struct ablkcipher_request *areq) 329{ 330 struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(areq); 331 struct sun4i_tfm_ctx *op = crypto_ablkcipher_ctx(tfm); 332 struct sun4i_cipher_req_ctx *rctx = ablkcipher_request_ctx(areq); 333 334 rctx->mode = SS_OP_AES | SS_CBC | SS_ENABLED | SS_DECRYPTION | 335 op->keymode; 336 return sun4i_ss_cipher_poll(areq); 337} 338 339/* ECB AES */ 340int sun4i_ss_ecb_aes_encrypt(struct ablkcipher_request *areq) 341{ 342 struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(areq); 343 struct sun4i_tfm_ctx *op = crypto_ablkcipher_ctx(tfm); 344 struct sun4i_cipher_req_ctx *rctx = ablkcipher_request_ctx(areq); 345 346 rctx->mode = SS_OP_AES | SS_ECB | SS_ENABLED | SS_ENCRYPTION | 347 op->keymode; 348 return sun4i_ss_cipher_poll(areq); 349} 350 351int sun4i_ss_ecb_aes_decrypt(struct ablkcipher_request *areq) 352{ 353 struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(areq); 354 struct sun4i_tfm_ctx *op = crypto_ablkcipher_ctx(tfm); 355 struct sun4i_cipher_req_ctx *rctx = ablkcipher_request_ctx(areq); 356 357 rctx->mode = SS_OP_AES | SS_ECB | SS_ENABLED | SS_DECRYPTION | 358 op->keymode; 359 return sun4i_ss_cipher_poll(areq); 360} 361 362/* CBC DES */ 363int sun4i_ss_cbc_des_encrypt(struct ablkcipher_request *areq) 364{ 365 struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(areq); 366 struct sun4i_tfm_ctx *op = crypto_ablkcipher_ctx(tfm); 367 struct sun4i_cipher_req_ctx *rctx = ablkcipher_request_ctx(areq); 368 369 rctx->mode = SS_OP_DES | SS_CBC | SS_ENABLED | SS_ENCRYPTION | 370 op->keymode; 371 return sun4i_ss_cipher_poll(areq); 372} 373 374int sun4i_ss_cbc_des_decrypt(struct ablkcipher_request *areq) 375{ 376 struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(areq); 377 struct sun4i_tfm_ctx *op = crypto_ablkcipher_ctx(tfm); 378 struct sun4i_cipher_req_ctx *rctx = ablkcipher_request_ctx(areq); 379 380 rctx->mode = SS_OP_DES | SS_CBC | SS_ENABLED | SS_DECRYPTION | 381 op->keymode; 382 return sun4i_ss_cipher_poll(areq); 383} 384 385/* ECB DES */ 386int sun4i_ss_ecb_des_encrypt(struct ablkcipher_request *areq) 387{ 388 struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(areq); 389 struct sun4i_tfm_ctx *op = crypto_ablkcipher_ctx(tfm); 390 struct sun4i_cipher_req_ctx *rctx = ablkcipher_request_ctx(areq); 391 392 rctx->mode = SS_OP_DES | SS_ECB | SS_ENABLED | SS_ENCRYPTION | 393 op->keymode; 394 return sun4i_ss_cipher_poll(areq); 395} 396 397int sun4i_ss_ecb_des_decrypt(struct ablkcipher_request *areq) 398{ 399 struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(areq); 400 struct sun4i_tfm_ctx *op = crypto_ablkcipher_ctx(tfm); 401 struct sun4i_cipher_req_ctx *rctx = ablkcipher_request_ctx(areq); 402 403 rctx->mode = SS_OP_DES | SS_ECB | SS_ENABLED | SS_DECRYPTION | 404 op->keymode; 405 return sun4i_ss_cipher_poll(areq); 406} 407 408/* CBC 3DES */ 409int sun4i_ss_cbc_des3_encrypt(struct ablkcipher_request *areq) 410{ 411 struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(areq); 412 struct sun4i_tfm_ctx *op = crypto_ablkcipher_ctx(tfm); 413 struct sun4i_cipher_req_ctx *rctx = ablkcipher_request_ctx(areq); 414 415 rctx->mode = SS_OP_3DES | SS_CBC | SS_ENABLED | SS_ENCRYPTION | 416 op->keymode; 417 return sun4i_ss_cipher_poll(areq); 418} 419 420int sun4i_ss_cbc_des3_decrypt(struct ablkcipher_request *areq) 421{ 422 struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(areq); 423 struct sun4i_tfm_ctx *op = crypto_ablkcipher_ctx(tfm); 424 struct sun4i_cipher_req_ctx *rctx = ablkcipher_request_ctx(areq); 425 426 rctx->mode = SS_OP_3DES | SS_CBC | SS_ENABLED | SS_DECRYPTION | 427 op->keymode; 428 return sun4i_ss_cipher_poll(areq); 429} 430 431/* ECB 3DES */ 432int sun4i_ss_ecb_des3_encrypt(struct ablkcipher_request *areq) 433{ 434 struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(areq); 435 struct sun4i_tfm_ctx *op = crypto_ablkcipher_ctx(tfm); 436 struct sun4i_cipher_req_ctx *rctx = ablkcipher_request_ctx(areq); 437 438 rctx->mode = SS_OP_3DES | SS_ECB | SS_ENABLED | SS_ENCRYPTION | 439 op->keymode; 440 return sun4i_ss_cipher_poll(areq); 441} 442 443int sun4i_ss_ecb_des3_decrypt(struct ablkcipher_request *areq) 444{ 445 struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(areq); 446 struct sun4i_tfm_ctx *op = crypto_ablkcipher_ctx(tfm); 447 struct sun4i_cipher_req_ctx *rctx = ablkcipher_request_ctx(areq); 448 449 rctx->mode = SS_OP_3DES | SS_ECB | SS_ENABLED | SS_DECRYPTION | 450 op->keymode; 451 return sun4i_ss_cipher_poll(areq); 452} 453 454int sun4i_ss_cipher_init(struct crypto_tfm *tfm) 455{ 456 struct sun4i_tfm_ctx *op = crypto_tfm_ctx(tfm); 457 struct crypto_alg *alg = tfm->__crt_alg; 458 struct sun4i_ss_alg_template *algt; 459 460 memset(op, 0, sizeof(struct sun4i_tfm_ctx)); 461 462 algt = container_of(alg, struct sun4i_ss_alg_template, alg.crypto); 463 op->ss = algt->ss; 464 465 tfm->crt_ablkcipher.reqsize = sizeof(struct sun4i_cipher_req_ctx); 466 467 return 0; 468} 469 470/* check and set the AES key, prepare the mode to be used */ 471int sun4i_ss_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key, 472 unsigned int keylen) 473{ 474 struct sun4i_tfm_ctx *op = crypto_ablkcipher_ctx(tfm); 475 struct sun4i_ss_ctx *ss = op->ss; 476 477 switch (keylen) { 478 case 128 / 8: 479 op->keymode = SS_AES_128BITS; 480 break; 481 case 192 / 8: 482 op->keymode = SS_AES_192BITS; 483 break; 484 case 256 / 8: 485 op->keymode = SS_AES_256BITS; 486 break; 487 default: 488 dev_err(ss->dev, "ERROR: Invalid keylen %u\n", keylen); 489 crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 490 return -EINVAL; 491 } 492 op->keylen = keylen; 493 memcpy(op->key, key, keylen); 494 return 0; 495} 496 497/* check and set the DES key, prepare the mode to be used */ 498int sun4i_ss_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key, 499 unsigned int keylen) 500{ 501 struct sun4i_tfm_ctx *op = crypto_ablkcipher_ctx(tfm); 502 struct sun4i_ss_ctx *ss = op->ss; 503 u32 flags; 504 u32 tmp[DES_EXPKEY_WORDS]; 505 int ret; 506 507 if (unlikely(keylen != DES_KEY_SIZE)) { 508 dev_err(ss->dev, "Invalid keylen %u\n", keylen); 509 crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 510 return -EINVAL; 511 } 512 513 flags = crypto_ablkcipher_get_flags(tfm); 514 515 ret = des_ekey(tmp, key); 516 if (unlikely(ret == 0) && (flags & CRYPTO_TFM_REQ_WEAK_KEY)) { 517 crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_RES_WEAK_KEY); 518 dev_dbg(ss->dev, "Weak key %u\n", keylen); 519 return -EINVAL; 520 } 521 522 op->keylen = keylen; 523 memcpy(op->key, key, keylen); 524 return 0; 525} 526 527/* check and set the 3DES key, prepare the mode to be used */ 528int sun4i_ss_des3_setkey(struct crypto_ablkcipher *tfm, const u8 *key, 529 unsigned int keylen) 530{ 531 struct sun4i_tfm_ctx *op = crypto_ablkcipher_ctx(tfm); 532 struct sun4i_ss_ctx *ss = op->ss; 533 534 if (unlikely(keylen != 3 * DES_KEY_SIZE)) { 535 dev_err(ss->dev, "Invalid keylen %u\n", keylen); 536 crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 537 return -EINVAL; 538 } 539 op->keylen = keylen; 540 memcpy(op->key, key, keylen); 541 return 0; 542}