Esempio n. 1
0
int
main(int argc, char **argv)
{
    int rv;
    const char *what;
    const char *filename;
    const char *outname;

    TheImg4 *img4;
    unsigned type;
    unsigned written;
    unsigned char ivkey[16 + 32];
    unsigned char *iv = NULL, *key = NULL;
    unsigned char *output = NULL;
    unsigned outlen = 0;
    int outdup = 0;

    DERItem item;
    unsigned char *data;
    size_t size;

    if (argc < 4) {
        fprintf(stderr, "usage: %s {-image|-extra|-keybag|-ticket} input output [ivkey]\n", argv[0]);
        return 1;
    }

    what = argv[1];
    filename = argv[2];
    outname = argv[3];
    if (argc > 4) {
        rv = str2hex(sizeof(ivkey), ivkey, argv[4]);
        if (rv == sizeof(ivkey)) {
            iv = ivkey;
            key = ivkey + 16;
        }
    }

    data = read_file(filename, 0, &size);
    if (data == NULL) {
        fprintf(stderr, "[e] cannot read '%s'\n", filename);
        return -1;
    }

    img4 = parse(data, size);
    if (!img4) {
        fprintf(stderr, "[e] cannot parse '%s'\n", filename);
        free(data);
        return -1;
    }

    rv = Img4DecodeGetPayloadType(img4, &type);
    if (rv) {
        fprintf(stderr, "[e] cannot identify '%s'\n", filename);
        goto err;
    }
    printf("%c%c%c%c\n", FOURCC(type));

    if (!strncmp(what, "-i", 2) || !strncmp(what, "-e", 2)) {
        int decompress;

        rv = Img4DecodeGetPayload(img4, &item);
        if (rv) {
            fprintf(stderr, "[e] cannot extract payload from '%s'\n", filename);
            goto err;
        }
        output = item.data;
        outlen = item.length;

        if (iv && key) {
            if (outlen & 15) {
                unsigned usize = (outlen + 15) & ~15;
                unsigned char *tmp = calloc(1, usize);
                if (!tmp) {
                    fprintf(stderr, "[e] out of memory %u\n", usize);
                    goto err;
                }
                memcpy(tmp, output, outlen);
                OUTSET(tmp);
            }

            rv = Img4DecodeGetPayloadKeybag(img4, &item);
            if (rv || item.length == 0) {
                fprintf(stderr, "[w] image '%s' has no keybag\n", filename);
            }
#ifdef USE_CORECRYPTO
            cccbc_one_shot(ccaes_cbc_decrypt_mode(), 32, key, iv, (outlen + 15) / 16, output, output);
#else
            AES_KEY decryptKey;
            AES_set_decrypt_key(key, 256, &decryptKey);
            AES_cbc_encrypt(output, output, (outlen + 15) & ~15, &decryptKey, iv, AES_DECRYPT);
#endif
        }

#ifdef iOS10
        if (img4->payload.compression.data && img4->payload.compression.length) {
            DERItem tmp[2];
            uint32_t deco = 0;
            uint64_t usize = 0;
            if (DERParseSequenceContent(&img4->payload.compression, 2, DERImg4PayloadItemSpecs10c, tmp, 0) ||
                DERParseInteger(&tmp[0], &deco) || DERParseInteger64(&tmp[1], &usize)) {
                fprintf(stderr, "[e] cannot get decompression info\n");
                goto err;
            }
            if (deco == 1 && what[1] == 'i') {
                size_t asize = lzfse_decode_scratch_size();
                unsigned char *dec, *aux = malloc(asize);
                if (!aux) {
                    fprintf(stderr, "[e] out of memory %zu\n", asize);
                    goto err;
                }
                dec = malloc(usize + 1);
                if (!dec) {
                    fprintf(stderr, "[e] out of memory %llu\n", usize + 1);
                    free(aux);
                    goto err;
                }
                outlen = lzfse_decode_buffer(dec, usize + 1, output, outlen, aux);
                free(aux);
                if (outlen != usize) {
                    fprintf(stderr, "[e] decompression error\n");
                    free(dec);
                    goto err;
                }
                OUTSET(dec);
            }
        }
#endif
        decompress = (DWORD_BE(output, 0) == 'comp' && DWORD_BE(output, 4) == 'lzss');
        if (decompress && what[1] == 'i') {
            uint32_t csize = DWORD_BE(output, 16);
            uint32_t usize = DWORD_BE(output, 12);
            uint32_t adler = DWORD_BE(output, 8);
            unsigned char *dec = malloc(usize);
            if (outlen > 0x180 + csize) {
                fprintf(stderr, "[i] extra 0x%x bytes after compressed chunk\n", outlen - 0x180 - csize);
            }
            if (!dec) {
                fprintf(stderr, "[e] out of memory %u\n", usize);
                goto err;
            }
            outlen = decompress_lzss(dec, output + 0x180, csize);
            if (adler != lzadler32(dec, outlen)) {
                fprintf(stderr, "[w] adler32 mismatch\n");
            }
            OUTSET(dec);
        } else if (decompress) {
            uint32_t csize = DWORD_BE(output, 16);
            uint32_t usize = outlen - 0x180 - csize;
            if (outlen > 0x180 + csize) {
                unsigned char *dec = malloc(usize);
                if (!dec) {
                    fprintf(stderr, "[e] out of memory %u\n", usize);
                    goto err;
                }
                memcpy(dec, output + 0x180 + csize, usize);
                outlen = usize;
                OUTSET(dec);
            } else {
                OUTSET(NULL);
            }
        } else if (what[1] == 'e') {
            OUTSET(NULL);
        }
        if (!output) {
            fprintf(stderr, "[e] nothing to do\n");
            goto err;
        }
    }
    if (!strncmp(what, "-k", 2)) {
        rv = Img4DecodeGetPayloadKeybag(img4, &item);
        if (rv == 0 && item.length) {
            output = item.data;
            outlen = item.length;
        } else {
            fprintf(stderr, "[e] image '%s' has no keybag\n", filename);
            goto err;
        }
    }
    if (!strncmp(what, "-t", 2)) {
        bool exists = false;
        rv = Img4DecodeManifestExists(img4, &exists);
        if (rv == 0 && exists) {
            output = img4->manifestRaw.data;
            outlen = img4->manifestRaw.length;
        } else {
            fprintf(stderr, "[e] image '%s' has no ticket\n", filename);
            goto err;
        }
    }

    written = write_file(outname, output, outlen);
    if (written != outlen) {
        fprintf(stderr, "[e] cannot write '%s'\n", outname);
        goto err;
    }

    rv = 0;
out:
    if (outdup) {
        free(output);
    }
    free(img4);
    free(data);
    return rv;

err:
    rv = -1;
    goto out;
}
Esempio n. 2
0
// Test the AES CBC mode
static int AES_CBC_POST()
{
	size_t key128Length = 16;
	size_t key192Length = 24;
	size_t key256Length = 32;
	
	typedef struct 
	{
		size_t				keyLength;
		int                 forEncryption;
		unsigned char*		keyData;
		unsigned char*		ivData;
		unsigned char*		inputData;
		unsigned char*		outputData;
	} testData;
	
	// AES 128 Encryption Test Data
	unsigned char* key128EncryptBuffer = (unsigned char*)"\x34\x49\x1b\x26\x6d\x8f\xb5\x4c\x5c\xe1\xa9\xfb\xf1\x7b\x09\x8c";
	unsigned char* iv128EncryptBuffer = (unsigned char*)"\x9b\xc2\x0b\x29\x51\xff\x72\xd3\xf2\x80\xff\x3b\xd2\xdc\x3d\xcc";
	unsigned char* input128EncryptBuffer = (unsigned char*)"\x06\xfe\x99\x71\x63\xcb\xcb\x55\x85\x3e\x28\x57\x74\xcc\xa8\x9d";
#ifdef FORCE_FAIL
	unsigned char* output128EncryptBuffer = (unsigned char*)"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f";
#else	
	unsigned char* output128EncryptBuffer = (unsigned char*)"\x32\x5d\xe3\x14\xe9\x29\xed\x08\x97\x87\xd0\xa2\x05\xd1\xeb\x33";
#endif	
	// AES 128 Decryption Test Data
	unsigned char* key128DecryptBuffer = (unsigned char*)"\xc6\x8e\x4e\xb2\xca\x2a\xc5\xaf\xee\xac\xad\xea\xa3\x97\x11\x94";
	unsigned char* iv128DecryptBuffer = (unsigned char*)"\x11\xdd\x9d\xa1\xbd\x22\x3a\xcf\x68\xc5\xa1\xe1\x96\x4c\x18\x9b";
	unsigned char* input128DecryptBuffer = (unsigned char*)"\xaa\x36\x57\x9b\x0c\x72\xc5\x28\x16\x7b\x70\x12\xd7\xfa\xf0\xde";
	unsigned char* output128DecryptBuffer = (unsigned char*)"\x9e\x66\x1d\xb3\x80\x39\x20\x9a\x72\xc7\xd2\x96\x40\x66\x88\xf2";
    
    // AES 192 Encryption Test Data
	unsigned char* key192EncryptBuffer = (unsigned char*)"\x05\x85\xfc\xe6\xa9\x8c\x54\xd7\x2a\x4d\x7d\x53\x13\xbd\xeb\x0c\x1c\x42\xbc\xba\xf1\x68\x9b\x6b";	
	unsigned char* iv192EncryptBuffer = (unsigned char*)"\xf5\xc8\x5d\x21\x3c\xe2\x7e\xb2\xea\xf6\x29\x3c\xee\x44\x6f\x18";
	unsigned char* input192EncryptBuffer = (unsigned char*)"\x5b\xb1\x61\xa5\x8d\xa6\x18\xfc\x55\x2d\x28\x23\x21\x4b\x8e\xee";
	unsigned char* output192EncryptBuffer = (unsigned char*)"\x34\x91\xb7\xa7\x88\x67\x71\xf7\xc8\x0d\x85\x95\x4d\x6f\x7f\x28";
	
	// AES 192 Decryption Test Data
	unsigned char* key192DecryptBuffer = (unsigned char*)"\x05\x8f\x89\xc4\xc9\x09\x0c\xad\x01\xd1\xa9\x37\x7f\x3f\xea\x14\x42\x24\xea\x49\x4b\x53\xc2\xd5";
	unsigned char* iv192DecryptBuffer = (unsigned char*)"\xb8\xb1\x88\x69\x88\x18\x10\xdd\x4a\xb4\xd1\x19\x55\x94\x70\xc2";
	unsigned char* input192DecryptBuffer = (unsigned char*)"\x12\xb9\xd4\x81\xeb\x0c\x7b\xe3\xfd\x6a\xe7\x55\xc9\xde\x3f\x6f";
	unsigned char* output192DecryptBuffer = (unsigned char*)"\x7e\xb8\x86\x01\xa8\xb4\x85\x60\x5e\xbe\x7d\x88\x95\x75\xea\x94";
	
	// AES 256 Encryption Test Data
	unsigned char* key256EncryptBuffer = (unsigned char*)"\xcd\x53\x9b\x65\x93\x19\x45\xb9\xe8\x65\xbc\x80\x4c\x4b\x16\x89\x24\x29\x8c\x3e\x02\xd9\xda\x79\x27\x2b\xe5\x99\x47\x92\xa0\xd4";
	unsigned char* iv256EncryptBuffer = (unsigned char*)"\x0d\x52\xe3\x43\x57\x31\x4e\x28\x78\xa0\xca\x96\xc5\x32\xef\xd8";
	unsigned char* input256EncryptBuffer = (unsigned char*)"\x17\x55\xb7\x73\x0b\x8c\x1c\x65\x0b\x42\x13\x70\x5b\x3e\x9c\xa2";
	unsigned char* output256EncryptBuffer = (unsigned char*)"\x48\x8f\x47\x28\xa5\xac\xd5\x19\x84\x11\x0a\x23\x37\x49\x37\x30";
	
	// AES 256 Decryption Test Data	
	unsigned char* key256DecryptBuffer = (unsigned char*)"\x10\x42\x2a\x2a\x6c\x95\x41\xf4\x25\x63\x29\x88\xcb\x91\x83\x10\xab\xc5\xab\x8d\x96\x1c\x98\x27\xe4\x20\x04\xc1\xb9\xf4\xcd\xd1";
	unsigned char* iv256DecryptBuffer = (unsigned char*)"\x0b\xf1\x8e\xba\x5e\x67\x1f\x71\x3c\x06\xd7\xc3\x15\x4c\xd4\xa9";
	unsigned char* input256DecryptBuffer = (unsigned char*)"\xcc\x1b\xbc\x58\x78\xef\xf3\xde\xa7\x61\xde\x94\x5e\xf2\x50\x12";
	unsigned char* output256DecryptBuffer = (unsigned char*)"\x61\xb7\x6a\x6d\xce\xaf\xc6\xae\xc1\xc3\x8d\xf3\x4a\xab\x49\x97";
	
	testData dataToTest[] =
	{
		{key128Length, 1, key128EncryptBuffer, iv128EncryptBuffer, input128EncryptBuffer, output128EncryptBuffer},
		{key128Length, 0, key128DecryptBuffer, iv128DecryptBuffer, input128DecryptBuffer, output128DecryptBuffer},
		{key192Length, 1, key192EncryptBuffer, iv192EncryptBuffer, input192EncryptBuffer, output192EncryptBuffer},
		{key192Length, 0, key192DecryptBuffer, iv192DecryptBuffer, input192DecryptBuffer, output192DecryptBuffer},
		{key256Length, 1, key256EncryptBuffer, iv256EncryptBuffer, input256EncryptBuffer, output256EncryptBuffer},
		{key256Length, 0, key256DecryptBuffer, iv256DecryptBuffer, input256DecryptBuffer, output256DecryptBuffer}
	};
    
    const struct ccmode_cbc* mode_enc = ccaes_cbc_encrypt_mode();
	const struct ccmode_cbc* mode_dec = ccaes_cbc_decrypt_mode();
	
	
    struct {
        const struct ccmode_cbc*	enc_mode_ptr;
		const struct ccmode_cbc*	dec_mode_ptr;
    } impl[] = {
        {mode_enc, mode_dec},
    };
	
	int memCheckResult = 0;
	unsigned char outputBuffer[CCAES_BLOCK_SIZE];
	
	int numDataToTest = 6;
	int numModesToTest = 1;
	
	for (int iCnt = 0; iCnt < numDataToTest; iCnt++)
	{
		for(int jCnt = 0; jCnt < numModesToTest; jCnt++)
		{
			
			cccbc_one_shot((dataToTest[iCnt].forEncryption ? 
                            impl[jCnt].enc_mode_ptr : 
                            impl[jCnt].dec_mode_ptr), 
		                   dataToTest[iCnt].keyLength, dataToTest[iCnt].keyData,
						   dataToTest[iCnt].ivData,
						   1, /* Only 1 block */
						   dataToTest[iCnt].inputData, outputBuffer);
            
			memCheckResult = (0 == memcmp(dataToTest[iCnt].outputData, outputBuffer, CCAES_BLOCK_SIZE));
            
            
			if (!memCheckResult)
			{
				return -1;
			}
		}
	}
	return 0;		
}