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

Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6:
crypto: padlock - fix VIA PadLock instruction usage with irq_ts_save/restore()
crypto: hash - Add missing top-level functions
crypto: hash - Fix digest size check for digest type
crypto: tcrypt - Fix AEAD chunk testing
crypto: talitos - Add handling for SEC 3.x treatment of link table

+153 -26
+1 -1
crypto/digest.c
··· 225 225 struct ahash_tfm *crt = &tfm->crt_ahash; 226 226 struct digest_alg *dalg = &tfm->__crt_alg->cra_digest; 227 227 228 - if (dalg->dia_digestsize > crypto_tfm_alg_blocksize(tfm)) 228 + if (dalg->dia_digestsize > PAGE_SIZE / 8) 229 229 return -EINVAL; 230 230 231 231 crt->init = digest_async_init;
+19 -9
crypto/tcrypt.c
··· 481 481 482 482 for (k = 0, temp = 0; k < template[i].np; k++) { 483 483 printk(KERN_INFO "page %u\n", k); 484 - q = &axbuf[IDX[k]]; 485 - hexdump(q, template[i].tap[k]); 484 + q = &xbuf[IDX[k]]; 485 + 486 + n = template[i].tap[k]; 487 + if (k == template[i].np - 1) 488 + n += enc ? authsize : -authsize; 489 + hexdump(q, n); 486 490 printk(KERN_INFO "%s\n", 487 - memcmp(q, template[i].result + temp, 488 - template[i].tap[k] - 489 - (k < template[i].np - 1 || enc ? 490 - 0 : authsize)) ? 491 + memcmp(q, template[i].result + temp, n) ? 491 492 "fail" : "pass"); 492 493 493 - for (n = 0; q[template[i].tap[k] + n]; n++) 494 - ; 494 + q += n; 495 + if (k == template[i].np - 1 && !enc) { 496 + if (memcmp(q, template[i].input + 497 + temp + n, authsize)) 498 + n = authsize; 499 + else 500 + n = 0; 501 + } else { 502 + for (n = 0; q[n]; n++) 503 + ; 504 + } 495 505 if (n) { 496 506 printk("Result buffer corruption %u " 497 507 "bytes:\n", n); 498 - hexdump(&q[template[i].tap[k]], n); 508 + hexdump(q, n); 499 509 } 500 510 501 511 temp += template[i].tap[k];
+8
drivers/char/hw_random/via-rng.c
··· 31 31 #include <asm/io.h> 32 32 #include <asm/msr.h> 33 33 #include <asm/cpufeature.h> 34 + #include <asm/i387.h> 34 35 35 36 36 37 #define PFX KBUILD_MODNAME ": " ··· 68 67 * Another possible performance boost may come from simply buffering 69 68 * until we have 4 bytes, thus returning a u32 at a time, 70 69 * instead of the current u8-at-a-time. 70 + * 71 + * Padlock instructions can generate a spurious DNA fault, so 72 + * we have to call them in the context of irq_ts_save/restore() 71 73 */ 72 74 73 75 static inline u32 xstore(u32 *addr, u32 edx_in) 74 76 { 75 77 u32 eax_out; 78 + int ts_state; 79 + 80 + ts_state = irq_ts_save(); 76 81 77 82 asm(".byte 0x0F,0xA7,0xC0 /* xstore %%edi (addr=%0) */" 78 83 :"=m"(*addr), "=a"(eax_out) 79 84 :"D"(addr), "d"(edx_in)); 80 85 86 + irq_ts_restore(ts_state); 81 87 return eax_out; 82 88 } 83 89
+27 -1
drivers/crypto/padlock-aes.c
··· 16 16 #include <linux/interrupt.h> 17 17 #include <linux/kernel.h> 18 18 #include <asm/byteorder.h> 19 + #include <asm/i387.h> 19 20 #include "padlock.h" 20 21 21 22 /* Control word. */ ··· 142 141 asm volatile ("pushfl; popfl"); 143 142 } 144 143 144 + /* 145 + * While the padlock instructions don't use FP/SSE registers, they 146 + * generate a spurious DNA fault when cr0.ts is '1'. These instructions 147 + * should be used only inside the irq_ts_save/restore() context 148 + */ 149 + 145 150 static inline void padlock_xcrypt(const u8 *input, u8 *output, void *key, 146 151 void *control_word) 147 152 { ··· 212 205 static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) 213 206 { 214 207 struct aes_ctx *ctx = aes_ctx(tfm); 208 + int ts_state; 215 209 padlock_reset_key(); 210 + 211 + ts_state = irq_ts_save(); 216 212 aes_crypt(in, out, ctx->E, &ctx->cword.encrypt); 213 + irq_ts_restore(ts_state); 217 214 } 218 215 219 216 static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) 220 217 { 221 218 struct aes_ctx *ctx = aes_ctx(tfm); 219 + int ts_state; 222 220 padlock_reset_key(); 221 + 222 + ts_state = irq_ts_save(); 223 223 aes_crypt(in, out, ctx->D, &ctx->cword.decrypt); 224 + irq_ts_restore(ts_state); 224 225 } 225 226 226 227 static struct crypto_alg aes_alg = { ··· 259 244 struct aes_ctx *ctx = blk_aes_ctx(desc->tfm); 260 245 struct blkcipher_walk walk; 261 246 int err; 247 + int ts_state; 262 248 263 249 padlock_reset_key(); 264 250 265 251 blkcipher_walk_init(&walk, dst, src, nbytes); 266 252 err = blkcipher_walk_virt(desc, &walk); 267 253 254 + ts_state = irq_ts_save(); 268 255 while ((nbytes = walk.nbytes)) { 269 256 padlock_xcrypt_ecb(walk.src.virt.addr, walk.dst.virt.addr, 270 257 ctx->E, &ctx->cword.encrypt, ··· 274 257 nbytes &= AES_BLOCK_SIZE - 1; 275 258 err = blkcipher_walk_done(desc, &walk, nbytes); 276 259 } 260 + irq_ts_restore(ts_state); 277 261 278 262 return err; 279 263 } ··· 286 268 struct aes_ctx *ctx = blk_aes_ctx(desc->tfm); 287 269 struct blkcipher_walk walk; 288 270 int err; 271 + int ts_state; 289 272 290 273 padlock_reset_key(); 291 274 292 275 blkcipher_walk_init(&walk, dst, src, nbytes); 293 276 err = blkcipher_walk_virt(desc, &walk); 294 277 278 + ts_state = irq_ts_save(); 295 279 while ((nbytes = walk.nbytes)) { 296 280 padlock_xcrypt_ecb(walk.src.virt.addr, walk.dst.virt.addr, 297 281 ctx->D, &ctx->cword.decrypt, ··· 301 281 nbytes &= AES_BLOCK_SIZE - 1; 302 282 err = blkcipher_walk_done(desc, &walk, nbytes); 303 283 } 304 - 284 + irq_ts_restore(ts_state); 305 285 return err; 306 286 } 307 287 ··· 334 314 struct aes_ctx *ctx = blk_aes_ctx(desc->tfm); 335 315 struct blkcipher_walk walk; 336 316 int err; 317 + int ts_state; 337 318 338 319 padlock_reset_key(); 339 320 340 321 blkcipher_walk_init(&walk, dst, src, nbytes); 341 322 err = blkcipher_walk_virt(desc, &walk); 342 323 324 + ts_state = irq_ts_save(); 343 325 while ((nbytes = walk.nbytes)) { 344 326 u8 *iv = padlock_xcrypt_cbc(walk.src.virt.addr, 345 327 walk.dst.virt.addr, ctx->E, ··· 351 329 nbytes &= AES_BLOCK_SIZE - 1; 352 330 err = blkcipher_walk_done(desc, &walk, nbytes); 353 331 } 332 + irq_ts_restore(ts_state); 354 333 355 334 return err; 356 335 } ··· 363 340 struct aes_ctx *ctx = blk_aes_ctx(desc->tfm); 364 341 struct blkcipher_walk walk; 365 342 int err; 343 + int ts_state; 366 344 367 345 padlock_reset_key(); 368 346 369 347 blkcipher_walk_init(&walk, dst, src, nbytes); 370 348 err = blkcipher_walk_virt(desc, &walk); 371 349 350 + ts_state = irq_ts_save(); 372 351 while ((nbytes = walk.nbytes)) { 373 352 padlock_xcrypt_cbc(walk.src.virt.addr, walk.dst.virt.addr, 374 353 ctx->D, walk.iv, &ctx->cword.decrypt, ··· 379 354 err = blkcipher_walk_done(desc, &walk, nbytes); 380 355 } 381 356 357 + irq_ts_restore(ts_state); 382 358 return err; 383 359 } 384 360
+9
drivers/crypto/padlock-sha.c
··· 22 22 #include <linux/interrupt.h> 23 23 #include <linux/kernel.h> 24 24 #include <linux/scatterlist.h> 25 + #include <asm/i387.h> 25 26 #include "padlock.h" 26 27 27 28 #define SHA1_DEFAULT_FALLBACK "sha1-generic" ··· 103 102 * PadLock microcode needs it that big. */ 104 103 char buf[128+16]; 105 104 char *result = NEAREST_ALIGNED(buf); 105 + int ts_state; 106 106 107 107 ((uint32_t *)result)[0] = SHA1_H0; 108 108 ((uint32_t *)result)[1] = SHA1_H1; ··· 111 109 ((uint32_t *)result)[3] = SHA1_H3; 112 110 ((uint32_t *)result)[4] = SHA1_H4; 113 111 112 + /* prevent taking the spurious DNA fault with padlock. */ 113 + ts_state = irq_ts_save(); 114 114 asm volatile (".byte 0xf3,0x0f,0xa6,0xc8" /* rep xsha1 */ 115 115 : "+S"(in), "+D"(result) 116 116 : "c"(count), "a"(0)); 117 + irq_ts_restore(ts_state); 117 118 118 119 padlock_output_block((uint32_t *)result, (uint32_t *)out, 5); 119 120 } ··· 128 123 * PadLock microcode needs it that big. */ 129 124 char buf[128+16]; 130 125 char *result = NEAREST_ALIGNED(buf); 126 + int ts_state; 131 127 132 128 ((uint32_t *)result)[0] = SHA256_H0; 133 129 ((uint32_t *)result)[1] = SHA256_H1; ··· 139 133 ((uint32_t *)result)[6] = SHA256_H6; 140 134 ((uint32_t *)result)[7] = SHA256_H7; 141 135 136 + /* prevent taking the spurious DNA fault with padlock. */ 137 + ts_state = irq_ts_save(); 142 138 asm volatile (".byte 0xf3,0x0f,0xa6,0xd0" /* rep xsha256 */ 143 139 : "+S"(in), "+D"(result) 144 140 : "c"(count), "a"(0)); 141 + irq_ts_restore(ts_state); 145 142 146 143 padlock_output_block((uint32_t *)result, (uint32_t *)out, 8); 147 144 }
+39 -15
drivers/crypto/talitos.c
··· 96 96 unsigned int exec_units; 97 97 unsigned int desc_types; 98 98 99 + /* SEC Compatibility info */ 100 + unsigned long features; 101 + 99 102 /* next channel to be assigned next incoming descriptor */ 100 103 atomic_t last_chan; 101 104 ··· 135 132 /* hwrng device */ 136 133 struct hwrng rng; 137 134 }; 135 + 136 + /* .features flag */ 137 + #define TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT 0x00000001 138 138 139 139 /* 140 140 * map virtual single (contiguous) pointer to h/w descriptor pointer ··· 791 785 /* copy the generated ICV to dst */ 792 786 if (edesc->dma_len) { 793 787 icvdata = &edesc->link_tbl[edesc->src_nents + 794 - edesc->dst_nents + 1]; 788 + edesc->dst_nents + 2]; 795 789 sg = sg_last(areq->dst, edesc->dst_nents); 796 790 memcpy((char *)sg_virt(sg) + sg->length - ctx->authsize, 797 791 icvdata, ctx->authsize); ··· 820 814 /* auth check */ 821 815 if (edesc->dma_len) 822 816 icvdata = &edesc->link_tbl[edesc->src_nents + 823 - edesc->dst_nents + 1]; 817 + edesc->dst_nents + 2]; 824 818 else 825 819 icvdata = &edesc->link_tbl[0]; 826 820 ··· 927 921 sg_count = sg_to_link_tbl(areq->src, sg_count, cryptlen, 928 922 &edesc->link_tbl[0]); 929 923 if (sg_count > 1) { 924 + struct talitos_ptr *link_tbl_ptr = 925 + &edesc->link_tbl[sg_count-1]; 926 + struct scatterlist *sg; 927 + struct talitos_private *priv = dev_get_drvdata(dev); 928 + 930 929 desc->ptr[4].j_extent |= DESC_PTR_LNKTBL_JUMP; 931 930 desc->ptr[4].ptr = cpu_to_be32(edesc->dma_link_tbl); 932 931 dma_sync_single_for_device(ctx->dev, edesc->dma_link_tbl, 933 932 edesc->dma_len, DMA_BIDIRECTIONAL); 933 + /* If necessary for this SEC revision, 934 + * add a link table entry for ICV. 935 + */ 936 + if ((priv->features & 937 + TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT) && 938 + (edesc->desc.hdr & DESC_HDR_MODE0_ENCRYPT) == 0) { 939 + link_tbl_ptr->j_extent = 0; 940 + link_tbl_ptr++; 941 + link_tbl_ptr->j_extent = DESC_PTR_LNKTBL_RETURN; 942 + link_tbl_ptr->len = cpu_to_be16(authsize); 943 + sg = sg_last(areq->src, edesc->src_nents ? : 1); 944 + link_tbl_ptr->ptr = cpu_to_be32( 945 + (char *)sg_dma_address(sg) 946 + + sg->length - authsize); 947 + } 934 948 } else { 935 949 /* Only one segment now, so no link tbl needed */ 936 950 desc->ptr[4].ptr = cpu_to_be32(sg_dma_address(areq->src)); ··· 970 944 desc->ptr[5].ptr = cpu_to_be32(sg_dma_address(areq->dst)); 971 945 } else { 972 946 struct talitos_ptr *link_tbl_ptr = 973 - &edesc->link_tbl[edesc->src_nents]; 974 - struct scatterlist *sg; 947 + &edesc->link_tbl[edesc->src_nents + 1]; 975 948 976 949 desc->ptr[5].ptr = cpu_to_be32((struct talitos_ptr *) 977 950 edesc->dma_link_tbl + 978 - edesc->src_nents); 951 + edesc->src_nents + 1); 979 952 if (areq->src == areq->dst) { 980 953 memcpy(link_tbl_ptr, &edesc->link_tbl[0], 981 954 edesc->src_nents * sizeof(struct talitos_ptr)); ··· 982 957 sg_count = sg_to_link_tbl(areq->dst, sg_count, cryptlen, 983 958 link_tbl_ptr); 984 959 } 960 + /* Add an entry to the link table for ICV data */ 985 961 link_tbl_ptr += sg_count - 1; 986 - 987 - /* handle case where sg_last contains the ICV exclusively */ 988 - sg = sg_last(areq->dst, edesc->dst_nents); 989 - if (sg->length == ctx->authsize) 990 - link_tbl_ptr--; 991 - 992 962 link_tbl_ptr->j_extent = 0; 963 + sg_count++; 993 964 link_tbl_ptr++; 994 965 link_tbl_ptr->j_extent = DESC_PTR_LNKTBL_RETURN; 995 966 link_tbl_ptr->len = cpu_to_be16(authsize); ··· 994 973 link_tbl_ptr->ptr = cpu_to_be32((struct talitos_ptr *) 995 974 edesc->dma_link_tbl + 996 975 edesc->src_nents + 997 - edesc->dst_nents + 1); 976 + edesc->dst_nents + 2); 998 977 999 978 desc->ptr[5].j_extent |= DESC_PTR_LNKTBL_JUMP; 1000 979 dma_sync_single_for_device(ctx->dev, edesc->dma_link_tbl, ··· 1061 1040 1062 1041 /* 1063 1042 * allocate space for base edesc plus the link tables, 1064 - * allowing for a separate entry for the generated ICV (+ 1), 1043 + * allowing for two separate entries for ICV and generated ICV (+ 2), 1065 1044 * and the ICV data itself 1066 1045 */ 1067 1046 alloc_len = sizeof(struct ipsec_esp_edesc); 1068 1047 if (src_nents || dst_nents) { 1069 - dma_len = (src_nents + dst_nents + 1) * 1048 + dma_len = (src_nents + dst_nents + 2) * 1070 1049 sizeof(struct talitos_ptr) + ctx->authsize; 1071 1050 alloc_len += dma_len; 1072 1051 } else { ··· 1125 1104 /* stash incoming ICV for later cmp with ICV generated by the h/w */ 1126 1105 if (edesc->dma_len) 1127 1106 icvdata = &edesc->link_tbl[edesc->src_nents + 1128 - edesc->dst_nents + 1]; 1107 + edesc->dst_nents + 2]; 1129 1108 else 1130 1109 icvdata = &edesc->link_tbl[0]; 1131 1110 ··· 1500 1479 err = -EINVAL; 1501 1480 goto err_out; 1502 1481 } 1482 + 1483 + if (of_device_is_compatible(np, "fsl,sec3.0")) 1484 + priv->features |= TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT; 1503 1485 1504 1486 priv->head_lock = kmalloc(sizeof(spinlock_t) * priv->num_channels, 1505 1487 GFP_KERNEL);
+32
include/asm-x86/i387.h
··· 13 13 #include <linux/sched.h> 14 14 #include <linux/kernel_stat.h> 15 15 #include <linux/regset.h> 16 + #include <linux/hardirq.h> 16 17 #include <asm/asm.h> 17 18 #include <asm/processor.h> 18 19 #include <asm/sigcontext.h> ··· 235 234 { 236 235 stts(); 237 236 preempt_enable(); 237 + } 238 + 239 + /* 240 + * Some instructions like VIA's padlock instructions generate a spurious 241 + * DNA fault but don't modify SSE registers. And these instructions 242 + * get used from interrupt context aswell. To prevent these kernel instructions 243 + * in interrupt context interact wrongly with other user/kernel fpu usage, we 244 + * should use them only in the context of irq_ts_save/restore() 245 + */ 246 + static inline int irq_ts_save(void) 247 + { 248 + /* 249 + * If we are in process context, we are ok to take a spurious DNA fault. 250 + * Otherwise, doing clts() in process context require pre-emption to 251 + * be disabled or some heavy lifting like kernel_fpu_begin() 252 + */ 253 + if (!in_interrupt()) 254 + return 0; 255 + 256 + if (read_cr0() & X86_CR0_TS) { 257 + clts(); 258 + return 1; 259 + } 260 + 261 + return 0; 262 + } 263 + 264 + static inline void irq_ts_restore(int TS_state) 265 + { 266 + if (TS_state) 267 + stts(); 238 268 } 239 269 240 270 #ifdef CONFIG_X86_64
+18
include/crypto/hash.h
··· 101 101 return crt->digest(req); 102 102 } 103 103 104 + static inline int crypto_ahash_init(struct ahash_request *req) 105 + { 106 + struct ahash_tfm *crt = crypto_ahash_crt(crypto_ahash_reqtfm(req)); 107 + return crt->init(req); 108 + } 109 + 110 + static inline int crypto_ahash_update(struct ahash_request *req) 111 + { 112 + struct ahash_tfm *crt = crypto_ahash_crt(crypto_ahash_reqtfm(req)); 113 + return crt->update(req); 114 + } 115 + 116 + static inline int crypto_ahash_final(struct ahash_request *req) 117 + { 118 + struct ahash_tfm *crt = crypto_ahash_crt(crypto_ahash_reqtfm(req)); 119 + return crt->final(req); 120 + } 121 + 104 122 static inline void ahash_request_set_tfm(struct ahash_request *req, 105 123 struct crypto_ahash *tfm) 106 124 {