Skip to content
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

segmentation fault retrieving unwrap template #52

Open
freedge opened this issue Aug 14, 2024 · 7 comments
Open

segmentation fault retrieving unwrap template #52

freedge opened this issue Aug 14, 2024 · 7 comments

Comments

@freedge
Copy link

freedge commented Aug 14, 2024

I am trying to set up a private RSA key with an unwrap template. This works but I could not find a way to retrieve the unwrap template from the key. In some instances python cores with segmentation fault:

Reproducer using DPOD and pycryptoki 2.6.6, on Centos Stream 9

sha256sum libs/64/libCryptoki2.so
6c088140bd181c5e23c99d23a84487275969f2984062123ce2e0c00c703b2ccc  libs/64/libCryptoki2.so
import argparse

from pycryptoki.default_templates import *
from pycryptoki.defines import *
from pycryptoki.key_generator import *
from pycryptoki.session_management import *
from pycryptoki.encryption import *
from pycryptoki.object_attr_lookup import *
from pycryptoki.key_generator import c_generate_key_pair_ex
from pycryptoki.mechanism import parse_mechanism
from pycryptoki.utilities import *

parser = argparse.ArgumentParser()
parser.add_argument('--slot', type=int, required=True)
parser.add_argument('--passwordfile', help='file containing the pin', required=True)
args = parser.parse_args()

with open(args.passwordfile, 'r') as f:
    password  = f.read()

with AuthenticatedSession(password, CKU_CRYPTO_OFFICER, slot=args.slot) as auth_session:
    pub_template, priv_template = get_default_key_pair_template(CKM_RSA_PKCS_KEY_PAIR_GEN)
    pub_template = pub_template | {
        CKA_MODULUS_BITS: 2048,
    }

    priv_template = priv_template | {
        CKA_EXTRACTABLE: False,
        CKA_DERIVE: False,
        CKA_MODIFIABLE: False,
        CKA_UNWRAP: True,
        CKA_UNWRAP_TEMPLATE: {
            CKA_EXTRACTABLE: False,
            CKA_PRIVATE: True,
            CKA_SENSITIVE: True,
            CKA_DERIVE: False,
            CKA_MODIFIABLE: False,
            CKA_CLASS: CKO_SECRET_KEY,
            CKA_KEY_TYPE: CKK_AES,
        },
    }

    pubkey, privkey = c_generate_key_pair_ex(auth_session, CKM_RSA_PKCS_KEY_PAIR_GEN, pub_template, priv_template)
    print(c_get_attribute_value_ex(auth_session, privkey, template={CKA_OUID: None}))
    attr = c_get_attribute_value_ex(auth_session, privkey, template={CKA_UNWRAP_TEMPLATE: { CKA_EXTRACTABLE: None} })

on my system this cores with segmentation fault:

