Question

All,

I am facing a strange issue with iPhone 5s. I am doing a HMAC-SHA1 encrypting in my app using a third party library. The library uses memcpy, which am not aware what it is, as I am not into too much of memory level programming in C. The encryption works perfectly fine in all iphones except the 64 bit 5s. Below is the code where it crashes (5th line).

void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len)
{
unsigned int i, j;

    j = (context->count[0] >> 3) & 63;
    if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
    context->count[1] += (len >> 29);
    if ((j + len) > 63) {
        memcpy(&context->buffer[j], data, (i = 64-j));
        SHA1Transform(context->state, context->buffer);
        for ( ; i + 63 < len; i += 64) {
            SHA1Transform(context->state, &data[i]);
        }
        j = 0;
    }
    else i = 0;
    memcpy(&context->buffer[j], &data[i], len - i);
}

Below is the crash details

Exception Type: EXC_BAD_ACCESS (SIGSEGV) Exception Subtype: KERN_INVALID_ADDRESS at 0x001a9c799cbfdcf9 Triggered by Thread: 0

Thread 0 Crashed: 0 libsystem_platform.dylib 0x0000000191c34dc8 _platform_memmove + 40 1 Anyvan 0x00000001001fc6a8 SHA1Update (sha1.c:128) 2 Anyvan 0x00000001000c7efc hmac_sha1 (hmac.c:73) 3 Anyvan 0x00000001000fe7cc -[LoginViewController callAuth:] (LoginViewController.m:360)

Any help will be highly appreciated.

Was it helpful?

Solution

This is crashing because you are using int not because of memcpy. Try replacing the int with NSInteger and it should work. You can find more information here.

The iPhone5S uses a 64bit architecture while the others use 32bit. One of the core differences between the two is how the system handles integers as explained in the doc. Your code is using unsigned int which does not mean the same thing on 32bit and on 64bit and that results in a crash. You should change your int called i and j to NSIntegers and I believe your code will work. Or come to think of it you can try to simply replace the word int by long.

OTHER TIPS

I had this same problem when compiling a Twitter+OAuth library for 64 bit platforms. I resolved it by replacing "unsigned long" by "uint32_t" in 7 places in sha1.h and sha1.c. Like this:

#include <stdint.h>
typedef struct {
    uint32_t state[5];
    uint32_t count[2];
    unsigned char buffer[64];
} SHA1_CTX;

You also need to include the stdint.h library (at the top of sha1.h and maybe sha1.c) to make this work. uint32_t is always 32 bits and I think that SHA1's transformation macros like R0 fail when operating on 64 bit data types. So changing to an explicit 32 bit data type fixes it. The answer about memcpy led me to this solution.

Remove support for arm64 if its not that important. Then set NO for "Build Active Architecture Only" (debug and release)

That did the trick for me, I didn't really need any 64bit specific functionality on my app so I took it out.

void CSHA1::Update(UINT_8 *data, long len){}

i just changed len form UINT_32 to long, and it did work, now can run on 4s, 5,5s,6 hah

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top