Hi David, I'm afraid I can't provide an exactly matching disassembly of the function since I've since updated to newer -rc kernels. Another debugging hurdle is that the specific kernel code path seems to be triggered by a very specific iwd code path that iwd only uses for 802.1X/EAP-secured networks, and I simply wasn't near any EAP-secured networks in the last few weeks. I've tried creating a reproducer using a bash script calling various keyctl commands but to no success. However, I can provide you a disassembly using my current -rc5 kernel that should correspond to the code path in question along with some observations. Note that I inserted a BUG_ON right before the if statement for testing (that I couldn't get it to trigger yet since I wasn't near any EAP networks in the last weeks). With the BUG_ON, lines 359-364 in crypto/asymmetric_keys/public_key.c look like this: BUG_ON(!sig->pkey_algo); if (strcmp(sig->pkey_algo, "sm2") == 0 && sig->data_size) { ret = cert_sig_digest_update(sig, tfm); if (ret) goto error_free_key; } The relevant disassembly (I've attached the full disassembly): <...> 359 BUG_ON(!sig->pkey_algo); 0xffffffff8158cee9 <+377>: mov 0x30(%rbp),%rsi 0xffffffff8158ceed <+381>: test %rsi,%rsi 0xffffffff8158cef0 <+384>: je 0xffffffff8158d11f <public_key_verify_signature+943> 0xffffffff8158d11f <+943>: ud2 360 if (strcmp(sig->pkey_algo, "sm2") == 0 && sig->data_size) { 0xffffffff8158cef6 <+390>: mov $0xffffffff82c427b0,%rdi 0xffffffff8158cefd <+397>: mov $0x4,%ecx 0xffffffff8158cf02 <+402>: repz cmpsb %es:(%rdi),%ds:(%rsi) 0xffffffff8158cf04 <+404>: seta %al 0xffffffff8158cf07 <+407>: sbb $0x0,%al 0xffffffff8158cf09 <+409>: test %al,%al 0xffffffff8158cf0b <+411>: jne 0xffffffff8158cf18 <public_key_verify_signature+424> 0xffffffff8158cf0d <+413>: mov 0x50(%rbp),%eax 0xffffffff8158cf10 <+416>: test %eax,%eax 0xffffffff8158cf12 <+418>: jne 0xffffffff8158d0df <public_key_verify_signature+879> <...> Some observations: 1. From the Oops report, rsi was zero and seems to be the source of the null pointer. 2. Interpreting the BUG_ON disassembly, rsi is apparently set to sig->pkey_algo. 3. If I recall correctly from the analysis I did right after the Oops, public_key_verify_signature+402 should be the instruction that triggered the Oops. It corresponds to the strcmp. In conclusion, my hypothesis would be that for some reason sig->pkey_algo is a null pointer. This seems plausible since the strcmp would be the first line to actually touch sig->pkey_algo in that function. Take all this with a grain of salt because in theory GCC could have shuffled stuff around since I introduced the BUG_ON. I would love to debug this further, but I'm in dire need of a simpler test case (other than finding another EAP-secured network). If you or anyone could point me to a simple program that uses the public key infrastructure, it might be easier to trigger the Oops again. Kind Regards, Tobias David Howells wrote: > Tobias Markus <tobias@xxxxxxxxxxxxxxxxxxxx> wrote: > >> kernel: RIP: 0010:public_key_verify_signature+0x189/0x3f0 > > Is it possible for you to provide a disassembly of this function from the > kernel you were using? For this to occur on that line, it appears that sig > would need to be NULL - but that should trip an assertion at the top of the > function - or a very small number (which could be RCX, R09 or R11). > > Thanks, > David >
Dump of assembler code for function public_key_verify_signature: crypto/asymmetric_keys/public_key.c: 311 { 0xffffffff8158cd70 <+0>: call 0xffffffff810cb580 <__fentry__> 0xffffffff8158cd75 <+5>: push %r15 0xffffffff8158cd77 <+7>: mov $0x8,%ecx 0xffffffff8158cd7c <+12>: push %r14 0xffffffff8158cd7e <+14>: push %r13 0xffffffff8158cd80 <+16>: push %r12 0xffffffff8158cd82 <+18>: push %rbp 0xffffffff8158cd83 <+19>: push %rbx 0xffffffff8158cd84 <+20>: mov %rdi,%rbx 0xffffffff8158cd87 <+23>: sub $0x100,%rsp 0xffffffff8158cd8e <+30>: mov %gs:0x28,%rax 0xffffffff8158cd97 <+39>: mov %rax,0xf8(%rsp) 0xffffffff8158cd9f <+47>: xor %eax,%eax 0xffffffff8158cda1 <+49>: lea 0x38(%rsp),%r13 312 struct crypto_wait cwait; 313 struct crypto_akcipher *tfm; 314 struct akcipher_request *req; 315 struct scatterlist src_sg[2]; 316 char alg_name[CRYPTO_MAX_ALG_NAME]; 317 char *key, *ptr; 318 int ret; 319 320 pr_devel("==>%s()\n", __func__); 321 322 BUG_ON(!pkey); 0xffffffff8158cda6 <+54>: test %rbx,%rbx 0xffffffff8158cda9 <+57>: movq $0x0,0x10(%rsp) 0xffffffff8158cdb2 <+66>: lea 0x78(%rsp),%r12 0xffffffff8158cdb7 <+71>: mov %r13,%rdi 0xffffffff8158cdba <+74>: movq $0x0,0x18(%rsp) 0xffffffff8158cdc3 <+83>: movq $0x0,0x20(%rsp) 0xffffffff8158cdcc <+92>: movq $0x0,0x28(%rsp) 0xffffffff8158cdd5 <+101>: movq $0x0,0x30(%rsp) 0xffffffff8158cdde <+110>: rep stos %rax,%es:(%rdi) 0xffffffff8158cde1 <+113>: mov $0x10,%ecx 0xffffffff8158cde6 <+118>: mov %r12,%rdi 0xffffffff8158cde9 <+121>: rep stos %rax,%es:(%rdi) 0xffffffff8158cdec <+124>: je 0xffffffff8158d0be <public_key_verify_signature+846> 323 BUG_ON(!sig); 0xffffffff8158cdf2 <+130>: test %rsi,%rsi 0xffffffff8158cdf5 <+133>: mov %rsi,%rbp 0xffffffff8158cdf8 <+136>: je 0xffffffff8158d0c0 <public_key_verify_signature+848> 324 BUG_ON(!sig->s); 0xffffffff8158cdfe <+142>: cmpq $0x0,0x10(%rsi) 0xffffffff8158ce03 <+147>: je 0xffffffff8158d0c2 <public_key_verify_signature+850> 325 326 ret = software_key_determine_akcipher(sig->encoding, 0xffffffff8158ce09 <+153>: mov 0x38(%rsi),%rsi 0xffffffff8158ce0d <+157>: mov %r12,%rcx 0xffffffff8158ce10 <+160>: mov %rbx,%rdx 0xffffffff8158ce13 <+163>: mov 0x40(%rbp),%rdi 0xffffffff8158ce17 <+167>: call 0xffffffff8158ca80 <software_key_determine_akcipher> 327 sig->hash_algo, 328 pkey, alg_name); 329 if (ret < 0) 0xffffffff8158ce1c <+172>: test %eax,%eax 0xffffffff8158ce1e <+174>: js 0xffffffff8158d07e <public_key_verify_signature+782> 330 return ret; 331 332 tfm = crypto_alloc_akcipher(alg_name, 0, 0); 0xffffffff8158ce24 <+180>: xor %edx,%edx 0xffffffff8158ce26 <+182>: xor %esi,%esi 0xffffffff8158ce28 <+184>: mov %r12,%rdi 0xffffffff8158ce2b <+187>: call 0xffffffff8156fa50 <crypto_alloc_akcipher> 333 if (IS_ERR(tfm)) 0xffffffff8158ce30 <+192>: cmp $0xfffffffffffff000,%rax 332 tfm = crypto_alloc_akcipher(alg_name, 0, 0); 0xffffffff8158ce36 <+198>: mov %rax,%r12 ./include/linux/err.h: 36 return IS_ERR_VALUE((unsigned long)ptr); 0xffffffff8158ce39 <+201>: ja 0xffffffff8158d07e <public_key_verify_signature+782> ./include/linux/slab.h: 557 return __kmalloc(size, flags); 0xffffffff8158ce3f <+207>: mov 0x10(%rax),%rax 0xffffffff8158ce43 <+211>: mov $0xcc0,%esi ./include/crypto/akcipher.h: 196 req = kmalloc(sizeof(*req) + crypto_akcipher_reqsize(tfm), gfp); 0xffffffff8158ce48 <+216>: mov -0x8(%rax),%edi 0xffffffff8158ce4b <+219>: add $0x48,%rdi ./include/linux/slab.h: 557 return __kmalloc(size, flags); 0xffffffff8158ce4f <+223>: call 0xffffffff8133e020 <__kmalloc> ./include/crypto/akcipher.h: 197 if (likely(req)) 0xffffffff8158ce54 <+228>: test %rax,%rax ./include/linux/slab.h: 557 return __kmalloc(size, flags); 0xffffffff8158ce57 <+231>: mov %rax,%r14 ./include/crypto/akcipher.h: 197 if (likely(req)) 0xffffffff8158ce5a <+234>: je 0xffffffff8158d0c4 <public_key_verify_signature+852> 136 return &tfm->base; 0xffffffff8158ce60 <+240>: mov 0x8(%rbx),%edx 137 } 138 139 static inline struct akcipher_alg *__crypto_akcipher_alg(struct crypto_alg *alg) 140 { 141 return container_of(alg, struct akcipher_alg, base); 142 } 143 144 static inline struct crypto_akcipher *__crypto_akcipher_tfm( 145 struct crypto_tfm *tfm) 146 { 147 return container_of(tfm, struct crypto_akcipher, base); 148 } 149 150 static inline struct akcipher_alg *crypto_akcipher_alg( 151 struct crypto_akcipher *tfm) 152 { 153 return __crypto_akcipher_alg(crypto_akcipher_tfm(tfm)->__crt_alg); 154 } 155 156 static inline unsigned int crypto_akcipher_reqsize(struct crypto_akcipher *tfm) 157 { 158 return crypto_akcipher_alg(tfm)->reqsize; 159 } 160 161 static inline void akcipher_request_set_tfm(struct akcipher_request *req, 162 struct crypto_akcipher *tfm) 163 { 164 req->base.tfm = crypto_akcipher_tfm(tfm); 0xffffffff8158ce63 <+243>: mov %r12,0x20(%rax) ./include/linux/slab.h: 557 return __kmalloc(size, flags); 0xffffffff8158ce67 <+247>: mov $0xcc0,%esi crypto/asymmetric_keys/public_key.c: 341 key = kmalloc(pkey->keylen + sizeof(u32) * 2 + pkey->paramlen, 0xffffffff8158ce6c <+252>: mov 0x18(%rbx),%eax 0xffffffff8158ce6f <+255>: lea 0x8(%rdx,%rax,1),%rdi ./include/linux/slab.h: 557 return __kmalloc(size, flags); 0xffffffff8158ce74 <+260>: call 0xffffffff8133e020 <__kmalloc> crypto/asymmetric_keys/public_key.c: 343 if (!key) 0xffffffff8158ce79 <+265>: test %rax,%rax ./include/linux/slab.h: 557 return __kmalloc(size, flags); 0xffffffff8158ce7c <+268>: mov %rax,%r15 crypto/asymmetric_keys/public_key.c: 343 if (!key) 0xffffffff8158ce7f <+271>: je 0xffffffff8158d12a <public_key_verify_signature+954> 344 goto error_free_req; 345 346 memcpy(key, pkey->key, pkey->keylen); 0xffffffff8158ce85 <+277>: mov 0x8(%rbx),%edx ./include/linux/string.h: 399 return __underlying_memcpy(p, q, size); 0xffffffff8158ce88 <+280>: mov %rax,%rdi 0xffffffff8158ce8b <+283>: mov (%rbx),%rsi crypto/asymmetric_keys/public_key.c: 346 memcpy(key, pkey->key, pkey->keylen); 0xffffffff8158ce8e <+286>: mov %edx,0xc(%rsp) ./include/linux/string.h: 399 return __underlying_memcpy(p, q, size); 0xffffffff8158ce92 <+290>: mov %rdx,(%rsp) 0xffffffff8158ce96 <+294>: call 0xffffffff81fd7590 <memcpy> crypto/asymmetric_keys/public_key.c: 347 ptr = key + pkey->keylen; 0xffffffff8158ce9b <+299>: mov (%rsp),%rdx 0xffffffff8158ce9f <+303>: mov 0xc(%rbx),%eax ./include/linux/string.h: 399 return __underlying_memcpy(p, q, size); 0xffffffff8158cea2 <+306>: mov 0x10(%rbx),%rsi crypto/asymmetric_keys/public_key.c: 347 ptr = key + pkey->keylen; 0xffffffff8158cea6 <+310>: lea (%r15,%rdx,1),%rdi ./include/linux/string.h: 399 return __underlying_memcpy(p, q, size); 0xffffffff8158ceaa <+314>: mov 0x18(%rbx),%edx 0xffffffff8158cead <+317>: mov %eax,(%rdi) 0xffffffff8158ceaf <+319>: add $0x8,%rdi 0xffffffff8158ceb3 <+323>: mov %edx,-0x4(%rdi) 0xffffffff8158ceb6 <+326>: call 0xffffffff81fd7590 <memcpy> crypto/asymmetric_keys/public_key.c: 352 if (pkey->key_is_private) 0xffffffff8158cebb <+331>: cmpb $0x0,0x1c(%rbx) 0xffffffff8158cebf <+335>: mov 0xc(%rsp),%r8d ./include/crypto/akcipher.h: 414 return alg->set_priv_key(tfm, key, keylen); 0xffffffff8158cec4 <+340>: mov 0x10(%r12),%rax crypto/asymmetric_keys/public_key.c: 352 if (pkey->key_is_private) 0xffffffff8158cec9 <+345>: jne 0xffffffff8158d0a7 <public_key_verify_signature+823> ./include/crypto/akcipher.h: 392 return alg->set_pub_key(tfm, key, keylen); 0xffffffff8158cecf <+351>: mov -0x30(%rax),%rax 0xffffffff8158ced3 <+355>: mov %r8d,%edx 0xffffffff8158ced6 <+358>: mov %r15,%rsi 0xffffffff8158ced9 <+361>: mov %r12,%rdi 0xffffffff8158cedc <+364>: call 0xffffffff82204c40 <__x86_indirect_thunk_rax> crypto/asymmetric_keys/public_key.c: 356 if (ret) 0xffffffff8158cee1 <+369>: test %eax,%eax 0xffffffff8158cee3 <+371>: jne 0xffffffff8158d059 <public_key_verify_signature+745> 357 goto error_free_key; 358 359 BUG_ON(!sig->pkey_algo); 0xffffffff8158cee9 <+377>: mov 0x30(%rbp),%rsi 0xffffffff8158ceed <+381>: test %rsi,%rsi 0xffffffff8158cef0 <+384>: je 0xffffffff8158d11f <public_key_verify_signature+943> 360 if (strcmp(sig->pkey_algo, "sm2") == 0 && sig->data_size) { 0xffffffff8158cef6 <+390>: mov $0xffffffff82c427b0,%rdi 0xffffffff8158cefd <+397>: mov $0x4,%ecx 0xffffffff8158cf02 <+402>: repz cmpsb %es:(%rdi),%ds:(%rsi) 0xffffffff8158cf04 <+404>: seta %al 0xffffffff8158cf07 <+407>: sbb $0x0,%al 0xffffffff8158cf09 <+409>: test %al,%al 0xffffffff8158cf0b <+411>: jne 0xffffffff8158cf18 <public_key_verify_signature+424> 0xffffffff8158cf0d <+413>: mov 0x50(%rbp),%eax 0xffffffff8158cf10 <+416>: test %eax,%eax 0xffffffff8158cf12 <+418>: jne 0xffffffff8158d0df <public_key_verify_signature+879> 361 ret = cert_sig_digest_update(sig, tfm); 362 if (ret) 363 goto error_free_key; 364 } 365 366 sg_init_table(src_sg, 2); 0xffffffff8158cf18 <+424>: mov %r13,%rdi 0xffffffff8158cf1b <+427>: mov $0x2,%esi 0xffffffff8158cf20 <+432>: call 0xffffffff815e2980 <sg_init_table> 367 sg_set_buf(&src_sg[0], sig->s, sig->s_size); 0xffffffff8158cf25 <+437>: mov 0x10(%rbp),%rax 0xffffffff8158cf29 <+441>: mov $0x80000000,%ecx 0xffffffff8158cf2e <+446>: mov 0x18(%rbp),%edx ./include/linux/scatterlist.h: 145 sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf)); 0xffffffff8158cf31 <+449>: mov %eax,%edi 0xffffffff8158cf33 <+451>: and $0xfff,%edi ./arch/x86/include/asm/page_64.h: 20 unsigned long y = x - __START_KERNEL_map; 0xffffffff8158cf39 <+457>: add %rcx,%rax 0xffffffff8158cf3c <+460>: jb 0xffffffff8158d147 <public_key_verify_signature+983> 21 22 /* use the carry flag to determine if x was < __START_KERNEL_map */ 23 x = y + ((x > y) ? phys_base : (__START_KERNEL_map - PAGE_OFFSET)); 0xffffffff8158cf42 <+466>: mov $0xffffffff80000000,%rsi 0xffffffff8158cf49 <+473>: sub 0x17c3b00(%rip),%rsi # 0xffffffff82d50a50 <page_offset_base> 24 25 return x; 0xffffffff8158cf50 <+480>: mov 0x17c3ae9(%rip),%rcx # 0xffffffff82d50a40 <vmemmap_base> 23 x = y + ((x > y) ? phys_base : (__START_KERNEL_map - PAGE_OFFSET)); 0xffffffff8158cf57 <+487>: add %rsi,%rax ./include/linux/scatterlist.h: 145 sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf)); 0xffffffff8158cf5a <+490>: shr $0xc,%rax 0xffffffff8158cf5e <+494>: shl $0x6,%rax 0xffffffff8158cf62 <+498>: lea (%rax,%rcx,1),%rsi 89 unsigned long page_link = sg->page_link & (SG_CHAIN | SG_END); 0xffffffff8158cf66 <+502>: mov 0x38(%rsp),%rax 0xffffffff8158cf6b <+507>: and $0x3,%eax 90 91 /* 92 * In order for the low bit stealing approach to work, pages 93 * must be aligned at a 32-bit boundary as a minimum. 94 */ 95 BUG_ON((unsigned long) page & (SG_CHAIN | SG_END)); 0xffffffff8158cf6e <+510>: test $0x3,%cl 0xffffffff8158cf71 <+513>: jne 0xffffffff8158d121 <public_key_verify_signature+945> 96 #ifdef CONFIG_DEBUG_SG 97 BUG_ON(sg_is_chain(sg)); 98 #endif 99 sg->page_link = page_link | (unsigned long) page; 0xffffffff8158cf77 <+519>: or %rsi,%rax 0xffffffff8158cf7a <+522>: mov $0x80000000,%esi 100 } 101 102 /** 103 * sg_set_page - Set sg entry to point at given page 104 * @sg: SG entry 105 * @page: The page 106 * @len: Length of data 107 * @offset: Offset into page 108 * 109 * Description: 110 * Use this function to set an sg entry pointing at a page, never assign 111 * the page directly. We encode sg table information in the lower bits 112 * of the page pointer. See sg_page() for looking up the page belonging 113 * to an sg entry. 114 * 115 **/ 116 static inline void sg_set_page(struct scatterlist *sg, struct page *page, 117 unsigned int len, unsigned int offset) 118 { 119 sg_assign_page(sg, page); 120 sg->offset = offset; 0xffffffff8158cf7f <+527>: mov %edi,0x40(%rsp) crypto/asymmetric_keys/public_key.c: 368 sg_set_buf(&src_sg[1], sig->digest, sig->digest_size); 0xffffffff8158cf83 <+531>: movzbl 0x28(%rbp),%edi ./include/linux/scatterlist.h: 99 sg->page_link = page_link | (unsigned long) page; 0xffffffff8158cf87 <+535>: mov %rax,0x38(%rsp) 121 sg->length = len; 0xffffffff8158cf8c <+540>: mov 0x20(%rbp),%rax 0xffffffff8158cf90 <+544>: mov %edx,0x44(%rsp) 122 } 123 124 static inline struct page *sg_page(struct scatterlist *sg) 125 { 126 #ifdef CONFIG_DEBUG_SG 127 BUG_ON(sg_is_chain(sg)); 128 #endif 129 return (struct page *)((sg)->page_link & ~(SG_CHAIN | SG_END)); 130 } 131 132 /** 133 * sg_set_buf - Set sg entry to point at given data 134 * @sg: SG entry 135 * @buf: Data 136 * @buflen: Data length 137 * 138 **/ 139 static inline void sg_set_buf(struct scatterlist *sg, const void *buf, 140 unsigned int buflen) 141 { 142 #ifdef CONFIG_DEBUG_SG 143 BUG_ON(!virt_addr_valid(buf)); 144 #endif 145 sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf)); 0xffffffff8158cf94 <+548>: mov %eax,%r8d 0xffffffff8158cf97 <+551>: and $0xfff,%r8d ./arch/x86/include/asm/page_64.h: 20 unsigned long y = x - __START_KERNEL_map; 0xffffffff8158cf9e <+558>: add %rsi,%rax 0xffffffff8158cfa1 <+561>: jb 0xffffffff8158d153 <public_key_verify_signature+995> 21 22 /* use the carry flag to determine if x was < __START_KERNEL_map */ 23 x = y + ((x > y) ? phys_base : (__START_KERNEL_map - PAGE_OFFSET)); 0xffffffff8158cfa7 <+567>: mov $0xffffffff80000000,%rsi 0xffffffff8158cfae <+574>: sub 0x17c3a9b(%rip),%rsi # 0xffffffff82d50a50 <page_offset_base> 24 25 return x; 0xffffffff8158cfb5 <+581>: add %rsi,%rax ./include/linux/scatterlist.h: 145 sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf)); 0xffffffff8158cfb8 <+584>: shr $0xc,%rax 0xffffffff8158cfbc <+588>: shl $0x6,%rax 0xffffffff8158cfc0 <+592>: lea (%rax,%rcx,1),%rsi 89 unsigned long page_link = sg->page_link & (SG_CHAIN | SG_END); 0xffffffff8158cfc4 <+596>: mov 0x58(%rsp),%rax 0xffffffff8158cfc9 <+601>: and $0x3,%eax 90 91 /* 92 * In order for the low bit stealing approach to work, pages 93 * must be aligned at a 32-bit boundary as a minimum. 94 */ 95 BUG_ON((unsigned long) page & (SG_CHAIN | SG_END)); 0xffffffff8158cfcc <+604>: and $0x3,%ecx 0xffffffff8158cfcf <+607>: jne 0xffffffff8158d123 <public_key_verify_signature+947> 96 #ifdef CONFIG_DEBUG_SG 97 BUG_ON(sg_is_chain(sg)); 98 #endif 99 sg->page_link = page_link | (unsigned long) page; 0xffffffff8158cfd5 <+613>: or %rsi,%rax 121 sg->length = len; 0xffffffff8158cfd8 <+616>: mov %edi,0x64(%rsp) ./include/linux/completion.h: 88 init_swait_queue_head(&x->wait); 0xffffffff8158cfdc <+620>: mov $0xffffffff82beaddd,%rsi ./include/crypto/akcipher.h: 254 req->src_len = src_len; 0xffffffff8158cfe3 <+627>: mov %edx,0x40(%r14) ./include/linux/completion.h: 88 init_swait_queue_head(&x->wait); 0xffffffff8158cfe7 <+631>: mov $0xffffffff83ab7a41,%rdx ./include/crypto/akcipher.h: 255 req->dst_len = dst_len; 0xffffffff8158cfee <+638>: mov %edi,0x44(%r14) ./include/linux/completion.h: 88 init_swait_queue_head(&x->wait); 0xffffffff8158cff2 <+642>: lea 0x18(%rsp),%rdi ./include/linux/scatterlist.h: 99 sg->page_link = page_link | (unsigned long) page; 0xffffffff8158cff7 <+647>: mov %rax,0x58(%rsp) 100 } 101 102 /** 103 * sg_set_page - Set sg entry to point at given page 104 * @sg: SG entry 105 * @page: The page 106 * @len: Length of data 107 * @offset: Offset into page 108 * 109 * Description: 110 * Use this function to set an sg entry pointing at a page, never assign 111 * the page directly. We encode sg table information in the lower bits 112 * of the page pointer. See sg_page() for looking up the page belonging 113 * to an sg entry. 114 * 115 **/ 116 static inline void sg_set_page(struct scatterlist *sg, struct page *page, 117 unsigned int len, unsigned int offset) 118 { 119 sg_assign_page(sg, page); 120 sg->offset = offset; 0xffffffff8158cffc <+652>: mov %r8d,0x60(%rsp) ./include/crypto/akcipher.h: 252 req->src = src; 0xffffffff8158d001 <+657>: mov %r13,0x30(%r14) 253 req->dst = dst; 0xffffffff8158d005 <+661>: movq $0x0,0x38(%r14) ./include/linux/completion.h: 87 x->done = 0; 0xffffffff8158d00d <+669>: movl $0x0,0x10(%rsp) 88 init_swait_queue_head(&x->wait); 0xffffffff8158d015 <+677>: call 0xffffffff811923d0 <__init_swait_queue_head> ./include/crypto/akcipher.h: 229 req->base.complete = cmpl; 0xffffffff8158d01a <+682>: movq $0xffffffff81569180,0x10(%r14) 230 req->base.data = data; 0xffffffff8158d022 <+690>: mov %r14,%rdi 0xffffffff8158d025 <+693>: lea 0x10(%rsp),%rax 231 req->base.flags = flgs; 0xffffffff8158d02a <+698>: movl $0x600,0x28(%r14) 230 req->base.data = data; 0xffffffff8158d032 <+706>: mov %rax,0x18(%r14) 256 } 257 258 /** 259 * crypto_akcipher_maxsize() - Get len for output buffer 260 * 261 * Function returns the dest buffer size required for a given key. 262 * Function assumes that the key is already set in the transformation. If this 263 * function is called without a setkey or with a failed setkey, you will end up 264 * in a NULL dereference. 265 * 266 * @tfm: AKCIPHER tfm handle allocated with crypto_alloc_akcipher() 267 */ 268 static inline unsigned int crypto_akcipher_maxsize(struct crypto_akcipher *tfm) 269 { 270 struct akcipher_alg *alg = crypto_akcipher_alg(tfm); 271 272 return alg->max_size(tfm); 273 } 274 275 /** 276 * crypto_akcipher_encrypt() - Invoke public key encrypt operation 277 * 278 * Function invokes the specific public key encrypt operation for a given 279 * public key algorithm 280 * 281 * @req: asymmetric key request 282 * 283 * Return: zero on success; error code in case of error 284 */ 285 static inline int crypto_akcipher_encrypt(struct akcipher_request *req) 286 { 287 struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 288 struct akcipher_alg *alg = crypto_akcipher_alg(tfm); 289 struct crypto_alg *calg = tfm->base.__crt_alg; 290 unsigned int src_len = req->src_len; 291 int ret; 292 293 crypto_stats_get(calg); 294 ret = alg->encrypt(req); 295 crypto_stats_akcipher_encrypt(src_len, ret, calg); 296 return ret; 297 } 298 299 /** 300 * crypto_akcipher_decrypt() - Invoke public key decrypt operation 301 * 302 * Function invokes the specific public key decrypt operation for a given 303 * public key algorithm 304 * 305 * @req: asymmetric key request 306 * 307 * Return: zero on success; error code in case of error 308 */ 309 static inline int crypto_akcipher_decrypt(struct akcipher_request *req) 310 { 311 struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 312 struct akcipher_alg *alg = crypto_akcipher_alg(tfm); 313 struct crypto_alg *calg = tfm->base.__crt_alg; 314 unsigned int src_len = req->src_len; 315 int ret; 316 317 crypto_stats_get(calg); 318 ret = alg->decrypt(req); 319 crypto_stats_akcipher_decrypt(src_len, ret, calg); 320 return ret; 321 } 322 323 /** 324 * crypto_akcipher_sign() - Invoke public key sign operation 325 * 326 * Function invokes the specific public key sign operation for a given 327 * public key algorithm 328 * 329 * @req: asymmetric key request 330 * 331 * Return: zero on success; error code in case of error 332 */ 333 static inline int crypto_akcipher_sign(struct akcipher_request *req) 334 { 335 struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 336 struct akcipher_alg *alg = crypto_akcipher_alg(tfm); 337 struct crypto_alg *calg = tfm->base.__crt_alg; 338 int ret; 339 340 crypto_stats_get(calg); 341 ret = alg->sign(req); 342 crypto_stats_akcipher_sign(ret, calg); 343 return ret; 344 } 345 346 /** 347 * crypto_akcipher_verify() - Invoke public key signature verification 348 * 349 * Function invokes the specific public key signature verification operation 350 * for a given public key algorithm. 351 * 352 * @req: asymmetric key request 353 * 354 * Note: req->dst should be NULL, req->src should point to SG of size 355 * (req->src_size + req->dst_size), containing signature (of req->src_size 356 * length) with appended digest (of req->dst_size length). 357 * 358 * Return: zero on verification success; error code in case of error. 359 */ 360 static inline int crypto_akcipher_verify(struct akcipher_request *req) 361 { 362 struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 363 struct akcipher_alg *alg = crypto_akcipher_alg(tfm); 364 struct crypto_alg *calg = tfm->base.__crt_alg; 365 int ret; 366 367 crypto_stats_get(calg); 368 ret = alg->verify(req); 0xffffffff8158d036 <+710>: mov 0x20(%r14),%rax 0xffffffff8158d03a <+714>: mov 0x10(%rax),%rax 0xffffffff8158d03e <+718>: mov -0x48(%rax),%rax 0xffffffff8158d042 <+722>: call 0xffffffff82204c40 <__x86_indirect_thunk_rax> ./include/linux/crypto.h: 590 switch (err) { 0xffffffff8158d047 <+727>: cmp $0xffffff8d,%eax 0xffffffff8158d04a <+730>: je 0xffffffff8158d104 <public_key_verify_signature+916> 0xffffffff8158d050 <+736>: cmp $0xfffffff0,%eax 0xffffffff8158d053 <+739>: je 0xffffffff8158d104 <public_key_verify_signature+916> crypto/asymmetric_keys/public_key.c: 378 kfree(key); 0xffffffff8158d059 <+745>: mov %r15,%rdi 0xffffffff8158d05c <+748>: mov %eax,(%rsp) 0xffffffff8158d05f <+751>: call 0xffffffff8133c9c0 <kfree> ./include/crypto/akcipher.h: 210 kfree_sensitive(req); 0xffffffff8158d064 <+756>: mov %r14,%rdi 0xffffffff8158d067 <+759>: call 0xffffffff812f0380 <kfree_sensitive> 136 return &tfm->base; 0xffffffff8158d06c <+764>: mov %r12,%rsi 0xffffffff8158d06f <+767>: mov %r12,%rdi 0xffffffff8158d072 <+770>: call 0xffffffff81569610 <crypto_destroy_tfm> crypto/asymmetric_keys/public_key.c: 384 if (WARN_ON_ONCE(ret > 0)) 0xffffffff8158d077 <+775>: mov (%rsp),%eax 0xffffffff8158d07a <+778>: test %eax,%eax 0xffffffff8158d07c <+780>: jg 0xffffffff8158d0d6 <public_key_verify_signature+870> 386 return ret; 387 } 0xffffffff8158d07e <+782>: mov 0xf8(%rsp),%rbx 0xffffffff8158d086 <+790>: sub %gs:0x28,%rbx 0xffffffff8158d08f <+799>: jne 0xffffffff8158d125 <public_key_verify_signature+949> 0xffffffff8158d095 <+805>: add $0x100,%rsp 0xffffffff8158d09c <+812>: pop %rbx 0xffffffff8158d09d <+813>: pop %rbp 0xffffffff8158d09e <+814>: pop %r12 0xffffffff8158d0a0 <+816>: pop %r13 0xffffffff8158d0a2 <+818>: pop %r14 0xffffffff8158d0a4 <+820>: pop %r15 0xffffffff8158d0a6 <+822>: ret ./include/crypto/akcipher.h: 414 return alg->set_priv_key(tfm, key, keylen); 0xffffffff8158d0a7 <+823>: mov %r8d,%edx 0xffffffff8158d0aa <+826>: mov %r15,%rsi 0xffffffff8158d0ad <+829>: mov %r12,%rdi 0xffffffff8158d0b0 <+832>: mov -0x28(%rax),%rax 0xffffffff8158d0b4 <+836>: call 0xffffffff82204c40 <__x86_indirect_thunk_rax> 0xffffffff8158d0b9 <+841>: jmp 0xffffffff8158cee1 <public_key_verify_signature+369> crypto/asymmetric_keys/public_key.c: 322 BUG_ON(!pkey); 0xffffffff8158d0be <+846>: ud2 323 BUG_ON(!sig); 0xffffffff8158d0c0 <+848>: ud2 324 BUG_ON(!sig->s); 0xffffffff8158d0c2 <+850>: ud2 ./include/crypto/akcipher.h: 136 return &tfm->base; 0xffffffff8158d0c4 <+852>: mov %r12,%rsi 0xffffffff8158d0c7 <+855>: mov %r12,%rdi 0xffffffff8158d0ca <+858>: call 0xffffffff81569610 <crypto_destroy_tfm> crypto/asymmetric_keys/public_key.c: 384 if (WARN_ON_ONCE(ret > 0)) 0xffffffff8158d0cf <+863>: mov $0xfffffff4,%eax 0xffffffff8158d0d4 <+868>: jmp 0xffffffff8158d07e <public_key_verify_signature+782> 0xffffffff8158d0d6 <+870>: ud2 385 ret = -EINVAL; 0xffffffff8158d0d8 <+872>: mov $0xffffffea,%eax 0xffffffff8158d0dd <+877>: jmp 0xffffffff8158d07e <public_key_verify_signature+782> 378 kfree(key); 0xffffffff8158d0df <+879>: mov %r15,%rdi 0xffffffff8158d0e2 <+882>: call 0xffffffff8133c9c0 <kfree> ./include/crypto/akcipher.h: 210 kfree_sensitive(req); 0xffffffff8158d0e7 <+887>: mov %r14,%rdi 0xffffffff8158d0ea <+890>: call 0xffffffff812f0380 <kfree_sensitive> 136 return &tfm->base; 0xffffffff8158d0ef <+895>: mov %r12,%rsi 0xffffffff8158d0f2 <+898>: mov %r12,%rdi 0xffffffff8158d0f5 <+901>: call 0xffffffff81569610 <crypto_destroy_tfm> crypto/asymmetric_keys/public_key.c: 384 if (WARN_ON_ONCE(ret > 0)) 0xffffffff8158d0fa <+906>: mov $0xfffffdf4,%eax 0xffffffff8158d0ff <+911>: jmp 0xffffffff8158d07e <public_key_verify_signature+782> ./include/linux/crypto.h: 593 wait_for_completion(&wait->completion); 0xffffffff8158d104 <+916>: lea 0x10(%rsp),%rdi 0xffffffff8158d109 <+921>: call 0xffffffff81fdb650 <wait_for_completion> ./include/linux/completion.h: 100 x->done = 0; 0xffffffff8158d10e <+926>: mov 0x30(%rsp),%eax 0xffffffff8158d112 <+930>: movl $0x0,0x10(%rsp) ./include/linux/crypto.h: 599 return err; 0xffffffff8158d11a <+938>: jmp 0xffffffff8158d059 <public_key_verify_signature+745> crypto/asymmetric_keys/public_key.c: 359 BUG_ON(!sig->pkey_algo); 0xffffffff8158d11f <+943>: ud2 ./include/linux/scatterlist.h: 95 BUG_ON((unsigned long) page & (SG_CHAIN | SG_END)); 0xffffffff8158d121 <+945>: ud2 0xffffffff8158d123 <+947>: ud2 0xffffffff8158d125 <+949>: call 0xffffffff81fd6eb0 <__stack_chk_fail> ./include/crypto/akcipher.h: 210 kfree_sensitive(req); 0xffffffff8158d12a <+954>: mov %r14,%rdi 0xffffffff8158d12d <+957>: call 0xffffffff812f0380 <kfree_sensitive> 136 return &tfm->base; 0xffffffff8158d132 <+962>: mov %r12,%rsi 0xffffffff8158d135 <+965>: mov %r12,%rdi 0xffffffff8158d138 <+968>: call 0xffffffff81569610 <crypto_destroy_tfm> crypto/asymmetric_keys/public_key.c: 384 if (WARN_ON_ONCE(ret > 0)) 0xffffffff8158d13d <+973>: mov $0xfffffff4,%eax 0xffffffff8158d142 <+978>: jmp 0xffffffff8158d07e <public_key_verify_signature+782> ./arch/x86/include/asm/page_64.h: 23 x = y + ((x > y) ? phys_base : (__START_KERNEL_map - PAGE_OFFSET)); 0xffffffff8158d147 <+983>: mov 0x1a8bec2(%rip),%rsi # 0xffffffff83019010 <phys_base> 0xffffffff8158d14e <+990>: jmp 0xffffffff8158cf50 <public_key_verify_signature+480> 0xffffffff8158d153 <+995>: mov 0x1a8beb6(%rip),%rsi # 0xffffffff83019010 <phys_base> 0xffffffff8158d15a <+1002>: jmp 0xffffffff8158cfb5 <public_key_verify_signature+581> End of assembler dump.