Core was generated by `python reproducer.py --slot 3 --passwordfile /dev/fd/63'.
Program terminated with signal SIGSEGV, Segmentation fault.

bt
#0  __memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:331
#1  0x00007fc72aeaa326 in CodeMapper::MassageReturnedAttributeValues(unsigned int, unsigned char*, unsigned int, unsigned char*, unsigned int&) () from /home/frigo/luna/libs/64/libCryptoki2.so
#2  0x00007fc72aeaa8f4 in CodeMapper::UpdateAttributeTemplate(unsigned short, PcmciaProtocol*, unsigned int, unsigned int, CK_ATTRIBUTE*, unsigned int) () from /home/frigo/luna/libs/64/libCryptoki2.so
#3  0x00007fc72ad44098 in PcmciaSlot::GetAttributeValue(unsigned long, unsigned long, CK_ATTRIBUTE*, unsigned long) ()
   from /home/frigo/luna/libs/64/libCryptoki2.so
#4  0x00007fc72ba728d6 in ffi_call_unix64 () at ../src/x86/unix64.S:105
#5  0x00007fc72ba6f556 in ffi_call_int (cif=<optimized out>, fn=<optimized out>, rvalue=<optimized out>, avalue=<optimized out>,
    closure=closure@entry=0x0) at ../src/x86/ffi64.c:672
#6  0x00007fc72ba71f86 in ffi_call (cif=<optimized out>, fn=<optimized out>, rvalue=<optimized out>, avalue=<optimized out>)
    at ../src/x86/ffi64.c:691
#7  0x00007fc72bee81e9 in _call_function_pointer (argtypecount=<optimized out>, argcount=4, resmem=0x7ffdb82d0130,
    restype=<optimized out>, atypes=<optimized out>, avalues=<optimized out>, pProc=0x7fc72ad798d0 <C_GetAttributeValue>,
    flags=4353) at /usr/src/debug/python3.9-3.9.19-4.el9.x86_64/Modules/_ctypes/callproc.c:920
#8  _ctypes_callproc (pProc=<optimized out>, argtuple=argtuple@entry=0x7fc72b715b80, flags=<optimized out>,
    argtypes=argtypes@entry=0x7fc72b715c70, restype=<optimized out>, checker=<optimized out>)
    at /usr/src/debug/python3.9-3.9.19-4.el9.x86_64/Modules/_ctypes/callproc.c:1263

(and the pin token is leaked in the core file)
ckdemo also fails to list the content of the unwrap template btw (attributes are there but value is 0 for all)

...
CKA_UNWRAP_TEMPLATE=
                CKA_PRIVATE 0
                CKA_SENSITIVE 0
                CKA_DERIVE 0
                CKA_EXTRACTABLE 0
                CKA_MODIFIABLE 0
                CKA_CLASS 0
                CKA_KEY_TYPE 0

I also tried with template={CKA_UNWRAP_TEMPLATE: None} which fails with an exception.

@astraw38
Copy link
Contributor

There's a few things going on here:

Don't specify key types in the unwrap template. You can apply other attributes, like modifiable, but the key types, sizes, etc all would be determined by the attr template provided to the C_Unwrap operation.

What was the log entry for generating the key complete w/ attrs? It might be helpful.

re password in core file

The password is encrypted at the boundaries of C_Login. As in, it will be encrypted during that call. Management of the password outside of that scope is left to user. Python in particular is rather difficult to force string vals to be cleared from memory. If you're concerned about that, use salogin to securely authenticate & use application IDs.

I also tried with template={CKA_UNWRAP_TEMPLATE: None} which fails with an exception.

What was the exception? IIRC, that's the preferred way. It's been some years since I've worked on this (almost 10 years!), so I'm a little hazy on the details.

@freedge
Copy link
Author

freedge commented Aug 14, 2024

I provide a reproducer if you wish to dig deeper.
There is no provided example or test of how to do the creation with a wrap template, so I had to guess (the key is created and works fine with the attributes I mention). The segmentation fault indicates a programming error in pycryptoki / libcryptoki that should be addressed there.

@astraw38
Copy link
Contributor

I get that. The segfault appears to be due to memory management when getting attrs. The P11 calling convention means we need to fully create the target data structure(s), of all the appropriate sizes, before calling C_GetAttributeValue. If I had to guess... perhaps it's because it's a nested template that there's something incorrect about the data struct sizing. Whether it's a problem in pycryptoki, libCryptoki, or both remains to be seen. That it's returned empty for ckdemo makes me think it might be a libCryptoki problem, but I'm not sure without digging deeper.

@astraw38
Copy link
Contributor

astraw38 commented Aug 14, 2024

Question for you -- did you try keygen w/ an unwrap template in ckdemo and verified it works too? That'll really help me narrow it down.

@freedge
Copy link
Author

freedge commented Aug 14, 2024

I did not try generating a key with a template through ckdemo, I don't know if the feature is present.

@astraw38
Copy link
Contributor

BTW, what was the exception you got when using CKA_UNWRAP_TEMPLATE: None in the c_get_attribute_value_ex?

@freedge
Copy link
Author

freedge commented Aug 14, 2024

 python reproducer.py  --slot 3  --passwordfile <(echo -n totototo2)
{2147483653: b'111d00002b00000153610900'}
Traceback (most recent call last):
  File "/home/frigo/luna/hsmstufff/reproducer.py", line 47, in <module>
    attr = c_get_attribute_value_ex(auth_session, privkey, template={CKA_UNWRAP_TEMPLATE: None })
  File "/home/frigo/luna/hsmstufff/myenv/lib64/python3.9/site-packages/pycryptoki/exceptions.py", line 61, in luna_function_exception_handle
    return_tuple = luna_function(*args, **kwargs)
  File "/home/frigo/luna/hsmstufff/myenv/lib64/python3.9/site-packages/pycryptoki/object_attr_lookup.py", line 75, in c_get_attribute_value
    c_obj_type = KEY_TRANSFORMS[key_type].ctype
AttributeError: 'function' object has no attribute 'ctype'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants