> From: owner-openssl-us...@openssl.org On Behalf Of ?? > Sent: Friday, 02 July, 2010 00:10
> Thank you for your detailed explanation. However, I still confused with > those "optimized" line, which also occurs in the verification process. > Here is the code to get a public key from the corresponding certificate, > which follows your suggestions about EVP. Well, on the X.509 side you don't have a choice; the pubkey in a cert is necessarily generic=EVP. > OpenSSL_add_all_algorithms(); > BIO *cert; > X509 *x; > EVP_PKEY *evp_key; > RSA *pKey_pub = NULL; > cert = BIO_new_file("cacert.pem", "rb"); > pKey_pub = RSA_new(); > x = X509_new(); > x = PEM_read_bio_X509(cert, &x, NULL, NULL); > evp_key = X509_get_pubkey(x); > pKey_pub = EVP_PKEY_get1_RSA(evp_key); > I even can not make "x = X509_new()" executed, which always > been optimized out. If the process is correct, I am not sure if > my code has other holes to lead this problem. Thank you so much. What exactly do you mean by "optimized out"? As I said this shouldn't be deleted entirely, since it is used. But it's possible that the optimizer could rearrange the code enough that nothing is *labelled* with that line number. Note this differs slightly from the RSAprivate case because read__X509 *can* use an existing object, although it *can* also create a new object which I suggested as the better practice. I believe recent versions of the GCC suite can do whole-program optimization in at least some cases, but I thought not without being asked specifically, and even if they did here that value is truly used and couldn't be optimized away. I tried a slightly simplified version of your code on the most convenient system, which is gcc 3.4.4 x86 (Linux), with -O2. Even without any use of the result it executes as expected: (gdb) list 9,16 9 BIO * cert = BIO_new_file ("cacert.pem", "rb"); 10 X509 *x; 11 x = X509_new(); 12 x = PEM_read_bio_X509 (cert,&x,NULL,NULL); 13 //EVP_PKEY *evp_key = X509_get_pubkey (x); 14 //RSA *pub = EVP_PKEY_get1_RSA (evp_key); 15 //printf ("length %d\n", RSA_size(pub)); 16 return 0; (gdb) info line 9 Line 9 of "xiang.c" starts at address 0x80492b3 <main+11> and ends at 0x80492c4 <main+28>. (gdb) info line 10 Line 10 of "xiang.c" is at address 0x80492c4 <main+28> but contains no code. (gdb) info line 11 Line 11 of "xiang.c" starts at address 0x80492c4 <main+28> and ends at 0x80492c9 <main+33>. (gdb) info line 12 Line 12 of "xiang.c" starts at address 0x80492c9 <main+33> and ends at 0x80492cd <main+37>. (gdb) info line 16 Line 16 of "xiang.c" is at address 0x80492da <main+50> but contains no code. (gdb) disass main Dump of assembler code for function main: 0x080492a8 <main+0>: push %ebp 0x080492a9 <main+1>: mov %esp,%ebp 0x080492ab <main+3>: push %ebx 0x080492ac <main+4>: push %eax 0x080492ad <main+5>: and $0xfffffff0,%esp 0x080492b0 <main+8>: sub $0x18,%esp 0x080492b3 <main+11>: push $0x80b7648 0x080492b8 <main+16>: push $0x80b764b 0x080492bd <main+21>: call 0x8049300 <BIO_new_file> 0x080492c2 <main+26>: mov %eax,%ebx 0x080492c4 <main+28>: call 0x804b7c0 <X509_new> 0x080492c9 <main+33>: push $0x0 0x080492cb <main+35>: push $0x0 0x080492cd <main+37>: mov %eax,0xfffffff8(%ebp) 0x080492d0 <main+40>: lea 0xfffffff8(%ebp),%eax 0x080492d3 <main+43>: push %eax 0x080492d4 <main+44>: push %ebx 0x080492d5 <main+45>: call 0x8050780 <PEM_read_bio_X509> 0x080492da <main+50>: xor %eax,%eax 0x080492dc <main+52>: mov 0xfffffffc(%ebp),%ebx 0x080492df <main+55>: leave 0x080492e0 <main+56>: ret End of assembler dump. (gdb) b 16 Breakpoint 1 at 0x80492da: file xiang.c, line 16. (gdb) r Starting program: /home1/dthomps/CSdev/hack/xiang Breakpoint 1, main () at xiang.c:17 17 } (gdb) p *x $1 = {cert_info = 0x80d7318, sig_alg = 0x80d7498, signature = 0x80d74a8, valid = 0, references = 1, name = 0x80d87c0 "/C=US/ST=NJ/L=Princeton/O=Dave/OU=DSA test/CN=dsatest", ex_data = {sk = 0x0, dummy = 0}, ex_pathlen = -1, ex_pcpathlen = 0, ex_flags = 0, ex_kusage = 0, ex_xkusage = 0, ex_nscert = 0, skid = 0x0, akid = 0x0, policy_cache = 0x0, sha1_hash = '\0' <repeats 19 times>, aux = 0x0} (gdb) Note that the second instruction implementing line 11 namely the store at main+37, is deferred to the middle of the code implementing line 12, and thus the code from main+37 to main+50 isn't in the 'official' range for any line but nevertheless gets executed and does the right thing. The return value from PEM_read_bio_X509 is dead and doesn't actually get stored, but it happens to be the same as the previously stored x. (Though I'm not sure what main+52 is supposed to be doing.) If your gcc is truly eliding a value that is used, or even worse a call not provably effectless, you should be able to create a minimal example with your own trivial (but separate) routines instead of OpenSSL, and complain to the gcc folks (either trunk or the packager for your distro if that's what you are using). You should search or ask first to see if this is an already known or even already fixed problem for the version you are using. However, you (apparently) ask in another post if -O0 "will be slow". All of the crypto computation is done deep in the OpenSSL library, not in your code. You just call OpenSSL. What matters for speed is how OpenSSL *was* compiled, not how your code is compiled. And on any reasonable general-purpose system today (not e.g. a router or cellphone) unless you're doing hundreds or more PKE operations per second, it's probably fast enough. If you want more exact times/numbers for your build, commandline 'openssl speed $algorithm' will measure that algorithm, or if omitted the 'usual suspects'. ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List openssl-users@openssl.org Automated List Manager majord...@openssl.org