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

axcrypt2-opencl "Call parameter type does not match function signature!" #5711

Open
solardiz opened this issue Mar 24, 2025 · 1 comment
Open

Comments

@solardiz
Copy link
Member

As seen with ancient Intel OpenCL on "super". I think this is a real bug. I'm not sure which exact kernel and parameter this refers to (it doesn't say, so it'll take a bit of effort to find out), but looking at opencl_axcrypt2_fmt_plug.c I see we allocate mem_salt as buffer of axcrypt2_salt_t, but then we reuse it twice: with crypt_kernel and with final_kernel. While axcrypt2_kernel.cl final_kernel does expect a __constant axcrypt2_salt_t *salt, which is hopefully the same type, we reuse a shared PBKDF2 kernel that expects its own salt type. While that type is made the first field of axcrypt2_salt_t, that may not be good enough per OpenCL spec and for all implementations.

Indeed, these related structs are of different size, so if we're talking an array of them, then wouldn't elements starting with the 2nd be at wrong offsets for one of the kernels? Yet somehow this works on most devices, so I guess their OpenCL runtimes implement buffers by passing individual element offsets or something. But are they required to?

I wonder if this format works with recent Intel OpenCL.

@magnumripper
Copy link
Member

Indeed, these related structs are of different size, so if we're talking an array of them, then wouldn't elements starting with the 2nd be at wrong offsets for one of the kernels?

Not sure what you mean with array, or why their respective sizes would matter at all: We only have one active salt, no array. The axcrypt2 kernel parameter is a pointer to the axcrypt2 salt struct transferred to GPU. The first member of that struct is another struct (not a pointer, a full pbkdf2 struct at start of the axcrypt struct).

typedef struct {
	uint64_t salt[(PBKDF2_64_MAX_SALT_SIZE + 1 + 4 + 7) / 8];
	uint32_t length;
	uint32_t rounds;
} salt_t;

typedef struct {
	salt_t pbkdf2;
	uint key_wrapping_rounds;
	uchar salt[64];
	uint wrappedkey[144/4];
} axcrypt2_salt_t;

axcrypt2(... __constant axcrypt2_salt_t *salt ...)

pbkdf2_sha512_kernel(... __constant salt_t *gsalt ...)

We do similar piggybacking in a good number of formats, predominantly non-looped PBKDF2-HMAC-SHA1 ones. It's been like that since 2012 or something. I'm not saying that makes it better but it's a data point. The majority of them work fine on nearly all devices, even lemon macOS runtimes.

Effectively this means (kosher or not) that when we send this "superstruct" *salt pointer as used by axcrypt2, to the pbkdf2 kernel instead, it will dereference it to what it thinks is a salt_t with nothing after it.

For the axcrypt2 side of it, this is all completely valid afaics. Just a struct within a struct. It can access length using salt->pbkdf2.length if it wanted to. But the pbkdf2 kernel doesn't even know about the outer struct so would call it gsalt->length and get to the very same data.

It's not any different than having a struct that starts with a string array, and then printf("%s", (char*)&struct) instead of printf("%s", struct.string). Not quite right, but it will work just fine.

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

No branches or pull requests

2 participants