Updated: April 19, 2023 |
The qcrypto library API includes functions that provide cryptographic signing and verification primitives. Several forms are provided to give you the flexibility of using one that is best suited to your needs.
Cryptographic signatures are useful for protecting assets by allowing an asset's integrity to be verified before it is used. Systems often use these signatures for code signing in secure boot environments.
See the library reference for detailed descriptions of the signing and verification functions.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <qcrypto/qcrypto.h> #include <qcrypto/qcrypto_error.h> #include <qcrypto/qcrypto_keys.h> #include <private/qcrypto/qcrypto_internal.h> int main(void) { int ret; int sig_result = 1; int ver_result = 1; qcrypto_ctx_t *qctx = NULL; qcrypto_ctx_t *qkeyctx = NULL; qcrypto_key_t *qprivkey = NULL; qcrypto_key_t *qpubkey = NULL; const char privkey_hex[] = "2d2d2d2d2d424547494e2050524956415445204b45592d2d2d2d2d0a4d49" "4945764149424144414e42676b71686b6947397730424151454641415343" "424b59776767536941674541416f494241514337322b65305a6173585674" "59480a4636414334587945542f3033674434384f436c6672313233597364" "4f6f7267686a4b56487655433445306971567a327544312f3753776a3879" "702b6a495753360a6d39583862623774756c417533555965662b4d4d704b" "2b46327a4e4651714a376c6c35654c506e6d62714c5036652b6378556830" "68737967456f6f5035646f550a4d3335362f697769644149764f36376c63" "33766174446a4b333748696e2f7a74344a442b66622b6843365861424e33" "6c36664f326c3667424276547572702f490a6f3861384958645663422b4a" "6751785a6f6278563545527231384a5059672b354832393164537733734f" "374330644d73314265707837443143394c792b6f654d0a44714d4d714d71" "45736441413974786d68493855484c42614e6e367a4f77542b50556a3071" "746770715a595058704e686d5969324557314764584356583246410a775a" "45746c417a7241674544416f49424148303952534c7563672b504f566f50" "77414872714667315533705666744c51473555666b382b584c346e423042" "5a640a7734556f3164414d327877364b5236303671654857314d78763849" "57517963536a71684a4b66505269736e6f32576d716c3133444836365349" "69347362464a6b0a50756c7a5555524a77642f78536d694468614d456947" "713342725644357267695646482b7942623441585453644a6a33702b6369" "3049632f792b7870676c6a390a76574f4d396c592f386245594143615244" "635a503339726c575475574e6c426468412f4561345774676f5365625a76" "35576c77763562694d385079755948772b0a6e485a4950557951446a5956" "316f326a4941495a506c4c2f6e58506f47744b5435395a4a435568796832" "49586a525475434f37593761344631455873557877480a42644b364a6647" "6b62695235723835587a675a7153786f4e6b516c494e413355436e6e7579" "6a734367594541395a484e734c7335706c5278754551553643386f0a704e" "377a425353446f676e4e2b7442725a4a794d572f55456730613479627130" "706e676651725772324a4434764c326b756e47305457634a434854694b43" "52570a5264676c50416562505841577851686f664e645933467972555974" "3238744155462f45315643764f4c737a3155544e525837714d704b313774" "6b4261347438560a594c6d6c2f394b61384d6652474850506c502f454437" "3843675945417739615752433377703873364177784c39587a6e75693473" "307851725451742f55332b730a484166756568666e574876616e6a543344" "6c4e394b53465967454e6a776b4563796c4a556774335030507a4f365451" "4a496335386c3344784b5655486d6b66490a536e50695944746173324a63" "6c66634c6162796839366c666b58316a4e794468594834472b7047334f70" "684e4b4d304163764c4c2f4d7a474a6a2b682b72677a0a374862707a6455" "43675945416f37614a49487a52475932684a594b346d736f62474a536941" "3232744672457a2f49727951784d49505534444169386c3239484e0a7846" "415531795048356258374b48357430614569336b53777345337347734c6b" "4c70415930712b38303641504c6757612f65546c3644334869374a505449" "71340a442f596a6a584b4a6449696a6933654c6c53634962636a394a4372" "6e51656f4f514876442f2b47386f4955324545303144662f59436e384367" "594541676f384f0a3242366762397a52563132482b503376305851643467" "31794d317a2f6a502f4945712f30555756453561666e46434e5058754a54" "634d446c71746558317459540a4d597734567a364b69314d306d33674746" "6f6d6f5a50583247343446455955774d614b57367449386435626f592f6f" "486d394d577052755643366a737a3274410a3676367655625a364a78417a" "63496971393079482f64335a627455577079563338766e784d2b4d436759" "4235504f697452706f47364f6a3869635337484175630a416c6b4368782f" "6149636d6532516f396e512f342b446c562b7338395679646533656a3078" "6444497a464e6c384533732b54754437653034524d6839666f6d790a3672" "2b4b58554b756a6f745977636f6434316d2f77433464724d686950516162" "3564794578654854775a513134434c3075673631353579484d64594f624b" "67470a78664c726c506c4d5648714b4166475237546f4b69513d3d0a2d2d" "2d2d2d454e442050524956415445204b45592d2d2d2d2d0a"; const char pubkey_hex[] = "2d2d2d2d2d424547494e205055424c4943204b45592d2d2d2d2d0a4d4949" "424944414e42676b71686b6947397730424151454641414f43415130414d" "49494243414b43415145417539766e744757724631625742786567417546" "380a68452f394e34412b504467705836396474324c4854714b344959796c" "5237314175424e49716c6339726739662b3073492f4d71666f79466b7570" "76562f47322b0a376270514c743147486e2f6a444b53766864737a52554b" "6965355a6558697a35356d36697a2b6e766e4d56496449624d6f424b4b44" "2b586146444e2b657634730a496e51434c7a757535584e37327251347974" "2b7834702f38376543512f6e322f6f51756c3267546435656e7a7470656f" "4151623037713666794b5047764346330a565841666959454d5761473856" "655245613966435432495075523976645855734e374475777448544c4e51" "587163657739517653387671486a41366a444b6a4b0a684c485141506263" "5a6f535046427977576a5a2b737a73452f6a3149394b72594b616d574431" "3654595a6d4974684674526e56776c563968514d47524c5a514d0a367749" "4241773d3d0a2d2d2d2d2d454e44205055424c4943204b45592d2d2d2d2d" "0a"; const char sig_hex[] = "90b605a54006c3eb749c4a03b3cb9ed5cd8ab95fe18f3fd49e0ac0b9544b8" "7f50cb1df831cb095fff5ba1e57460a49709287cca42670ee4fe3ba05d873" "a62b43e92a699a1cf7143586d181e98831bb7159c3fe2346440fe0f83f52c" "096a4fa4ed82274661d1157b6b177475f41bc37318e45ef621b7bd3f31acc" "d7f315bdffa837c696a2b4b8479891a7cd87638837c647f89f35e072bb7fb" "3fced7a5eb4e59637cb445776608e1a1a977dd68616f8115c616bbc39c48d" "05b4f983e7964930b67592ca85f2f12b52defdd4a4daf9b812e3d4696e20e" "3fe044aa731a65aa23dae281e25c985d7f43530488055d5758deff9f5114a" "a14ed39a939402762ff208ee"; const char input_hex[] = "3031323334353637383941424344454631323334"; const size_t privkeysize = (sizeof(privkey_hex)-1)/2; uint8_t privkeybuf[2000]; uint8_t *privkey_bin = privkeybuf; const size_t pubkeysize = (sizeof(pubkey_hex)-1)/2; uint8_t pubkeybuf[sizeof(privkeybuf)]; uint8_t *pubkey_bin = pubkeybuf; const size_t inputsize = (sizeof(input_hex)-1)/2; uint8_t inputbuf[inputsize]; uint8_t *input_bin = inputbuf; const size_t sigsize = (sizeof(sig_hex)-1)/2; uint8_t sig_cmpbuf[sigsize]; uint8_t *sig_cmp = sig_cmpbuf; size_t sigsize_cmp = 0; char sig_cmp_hexbuf[sigsize*2]; char *sig_cmp_hex = sig_cmp_hexbuf; /* Initialize the Qcrypto Library */ ret = qcrypto_init(QCRYPTO_INIT_LAZY, NULL); if (ret != QCRYPTO_R_EOK) { fprintf(stderr, "qcryto_init() failed (%d:%s)\n", ret, qcrypto_strerror(ret)); goto done; } /* Request rsa keygen */ ret = qcrypto_keygen_request("rsa", NULL, 0, &qkeyctx); if (ret != QCRYPTO_R_EOK) { fprintf(stderr, "qcrypto_keygen_request() failed (%d:%s)\n", ret, qcrypto_strerror(ret)); goto done; } /* Initialize signature arguments */ qcrypto_signature_args_t sargs = { .mode = QCRYPTO_SIGNATURE_SIGN, .rsa.pad_mode = QCRYPTO_RSA_PAD_PKCS1v15, .rsa.saltsize = 0, }; /* Request rsa-with-sha256 to sign a signature */ ret = qcrypto_signature_request("rsa-with-sha256", NULL, 0, &qctx); if (ret != QCRYPTO_R_EOK) { fprintf(stderr, "qcrypto_signature_request() failed (%d:%s)\n", ret, qcrypto_strerror(ret)); goto done; } /* Convert privkey */ ret = qcrypto_hex2bin(privkey_bin, privkey_hex, privkeysize); if (ret != QCRYPTO_R_EOK) { fprintf(stderr, "qcrypto_hex2bin() failed (%d:%s)\n", ret, qcrypto_strerror(ret)); goto done; } /* Convert pubkey */ ret = qcrypto_hex2bin(pubkey_bin, pubkey_hex, pubkeysize); if (ret != QCRYPTO_R_EOK) { fprintf(stderr, "qcrypto_hex2bin() failed (%d:%s)\n", ret, qcrypto_strerror(ret)); goto done; } /* Convert input */ ret = qcrypto_hex2bin(input_bin, input_hex, inputsize); if (ret != QCRYPTO_R_EOK) { fprintf(stderr, "qcrypto_hex2bin() failed (%d:%s)\n", ret, qcrypto_strerror(ret)); goto done; } /* Load privkey */ ret = qcrypto_privkey_from_mem(qkeyctx, &qprivkey, privkey_bin, privkeysize, QCRYPTO_KEY_FMT_PEM); if (ret != QCRYPTO_R_EOK) { fprintf(stderr, "qcrypto_privkey_from_mem() failed (%d:%s)\n", ret, qcrypto_strerror(ret)); goto done; } /* Initialize signature signing */ ret = qcrypto_signature_init(qctx, qprivkey, &sargs); if (ret != QCRYPTO_R_EOK) { fprintf(stderr, "qcrypto_signature_init() failed (%d:%s)\n", ret, qcrypto_strerror(ret)); goto done; } /* Compare sig size */ sigsize_cmp = qcrypto_signature_sigsize(qctx); if (sigsize_cmp != sigsize) { fprintf(stderr, "Computed sigsize failed to match with expected sigsize\n"); goto done; } /* Sign the Signature */ qcrypto_memclear(sig_cmp, sigsize_cmp); ret = qcrypto_signature_sign_oneshot(qctx, input_bin, inputsize, sig_cmp, &sigsize_cmp); if (ret != QCRYPTO_R_EOK) { fprintf(stderr, "qcrypto_signature_sign_oneshot() failed (%d:%s)\n", ret, qcrypto_strerror(ret)); goto done; } /* Convert the sig */ qcrypto_bin2hex(sig_cmp_hex, sig_cmp, sigsize); /* Compare the sig results */ sig_result = memcmp(sig_cmp_hex, sig_hex, sigsize); if (sig_result == 0) { printf("Computed sig matches with expected sig\n"); } else { fprintf(stderr, "Computed sig failed to match with expected sig\n"); goto done; } /* Switch to verification mode */ sargs.mode = QCRYPTO_SIGNATURE_VERIFY; /* Load pubkey */ ret = qcrypto_pubkey_from_mem(qkeyctx, &qpubkey, pubkey_bin, pubkeysize, QCRYPTO_KEY_FMT_PEM); if (ret != QCRYPTO_R_EOK) { fprintf(stderr, "qcrypto_pubkey_from_mem() failed (%d:%s)\n", ret, qcrypto_strerror(ret)); goto done; } /* Initialize signature verification */ ret = qcrypto_signature_init(qctx, qpubkey, &sargs); if (ret != QCRYPTO_R_EOK) { fprintf(stderr, "qcrypto_signature_init() failed (%d:%s)\n", ret, qcrypto_strerror(ret)); goto done; } /* Verify the Signature */ ret = qcrypto_signature_verify_oneshot(qctx, input_bin, inputsize, sig_cmp, sigsize, &ver_result); if (ret != QCRYPTO_R_EOK) { fprintf(stderr, "qcrypto_signature_verify_oneshot() failed (%d:%s)\n", ret, qcrypto_strerror(ret)); goto done; } /* Check the verification result */ if (ver_result == 1) { printf("Signature verified\n"); } else { fprintf(stderr, "Signature verification failed\n"); goto done; } goto done; done: /* Release all context handles */ qcrypto_release_ctx(qctx); qcrypto_release_ctx(qkeyctx); /* Release all key handles */ qcrypto_release_key(qprivkey); qcrypto_release_key(qpubkey); /* Uninitialize the Qcrypto Library */ qcrypto_uninit(); return ret; } #if defined(__QNXNTO__) && defined(__USESRCVERSION) #include <sys/srcversion.h> __SRCVERSION("$URL$ $Rev$") #endif