-
Notifications
You must be signed in to change notification settings - Fork 186
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Loading libpkcs11.so
from program with statically compiled OpenSSL?
#529
Comments
I don't think OpenSSL's engine API allows for loading engines into a statically linked executable. This is not specific to libp11. Please consider opening an issue on https://github.com/openssl/openssl/ instead. Make sure to check whether there is an existing (possibly already closed) issue about it. |
Thanks! I've looked there and it seems like compiling If I'm not mistaken it would not be trivial to do so however, at least without some gymnastics with autotools |
This comment describes a very special theoretical scenario where your statically linked application exposes all the OpenSSL symbols that are needed by your engine. I don't think your application does that, but it doesn't hurt to check. Also, if you read further comments, nobody seems to have succeeded with a practical implementation of this theoretical scenario. |
Good news:
|
Funnily enough, this could be the case here:
There are lots of symbols, however I'm aware that it might not be everything, depending e.g. on compilation flags. I don't feel comfortable around autotools enough to force Edit: I've just noticed your comment above, I see we've come to similar conclusions |
I guess the dynamic loader should not search for symbols that are already available. If I'm right, no special special linker tricks should be needed. Just make sure to use the same version of OpenSSL (3.0.2) for building libp11. |
After quick looking I've noticed that OpenSSL 3.0.2 is already the default on my Ubuntu 22.04, and this is what I've been compiling
I'll try checking in debugger where do OpenSSL calls go when called from |
I've set breakpoint at this line, stepped few instructions and landed at address 0x7ffff7bbcf70, where
So unfortunately I land on dynamically loaded |
I've tried to recreate roughly what #include <stdio.h>
#include <openssl/engine.h>
int main(int argc, char *argv[]) {
ENGINE *engine;
if (argc != 2) {
printf("Usage: %s <engine_name>\n", argv[0]);
return 1;
}
engine = ENGINE_by_id(argv[1]);
if (!engine) {
printf("Failed to load engine: %s\n", argv[1]);
return 1;
}
if (!ENGINE_init(engine)) {
printf("Failed to initialize engine: %s\n", ENGINE_get_id(engine));
ENGINE_free(engine);
return 1;
}
if (!ENGINE_set_default_RAND(engine)) {
printf("Failed to set engine as default for random number generation.\n");
ENGINE_free(engine);
return 1;
}
unsigned char rand_bytes[16];
if (!RAND_bytes(rand_bytes, sizeof(rand_bytes))) {
printf("Failed to generate random bytes.\n");
ENGINE_free(engine);
return 1;
}
printf("Random bytes generated using engine %s:\n", ENGINE_get_id(engine));
for (int i = 0; i < sizeof(rand_bytes); i++) {
printf("%02x", rand_bytes[i]);
}
printf("\n");
ENGINE_free(engine);
return 0;
} I compile that program with following command:
Where I run it and it works even with my distro's
So what could be the problem with static EX_CALLBACKS *get_and_lock(OSSL_EX_DATA_GLOBAL *global, int class_index,
int read)
{
...
if (global->ex_data_lock == NULL) {
/*
* If we get here, someone (who?) cleaned up the lock, so just
* treat it as an error.
*/
return NULL;
}
... In
My first guess would be that this behavior depends on how symbols are resolved and as a result, where does the default |
Yes, the application and the engine must use the same library. Compiling them against the same version is the essential first step, but then they need to be linked to the same instance, and not only the same version. With two separate libraries, at least one of them won't get properly initialized. Also, passing pointers to objects initialized with one library and using them in another library will very likely break the dependencies assumed by those libraries. |
I also tried this with # Extract hashes
./rk_sign_tool cc --chip px30
./rk_sign_tool lk --pubkey public_key.pem
./rk_sign_tool ss --extract
./rk_sign_tool sf --firmware update.img
cp out/si_usb_head.bin{,.orig}
cp out/si_flash_head.bin{,.orig}
cp out/si_update_hash.bin{,.orig}
# Sign hashes
export PKCS11_MODULE_PATH="..."
for img in si_flash_head.bin si_update_hash.bin si_usb_head.bin; do
openssl pkeyutl -sign \
-engine pkcs11 \
-in "out/$img.orig" \
-out "out/$img" \
-keyform engine \
-inkey "pkcs11:object=mykey" \
-pkeyopt digest:sha256 \
-pkeyopt rsa_padding_mode:pss \
-pkeyopt rsa_pss_saltlen:-1
done
# Inject signatures
./rk_sign_tool ss --inject
./rk_sign_tool sf --firmware update.img Hope this helps. |
I'm trying to set up secure boot signing for Rock 5B board using PKCS#11 and this program: https://github.com/rockchip-linux/rkbin/blob/master/tools/rk_sign_tool
Unfortunately, this program is closed-source and has little to no documentation. All I know is that it has some version of OpenSSL compiled statically and is configured by this file. It is possible to tell it to use chosen OpenSSL engine by setting those lines as follows:
Also, the program expects
openssl.cnf
to be in the same directory as the binary. This is my configuration:The problem is, that in Ubuntu 22.04 (and most likely in any other Linux distro)
libpkcs11.so
is dynamically linked to my distro's OpenSSL. I've found that out after compilinglibp11
myself with debug symbols and hooking it up togdb
, as it fails exactly here: https://github.com/OpenSC/libp11/blob/master/src/eng_front.c#L92From my understanding this is a wrong approach, because I'm basically mixing two versions of OpenSSL now, each of different version and with it's own set of static variables etc.
But what could be a good approach here? Is there any way to convince
libpkcs11.so
to somehow use symbols that are already available, instead of those from my distro'slibcrypto.so
? I've tried configuringlibp11
withLDFLAGS="-Wl,--exclude-libs,all"
, but the behaviour didn't change. Maybe the problem could be hidden completely elsewhere?The text was updated successfully, but these errors were encountered: