Hi all,

In my epic quest to make NSS encrypt a string, I have managed to successfully create a key from a passphrase, and I have successfully managed to call PK11_CreateContextBySymKey to create an encryption context.

The next error happens at the PK11_CipherOp stage, and resolves to SEC_ERROR_IO, which I understand means "an error has occurred". Unfortunately it gives no more details than that.

Can anyone confirm from the trace below whether any of the parameters used are incorrect, or whether I have missed a step in this process?

The lack of NSS documentation means that I am coding completely in the dark. Much of this code is based on existing code out there (most specifically the weave example and xml-security), and as neither of these are documented either, I am blindly following their recipes, and am still getting nowhere.

In this particular example, I started with SEC_OID_AES_128_ECB, used PK11_AlgtagToMechanism and then PK11_GetPadMechanism to get a cipherMech of 4225 (CKM_AES_ECB).

I then used PK11_CreatePBEV2AlgorithmID to generate a key based on a pbeAlgTag of SEC_OID_AES_128_ECB, a cipherAlgTag based on SEC_OID_AES_128_ECB, and a prfAlgTag SEC_OID_HMAC_SHA1, and this succeeded.

To initialise the encryption I used PK11_GenerateNewParam to create the secParam (as NULL causes failure with no error code), followed by PK11_CreateContextBySymKey using the key and CKM_AES_ECB cipherMech, and this succeeds.

PK11_CipherOp then runs, but fails with SEC_ERROR_IO.

Can anyone see anything wrong with the process so far?

Here is the details gdb trace of the code flow:

Breakpoint 3, crypto_passphrase (p=0x809018, f=0x8090e8, pass=0x116d8 "secret", passLen=6, salt=0x116e0 "salt", saltLen=4, type=KEY_AES_128, mode=MODE_ECB, doPad=1, iterations=4096, k=0xbfffefd4) at crypto/apr_crypto_nss.c:248
248             apr_status_t rv = APR_SUCCESS;
(gdb) next
253         void *wincx = NULL; // what is wincx?
(gdb)
254         apr_crypto_key_t *key = *k;
(gdb)
256         if (!key) {
(gdb)
257             *k = key = apr_pcalloc(p, sizeof(apr_crypto_key_t));
(gdb)
259         if (!key) {
(gdb)
264         switch (type) {
(gdb)
277             if (MODE_CBC == mode) {
(gdb)
281                     key->cipherOid = SEC_OID_AES_128_ECB;
(gdb)
306         key->cipherMech = PK11_AlgtagToMechanism(key->cipherOid);
(gdb)
307         if (doPad) {
(gdb)
308             key->cipherMech = PK11_GetPadMechanism(key->cipherMech);
(gdb)
310         if (key->cipherMech == CKM_INVALID_MECHANISM) {
(gdb)
315         passItem.data = (unsigned char*)pass;
(gdb)
316         passItem.len = passLen;
(gdb)
317         saltItem.data = (unsigned char*)salt;
(gdb)
318         saltItem.len = saltLen;
(gdb)
322 algid = PK11_CreatePBEV2AlgorithmID(key->cipherOid, key->cipherOid, SEC_OID_HMAC_SHA1, 0, iterations, &saltItem);
(gdb) print key->cipherOid
$1 = SEC_OID_AES_128_ECB
(gdb) print key->cipherMech
$2 = 4225
(gdb) print iterations
$3 = 4096
(gdb) next
324         if (algid) {
(gdb)
326             slot = PK11_GetBestSlot(key->cipherMech, wincx);
(gdb)
327             if (slot) {
(gdb)
328 key->symKey = PK11_PBEKeyGen(slot, algid, &passItem, PR_FALSE, wincx);
(gdb)
329                 PK11_FreeSlot(slot);
(gdb)
331             SECOID_DestroyAlgorithmID(algid, PR_TRUE);
(gdb)
335         if (!key->symKey) {
(gdb)
344         return rv;
(gdb) print key->symKey
$4 = (PK11SymKey *) 0x10cd40
(gdb) print *key->symKey
$5 = <incomplete type>
(gdb) cont
Continuing.
-
Breakpoint 2, crypto_block_encrypt_init (p=0x809018, f=0x8090e8, key=0x809118, iv=0xbffff078, ctx=0xbfffefbc, ivSize=0xbffff07c) at crypto/apr_crypto_nss.c:376
376             apr_crypto_block_t *block = *ctx;
(gdb) next
377         if (!block) {
(gdb)
378             *ctx = block = apr_pcalloc(p, sizeof(apr_crypto_block_t));
(gdb)
380         if (!block) {
(gdb)
383         block->factory = f;
(gdb)
384         block->pool = p;
(gdb)
386         apr_pool_cleanup_register(p, block,
(gdb)
390         usedIvSize = PK11_GetIVLength(key->cipherMech);
(gdb)
391         if (usedIvSize) {
(gdb)
414             secParam = PK11_GenerateNewParam(key->cipherMech, key->symKey);
(gdb) print usedIvSize
$6 = 0
(gdb) next
417         block->blockSize = PK11_GetBlockSize(key->cipherMech, secParam);
(gdb)
418 block->ctx = PK11_CreateContextBySymKey(key->cipherMech, CKA_ENCRYPT, key->symKey, secParam);
(gdb)
421         perr = PORT_GetError();
(gdb) print block->blockSize
$7 = 16
(gdb) print block->ctx
$8 = (PK11Context *) 0x10ceb0
(gdb) print key->cipherMech
$9 = 4225
(gdb) next
422         if (perr || !block->ctx) {
(gdb)
428         *ivSize = usedIvSize;
(gdb)
429         return APR_SUCCESS;
(gdb) cont
Continuing.
-
Breakpoint 4, apr_crypto_block_encrypt (driver=0x1e074, ctx=0x809128, out=0xbffff068, outlen=0xbffff06c, in=0x11d34 "plain text string that is a very long string", inlen=45) at crypto/apr_crypto.c:300
300         return driver->block_encrypt(ctx, out, outlen, in, inlen);
(gdb) step

Breakpoint 5, crypto_block_encrypt (block=0x809128, out=0xbffff068, outlen=0xbffff06c, in=0x11d34 "plain text string that is a very long string", inlen=45) at crypto/apr_crypto_nss.c:459
459         int outl = (int) *outlen;
(gdb) next
460         if (!out) {
(gdb)
464         if (!*out) {
(gdb)
465             buffer = apr_palloc(block->pool, inlen + block->blockSize);
(gdb)
466             if (!buffer) {
(gdb)
469             *out = buffer;
(gdb)
472 SECStatus s = PK11_CipherOp(block->ctx, *out, &outl, outl, (unsigned char*)in, inlen);
(gdb)
474         if (s != SECSuccess) {
(gdb)
475             PRErrorCode perr = PORT_GetError();
(gdb)
476             if (perr) {
(gdb)
477                     block->factory->result->rc = perr;
(gdb)
478                     block->factory->result->msg = PR_ErrorToName(perr);
(gdb)
480             return APR_ECRYPT;
(gdb) print s
$10 = SECFailure
(gdb) print block->ctx
$11 = (PK11Context *) 0x10ceb0
(gdb) print perr
$12 = -8192

Regards,
Graham
--

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature

_______________________________________________
dev-tech-crypto mailing list
dev-tech-crypto@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-crypto

Reply via email to