Beispiel #1
0
/* Subroutine sceDdrdb_driver_B8218473 - Address 0x000028D8 */
s32 sceDdrdbPrngen(u8 *pDstData) 
{
    s32 status;
    s32 tmpStatus;
    u32 i;

    status = SCE_DNAS_ERROR_OPERATION_FAILED; //0x000028FC
    
    status = sceKernelWaitSema(g_semaId, 1, NULL); //0x00002908
    if (status != SCE_ERROR_OK)
        return SCE_ERROR_SEMAPHORE;

    /* Compute a pseudorandom number. */
    tmpStatus = sceUtilsBufferCopyWithRange(g_pWorkData, KIRK_PRN_LEN, NULL, 0, KIRK_CMD_PRN_GEN); //0x00002950
    if (tmpStatus == SCE_ERROR_OK) { //0x00002958

        /* Copy computed number into provided buffer. */
        for (i = 0; i < KIRK_PRN_LEN; i++) //0x00002960 - 0x00002980
            pDstData[i] = g_pWorkData[i]; //0x00002980

        status = SCE_ERROR_OK;
    }
    
    /* Clear the work area. */
    for (i = 0; i < KIRK_PRN_LEN; i++) // 0x00002988 - 0x000029A0
        g_pWorkData[i] = 0; 

    tmpStatus = sceKernelSignalSema(g_semaId, 1); //0x000029A8
    return (tmpStatus != SCE_ERROR_OK) ? SCE_ERROR_SEMAPHORE : status; //0x000029B0 - 0x000029BC
}
Beispiel #2
0
/* Subroutine sceDdrdb_driver_370F456A - Address 0x00002494 */
s32 sceDdrdbCertvry(u8 *pCert) 
{
    s32 status;
    s32 tmpStatus;
    u32 i;
    
    status = sceKernelWaitSema(g_semaId, 1, NULL); //0x000024C4
    if (status != SCE_ERROR_OK)
        return SCE_ERROR_SEMAPHORE; 

    /* Set up the work area. */
    for (i = 0; i < KIRK_CERT_LEN; i++) //0x000024D4 & 0x000024F4
        g_pWorkData[i] = pCert[i]; //0x000024F4

    /* Verify the provided certificate. */
    tmpStatus = sceUtilsBufferCopyWithRange(NULL, 0, g_pWorkData, KIRK_CERT_LEN, KIRK_CMD_CERT_VER); //0x0000250C
    status = (tmpStatus != SCE_ERROR_OK) ? SCE_DNAS_ERROR_OPERATION_FAILED : SCE_ERROR_OK; //0x00002510 - 0x00002518

    /* Clear the work area. */
    for (i = 0; i < KIRK_CERT_LEN; i++) //0x0000251C - 0x00002534
        g_pWorkData[i] = 0;

    tmpStatus = sceKernelSignalSema(g_semaId, 1); //0x0000253C
    return (tmpStatus != SCE_ERROR_OK) ? SCE_ERROR_SEMAPHORE : status;
}
Beispiel #3
0
int sub_17A8(u8* data)
{
    if (sceUtilsBufferCopyWithRange(data, 20, 0, 0, 14) == 0) {
        return 0;
    }
    return -261;
}
Beispiel #4
0
/* Subroutine sceDdrdb_driver_E27CE4CB - Address 0x00002358 */
s32 sceDdrdbSigvry(u8 *pPubKey, u8 *pData, u8 *pSig) 
{
    s32 status;
    s32 tmpStatus;
    SceSize workSize;
    u32 i;
    
    tmpStatus = sceKernelWaitSema(g_semaId, 1, NULL); // 0x00002398
    if (tmpStatus != SCE_ERROR_OK)
        return SCE_ERROR_SEMAPHORE;

    /* Set up the work area. */
    for (i = 0; i < KIRK_ECDSA_PUBLIC_KEY_LEN; i++) // 0x000023AC - 0x000023C8
        g_pWorkData[i] = pPubKey[i]; // 0x000023C8

    for (i = 0; i < KIRK_ECDSA_SRC_DATA_LEN; i++) // 0x000023CC - 0x000023EC
        g_pWorkData[KIRK_ECDSA_PUBLIC_KEY_LEN + i] = pData[i]; // 0x000023EC

    for (i = 0; i < KIRK_ECDSA_SIG_LEN; i++) // 0x000023CC - 0x000023EC
        g_pWorkData[KIRK_ECDSA_PUBLIC_KEY_LEN + KIRK_ECDSA_SRC_DATA_LEN + i] = pSig[i]; // 0x00002410

    workSize = KIRK_ECDSA_PUBLIC_KEY_LEN + KIRK_ECDSA_SRC_DATA_LEN + KIRK_ECDSA_SIG_LEN;

    /* Verify the provided signature. */
    tmpStatus = sceUtilsBufferCopyWithRange(NULL, 0, g_pWorkData, workSize, KIRK_CMD_SIG_VER_ECDSA); //0x00002428
    status = (tmpStatus != SCE_ERROR_OK) ? SCE_DNAS_ERROR_OPERATION_FAILED : SCE_ERROR_OK; //0x0000242C - 0x00002434

    /* Clear the work area. */
    for (i = 0; i < workSize; i++) //0x00002438 - 0x00002450
        g_pWorkData[i] = 0;

    tmpStatus = sceKernelSignalSema(g_semaId, 1); //0x00002458
    return (tmpStatus != SCE_ERROR_OK) ? SCE_ERROR_SEMAPHORE : status; //0x00002460 - 0x00002468
}
Beispiel #5
0
/* Subroutine sceDdrdb_driver_F970D54E - Address 0x00002570 */
s32 sceDdrdbMul1(u8 *pKeyData) 
{
    s32 status;
    s32 tmpStatus;
    SceSize workSize;
    u32 i;
    
    tmpStatus = sceKernelWaitSema(g_semaId, 1, NULL); //0x000025A0
    if (tmpStatus != SCE_ERROR_OK)
        return SCE_ERROR_SEMAPHORE;

    status = SCE_DNAS_ERROR_OPERATION_FAILED; // 0x00002598
    workSize = KIRK_ECDSA_PUBLIC_KEY_LEN + KIRK_ECDSA_PRIVATE_KEY_LEN;

    /* Compute a (public, private) key pair. */
    tmpStatus = sceUtilsBufferCopyWithRange(g_pWorkData, workSize, NULL, 0, KIRK_CMD_KEY_GEN_ECDSA); //0x000025E8
    if (tmpStatus == SCE_ERROR_OK) { // 0x000025F0

        /* Copy the computed key pair into the provided buffer. */
        for (i = 0; i < workSize; i++) // 0x000025F8 & 0x00002618
            pKeyData[i] = g_pWorkData[i]; //0x00002618

        status = SCE_ERROR_OK;
    }

    /* Clear the work area. */
    for (i = 0; i < workSize; i++) // 0x00002620 - 0x00002638
        g_pWorkData[i] = 0;

    tmpStatus = sceKernelSignalSema(g_semaId, 1); //0x00002640
    return (tmpStatus != SCE_ERROR_OK) ? SCE_ERROR_SEMAPHORE : status; //0x00002648 & 0x0000264C & 0x00002654
}
Beispiel #6
0
static int kirk14(u8 *buf)
{
	int retv;

	retv = sceUtilsBufferCopyWithRange(buf, 0x14, 0, 0, 14);
	if(retv)
		return 0x80510315;

	return 0;
}
Beispiel #7
0
static int Scramble(u32_le *buf, u32 size, u32 code)
{
	buf[0] = 5;
	buf[1] = buf[2] = 0;
	buf[3] = code;
	buf[4] = size;

	if (sceUtilsBufferCopyWithRange((u8*)buf, size+0x14, (u8*)buf, size+0x14, KIRK_CMD_DECRYPT_IV_0) < 0)
	{
		return -1;
	}

	return 0;
}
Beispiel #8
0
int kirkSendCmd(u8* data, int length, int num, bool encrypt)
{
    *(int*)(data+0) = encrypt ? KIRK_MODE_ENCRYPT_CBC : KIRK_MODE_DECRYPT_CBC;
    *(int*)(data+4) = 0;
    *(int*)(data+8) = 0;
    *(int*)(data+12) = num;
    *(int*)(data+16) = length;

    if (sceUtilsBufferCopyWithRange(data, length + 20, data, length + 20, encrypt ? KIRK_CMD_ENCRYPT_IV_0 : KIRK_CMD_DECRYPT_IV_0)) {
        return -257;
    }

    return 0;
}
Beispiel #9
0
/* Subroutine sceDdrdb_driver_40CB752A - Address 0x000029C0 */
s32 sceDdrdbHash(u8 *pSrcData, SceSize size, u8 *pDigest) 
{
    s32 status;
    s32 tmpStatus;
    SceSize workSize;
    u32 i;
    
    tmpStatus = sceKernelWaitSema(g_semaId, 1, NULL); //0x00002A04
    if (tmpStatus != SCE_ERROR_OK)
        return SCE_ERROR_SEMAPHORE;

    workSize = size + sizeof(KirkSHA1Hdr); //0x00002A20
    if (size <= SCE_DNAS_USER_DATA_MAX_LEN) { //0x00002A1C

        /* Set up the work area for KIRK. */
        KirkSHA1Hdr *pSha1Hdr = (KirkSHA1Hdr *)g_pWorkData;
        pSha1Hdr->dataSize = size; // 0x00002A28 
        
        /* Copy data used for hash computation to work area. */
        u8 *pData = g_pWorkData + sizeof(KirkSHA1Hdr);
        for (i = 0; i < size; i++)
            pData[i] = pSrcData[i]; //0x00002A54

        workSize = size + sizeof(KirkSHA1Hdr); //0x00002A5C
        status = SCE_DNAS_ERROR_OPERATION_FAILED; //0x00002A74 & 0x00002A7C

        /* Compute the SHA-1 hash value of the specified data. */
        tmpStatus = sceUtilsBufferCopyWithRange(g_pWorkData, KIRK_SHA1_DIGEST_LEN, g_pWorkData, workSize, KIRK_CMD_HASH_GEN_SHA1); //0x00002A70
        if (tmpStatus == SCE_ERROR_OK) { //0x00002A9C

            /* Copy hash value into provided buffer. */
            for (i = 0; i < KIRK_SHA1_DIGEST_LEN; i++) //0x00002A80 - 0x00002AA0
                pDigest[i] = g_pWorkData[i];

            status = SCE_ERROR_OK; //0x00002AA4
        }
    }

    /* Clear at least <KIRK_SHA1_DIGEST_LEN> bits of the working area. */
    for (i = 0; i < KIRK_SHA1_DIGEST_LEN; i++) // 0x00002AAC
        g_pWorkData[i] = 0; //0x00002B30

    /* Use casts here to handle potential underflow situation. */
    for (i = 0; (s32)i < (s32)(workSize - KIRK_SHA1_DIGEST_LEN); i++) // 0x00002B1C - 0x00002B30
        g_pWorkData[KIRK_SHA1_DIGEST_LEN + i] = 0;

    tmpStatus = sceKernelSignalSema(g_semaId, 1); //0x00002AD4
    return (tmpStatus != SCE_ERROR_OK) ? SCE_ERROR_SEMAPHORE : tmpStatus; //0x00002ADC & 0x00002AE0 & 0x00002AE4
}
Beispiel #10
0
int kirkSendFuseCmd(u8* data, int length, bool encrypt)
{
    *(int*)(data+0) = encrypt ? KIRK_MODE_ENCRYPT_CBC : KIRK_MODE_DECRYPT_CBC;
    *(int*)(data+4) = 0;
    *(int*)(data+8) = 0;
    *(int*)(data+12) = 256;
    *(int*)(data+16) = length;

    // Note: CMD 5 and 8 are not available, will always return -1
    if (sceUtilsBufferCopyWithRange(data, length + 20, data, length + 20, encrypt ? KIRK_CMD_ENCRYPT_IV_FUSE : KIRK_CMD_DECRYPT_IV_FUSE)) {
        return -258;
    }

    return 0;
}
Beispiel #11
0
static void ExtraV2Mangle(u8* buffer1, u8 codeExtra)
{
	u8 buffer2[ROUNDUP16(0x14+0xA0)];

	memcpy(buffer2+0x14, buffer1, 0xA0);

	u32_le* pl2 = (u32_le*)buffer2;
	pl2[0] = 5;
	pl2[1] = pl2[2] = 0;
	pl2[3] = codeExtra;
	pl2[4] = 0xA0;

	sceUtilsBufferCopyWithRange(buffer2, 20+0xA0, buffer2, 20+0xA0, KIRK_CMD_DECRYPT_IV_0);
	// copy result back
	memcpy(buffer1, buffer2, 0xA0);
}
Beispiel #12
0
// Name: sceDdrdbSigvryForUser ?
s32 sceDdrdb_F013F8BF(u8 *pData, u8 *pSig) 
{
    s32 status;
    s32 tmpStatus;
    SceSize workSize;
    s32 oldK1;
    u32 i;
    
    oldK1 = pspShiftK1();

    /* Check if the provided buffers are located in userland. */
    if (!pspK1StaBufOk(pData, KIRK_SHA1_DIGEST_LEN) || !pspK1StaBufOk(pSig, KIRK_ECDSA_SIG_LEN)) { // 0x00002E68 & 0x00002E7C
        pspSetK1(oldK1);
        return SCE_ERROR_PRIV_REQUIRED;
    }
         
    tmpStatus = sceKernelWaitSema(g_semaId, 1, NULL); //0x00002EC4
    if (tmpStatus != SCE_ERROR_OK) {
        pspSetK1(oldK1);
        return SCE_ERROR_SEMAPHORE;
    }

    /* Set up the work area. */
    for (i = 0; i < KIRK_ECDSA_PUBLIC_KEY_LEN; i++) // 0x00002ED4 - 0x00002F00
        g_pWorkData[i] = g_pubKeySigForUser[i]; // 0x00002F00

    for (i = 0; i < KIRK_SHA1_DIGEST_LEN; i++) //0x00002F04 - 0x00002F24
        g_pWorkData[KIRK_ECDSA_PUBLIC_KEY_LEN + i] = pData[i];

    for (i = 0; i < KIRK_ECDSA_SIG_LEN; i++) //0x00002F28 - 0x00002F48
        g_pWorkData[KIRK_ECDSA_PUBLIC_KEY_LEN + KIRK_SHA1_DIGEST_LEN + i] = pSig[i]; //0x00002F48

    workSize = KIRK_ECDSA_PUBLIC_KEY_LEN + KIRK_SHA1_DIGEST_LEN + KIRK_ECDSA_SIG_LEN;

    /* Verify the provided signature. */
    tmpStatus = sceUtilsBufferCopyWithRange(NULL, 0, g_pWorkData, workSize, KIRK_CMD_SIG_VER_ECDSA); //0x00002F60
    status = (tmpStatus != SCE_ERROR_OK) ? SCE_ERROR_INVALID_VALUE : SCE_ERROR_OK; //0x00002F64 - 0x00002F6C
    
    /* Clear the work area. */
    for (i = 0; i < workSize; i++) //0x00002F70 - 0x00002F88
        g_pWorkData[i] = 0; //0x00002F88

    tmpStatus = sceKernelSignalSema(g_semaId, 1); //0x00002F90

    pspSetK1(oldK1);
    return (tmpStatus != SCE_ERROR_OK) ? SCE_ERROR_SEMAPHORE : status; //0x00002F98 - 0x00002FA4
}
Beispiel #13
0
static int kirk8(u8 *buf, int size)
{
	int retv;
	u32 *header = (u32*)buf;

	header[0] = 5;
	header[1] = 0;
	header[2] = 0;
	header[3] = 0x0100;
	header[4] = size;

	retv = sceUtilsBufferCopyWithRange(buf, size+0x14, buf, size, 8);
	if(retv)
		return 0x80510312;

	return 0;
}
Beispiel #14
0
static int kirk4(u8 *buf, int size, int type)
{
	int retv;
	u32 *header = (u32*)buf;

	header[0] = 4;
	header[1] = 0;
	header[2] = 0;
	header[3] = type;
	header[4] = size;

	retv = sceUtilsBufferCopyWithRange(buf, size+0x14, buf, size, 4);

	if(retv)
		return 0x80510311;

	return 0;
}
Beispiel #15
0
/* Subroutine sceDdrdb_driver_EC05300A - Address 0x00002658 */
s32 sceDdrdbMul2(u8 *pPrivKey, u8 *pBasePoint, u8 *pNewPoint) 
{
    s32 status;
    s32 tmpStatus;
    SceSize workSize;
    u32 i;
    
    tmpStatus = sceKernelWaitSema(g_semaId, 1, NULL); // 0x00002698
    if (tmpStatus != SCE_ERROR_OK)
        return SCE_ERROR_SEMAPHORE;

    /* Set up the work area. */
    for (i = 0; i < KIRK_ECDSA_PRIVATE_KEY_LEN; i++) // 0x000026A4 - 0x000026C8
        g_pWorkData[i] = pPrivKey[i]; //0x000026C8

    for (i = 0; i < KIRK_ECDSA_POINT_LEN; i++) // 0x000026CC - 0x000026EC
        g_pWorkData[KIRK_ECDSA_PRIVATE_KEY_LEN + i] = pBasePoint[i]; //0x000026EC

    status = SCE_DNAS_ERROR_OPERATION_FAILED; //0x00002708 & 0x00002710

    /* Compute a new point on the elliptic curve using the provided key and curve base point. */
    tmpStatus = sceUtilsBufferCopyWithRange(g_pWorkData, KIRK_ECDSA_POINT_LEN,
        g_pWorkData, KIRK_ECDSA_PRIVATE_KEY_LEN, 
        KIRK_CMD_POINT_MULTIPLICATION_ECDSA
        ); //0x00002704
    if (tmpStatus == SCE_ERROR_OK) { //0x0000270C

        /* Copy the computed point into the provided buffer. */
        for (i = 0; i < KIRK_ECDSA_POINT_LEN; i++) //0x00002714 - 0x00002734
            pNewPoint[i] = g_pWorkData[i];

        status = SCE_ERROR_OK;
    }
    workSize = KIRK_ECDSA_PRIVATE_KEY_LEN + KIRK_ECDSA_POINT_LEN;
    
    /* Clear the work area. */
    for (i = 0; i < workSize; i++) //0x00002740 - 0x00002754
        g_pWorkData[i] = 0;

    tmpStatus = sceKernelSignalSema(g_semaId, 1); //0x0000275C
    return (tmpStatus != SCE_ERROR_OK) ? SCE_ERROR_SEMAPHORE : status; //0x00002764 & 0x00002764 & 0x0000276C
}
Beispiel #16
0
/* sceDdrdb_driver_B24E1391 - Address 0x00002798 */
s32 sceDdrdbSiggen(u8 *pPrivKey, u8 *pSrcData, u8 *pSig) 
{
    s32 status;
    s32 tmpStatus; 
    SceSize workSize;
    u32 i;
    
    tmpStatus = sceKernelWaitSema(g_semaId, 1, NULL); //0x000027D8
    if (tmpStatus != SCE_ERROR_OK)
        return SCE_ERROR_SEMAPHORE;
    
    /* Setup the work area. */
    for (i = 0; i < 32; i++) //0x000027E4 - 0x00002808
        g_pWorkData[i] = pPrivKey[i];
    
    for (i = 0; i < KIRK_ECDSA_SRC_DATA_LEN; i++) //0x0000280C - 0x0000282C
        g_pWorkData[i] = pSrcData[i];

    workSize = 32 + KIRK_ECDSA_SRC_DATA_LEN;
    status = SCE_DNAS_ERROR_OPERATION_FAILED; //0x00002848 & 0x00002850

    /* Compute the signature for the provided data. */
    tmpStatus = sceUtilsBufferCopyWithRange(g_pWorkData, workSize, g_pWorkData, workSize, KIRK_CMD_SIG_GEN_ECDSA); //0x00002844
    if (tmpStatus == SCE_ERROR_OK) { //0x0000284C

        /* Copy the computed signature into the provided buffer. */
        for (i = 0; i < KIRK_ECDSA_SIG_LEN; i++) //0x00002854 - 0x00002874
            pSig[i] = g_pWorkData[i]; //0x00002874

        status = SCE_ERROR_OK;
    }
    
    /* Clear the work area. */
    for (i = 0; i < workSize; i++) //0x00002880 - 0x00002894
        g_pWorkData[i] = 0;

    tmpStatus = sceKernelSignalSema(g_semaId, 1); //0x0000289C
    return (tmpStatus != SCE_ERROR_OK) ? SCE_ERROR_SEMAPHORE : status; //0x000028A4 - 0x000028AC
}
Beispiel #17
0
/* Subroutine sceDdrdb_driver_05D50F41 - Address 0x00002B3C */
s32 sceDdrdbEncrypt(u8 *pSrcData, SceSize size) 
{
    s32 status;
    SceSize workSize;
    s32 tmpStatus;
    u32 i;
    
    tmpStatus = sceKernelWaitSema(g_semaId, 1, NULL); //0x00002B78
    if (tmpStatus != SCE_ERROR_OK)
        return SCE_ERROR_SEMAPHORE;

    if (size <= SCE_DNAS_USER_DATA_MAX_LEN && IS_AES_BLOCK_LEN_MULTIPLE(size)) { // 0x00002B84 & 0x00002B90
        // 0x00002C10 - 0x00002C24

        /* Set up the work area for KIRK. */
        KirkAESHeader *pAesHdr = (KirkAESHeader *)g_pWorkData;
        pAesHdr->mode = 4;
        pAesHdr->unk4 = 0;
        pAesHdr->unk8 = 0;
        pAesHdr->keyIndex = 0xB;
        pAesHdr->dataSize = size;

        /* Copy data to be encrypted into work area. */
        u8 *pData = g_pWorkData + sizeof(KirkAESHeader);
        for (i = 0; i < size; i++) // 0x00002C34 - 0x00002C50
            pData[i] = pSrcData[i]; //0x00002C50

        workSize = size + sizeof(KirkAESHeader); //0x00002C58
        status = SCE_DNAS_ERROR_OPERATION_FAILED;

        /* Encrypt the specified data. */
        tmpStatus = sceUtilsBufferCopyWithRange(g_pWorkData, workSize, g_pWorkData, workSize, KIRK_CMD_ENCRYPT_AES_CBC_IV_NONE); //0x00002C6C
        if (tmpStatus == SCE_ERROR_OK) { //0x00002C74    

            /* Copy encrypted data into provided buffer. */
            for (i = 0; i < size; i++)
                pSrcData[i] = pData[i];

            status = SCE_ERROR_OK; //0x00002CAC
        }
    }
    else {
        status = SCE_DNAS_ERROR_INVALID_ARGUMENTS; // 0x00002BA0

        /*
        * UOFW: size here is > SCE_DDRDB_MAX_BUFFER_SIZE, so more data gets cleared
        * below then neccessary. Depending on size, we even clear data which does not
        * belong to the work area.
        * Another note: Why do we have to clear any data in this case? The work area
        * wasn't set up. workSize should be 0.
        */
        workSize = size + sizeof(KirkAESHeader); //0x00002B9C
    }
    
    /* Clear the work area. */
    for (i = 0; i < workSize; i++) //0x00002BB0 - 0x00002BC4
        g_pWorkData[i] = 0;

    tmpStatus = sceKernelSignalSema(g_semaId, 1);
    return (tmpStatus != SCE_ERROR_OK) ? SCE_ERROR_SEMAPHORE : status; //0x00002BD4 - 0x00002BDC
}
Beispiel #18
0
/* Subroutine sceDdrdb_driver_B33ACB44 - Address 0x00002CB0 */
s32 sceDdrdbDecrypt(u8 *pSrcData, SceSize size) 
{
    s32 status;
    s32 workSize;
    s32 tmpStatus;
    u32 i;
    
    tmpStatus = sceKernelWaitSema(g_semaId, 1, NULL); //0x00002CF0
    if (tmpStatus != SCE_ERROR_OK)
        return SCE_ERROR_SEMAPHORE;

    if (size <= SCE_DNAS_USER_DATA_MAX_LEN && IS_AES_BLOCK_LEN_MULTIPLE(size)) { //0x00002CFC & 0x00002CD0
         // 0x00002D8C - 0x00002DA4

        /* Set up the work area for KIRK. */
        KirkAESHeader *pAesHdr = (KirkAESHeader *)g_pWorkData;
        pAesHdr->mode = 5;
        pAesHdr->unk4 = 0;
        pAesHdr->unk8 = 0;
        pAesHdr->keyIndex = 0xB;
        pAesHdr->dataSize = size;

        /* Copy data to be decrypted into work area. */
        u8 *pData = g_pWorkData + sizeof(KirkAESHeader);
        for (i = 0; i < size; i++) //0x00002DB4 - 0x00002DD0
            pData[i] = pSrcData[i];

        workSize = size + sizeof(KirkAESHeader); //0x00002DD8
        status = SCE_DNAS_ERROR_OPERATION_FAILED; //0x00002DF0 & 0x00002DF8

        /* Decrypt the specified data. */
        tmpStatus = sceUtilsBufferCopyWithRange(g_pWorkData, workSize, g_pWorkData, workSize, KIRK_CMD_DECRYPT_AES_CBC_IV_NONE); //0x00002DEC
        if (tmpStatus == SCE_ERROR_OK) { //0x00002DF4
            
            /* Copy the computed data back into the provided buffer. */
            for (i = 0; i < size; i++) //0x00002E04 - 0x00002E20
                /*
                 * UOFW: Is this correct? We are copying <size> bytes from the beginning of the
                 * the work data, which includes the KIRK AES header. If the header is still 
                 * inside the workData after decryption, we copy wrong data over and miss out
                 * the last <sizeof(KirkAESHeader)> bits of the data to be decrypted.
                 *
                 * Note: sceDdrdbEncrypt() assumes the header is still there and skips it accordingly.
                 */
                pSrcData[i] = g_pWorkData[i]; //0x00002E20

            status = SCE_ERROR_OK; //0x00002E20
        }
    }
    else {
        status = SCE_DNAS_ERROR_INVALID_ARGUMENTS; //0x00002D10 & 0x00002D18

        /* 
         * UOFW: size here is > SCE_DDRDB_MAX_BUFFER_SIZE, so more data gets cleared 
         * below then neccessary. Depending on size, we even clear data which does not 
         * belong to the work area.
         * Another note: Why do we have to clear any data in this case? The work area 
         * wasn't set up. workSize should be 0.
         */
        workSize = size + sizeof(KirkAESHeader); //0x00002D14
    }

    /* Clear the work area. */
    for (i = 0; i < workSize; i++) // 0x00002D20 - 0x00002D3C
        g_pWorkData[i] = 0;

    tmpStatus = sceKernelSignalSema(g_semaId, 1); //0x00002D44
    return (tmpStatus != SCE_ERROR_OK) ? SCE_ERROR_SEMAPHORE : status; //0x00002D4C & 0x00002D50 & 0x00002D54
}
Beispiel #19
0
int main(int argc, char  *argv[])
{
    int res;
    u8 rnd[0x14];
    u8 rndbig[0x80];
    u8 keypair[0x3C];
    u8 newpoint[0x28];
    u8 mult_test[0x3c];
    u8 correct_sha1[0x14] = { 0xDE, 0x8A, 0x84, 0x7B, 0xFF, 0x8C, 0x34, 0x3D, 0x69,0xB8,
                              0x53,0xA2,0x15, 0xE6, 0xEE, 0x77, 0x5E,0xF2, 0xEF, 0x96
                            };
    u8 test17_fullsig[0x64];
    KIRK_CMD16_BUFFER ecdsa_sign;
    ECDSA_SIG signature;
    KIRK_CMD17_BUFFER ecdsa_test;
    // My private RIF

    // From NPEH90049 Demo NPUMDIMG Header SHA1 of 0xD8 bytes
    u8 test17_hash[0x14]= {
        0x2C, 0x39, 0xC1, 0x46, 0x22, 0xD5, 0x55, 0x02,
        0x3A, 0x03, 0xB1, 0x2D, 0x17, 0x00, 0x00, 0x36,
        0x8C, 0x28, 0xBD, 0x50
    };

    // From NPEH90049 Demo NPUMDIMG Header at offset 0xD8
    u8 test17_sig[0x28] = {
        0x4B, 0xBC, 0xBC, 0xB5, 0x01, 0x70, 0xCD, 0x23,
        0x20, 0x6F, 0x51, 0x9A, 0xBE, 0xD7, 0xD8, 0xCC,
        0x04, 0x56, 0x4C, 0x9E, 0x17, 0xE0, 0x1E, 0x2E,
        0x63, 0x12, 0x38, 0x60, 0x58, 0x0B, 0x21, 0x84,
        0x9F, 0x52, 0x13, 0xF1, 0x31, 0x2C, 0x6A, 0xBC
    };

    // Public NPUMDIMG Key from np9660.prx
    u8 rif_public[0x28] = {
        0x01, 0x21, 0xEA, 0x6E, 0xCD, 0xB2, 0x3A, 0x3E,
        0x23, 0x75, 0x67, 0x1C, 0x53, 0x62, 0xE8, 0xE2,
        0x8B, 0x1E, 0x78, 0x3B, 0x1A, 0x27, 0x32, 0x15,
        0x8B, 0x8C, 0xED, 0x98, 0x46, 0x6C, 0x18, 0xA3,
        0xAC, 0x3B, 0x11, 0x06, 0xAF, 0xB4, 0xEC, 0x3B

    };



    printf("Starting Test Harness...\n");

    // In the real world, you should use a secure way of generated a nice chunk of random data.
    // There are good OS-specific ways available on each platform normally. Use those!
    //
    // The two values for the fuse id can be grabbed from your personal device
    // by reading BC100090 for the first value and BC100094 for the second value.
    // Process them as u32 so the endian order stays correct.
    kirk_init2((u8*)"This is my test seed",20,0x12345678, 0xabcd );

    //test_cmd1();
    test_cmd7();
    exit(0);

    //kirk_init();
    memset(rnd,0,0x14);
    memset(rndbig,0,0x80);
    rndbig[0]= 0x20;
    hex_dump("KIRK 11 buff", rndbig,0x24);
    sceUtilsBufferCopyWithRange(rnd,0x14,rndbig,0x24,0xB);
    hex_dump("SHA1 Result", rnd,0x14);
    if(memcmp(rnd,correct_sha1,0x14) == 0 ) {
        printf("SHA1 of 0x20 00s is correct!\n");
    } else {
        printf("SHA1 failed!\n");
        return -1;
    }

    // Test Random Generator
    printf("\nGenerating 2 random numbers...\n");
    sceUtilsBufferCopyWithRange(rndbig,0x77,0,0,0xE);
    hex_dump("Big Random Number", rndbig, 0x77);

    sceUtilsBufferCopyWithRange(rnd,0x14,0,0,0xE);
    hex_dump("Random Number", rnd, 0x14);

    // Test Key Pair Generator
    printf("\nGenerating a new ECDSA keypair...\n");
    sceUtilsBufferCopyWithRange(keypair,0x3C,0,0,0xC);
    hex_dump("Private Key", keypair, 0x14);
    hex_dump("Public Key", keypair+0x14, 0x28);

    // Test Point Multiplication
    printf("\nMultiplying the Public Key by the Random Number...\n");
    memcpy(mult_test,rnd,0x14);
    memcpy(mult_test+0x14,keypair+0x14,0x28);
    sceUtilsBufferCopyWithRange(newpoint,0x28,mult_test,0x3C,0xD);
    hex_dump("New point", newpoint, 0x28);

    printf("Testing a known valid ECDSA signature...\n");
    memcpy(test17_fullsig, rif_public,0x28);
    memcpy(test17_fullsig+0x28, test17_hash,0x14);
    memcpy(test17_fullsig+0x3C, test17_sig,0x28);
    res=sceUtilsBufferCopyWithRange(0,0,test17_fullsig,0x64,0x11);
    printf("Signature check returned %d\n", res);
    if(res) {
        printf("Signature FAIL!\n");
    } else {
        printf("Signature VALID!\n");
    }
    printf("\nTesting ECDSA signing with ECDSA key pair...\n");
    encrypt_kirk16_private(ecdsa_sign.enc_private,keypair);
    hex_dump("Encrypted Private", ecdsa_sign.enc_private, 0x20);
    //Test with a message hash of all 00s
    memset(ecdsa_sign.message_hash,0,0x14);
    sceUtilsBufferCopyWithRange(signature.r,0x28,ecdsa_sign.enc_private,0x34,0x10);

    printf("\nChecking signature and Message hash...\n");
    hex_dump("Signature R", signature.r, 0x14);
    hex_dump("Signature S", signature.s, 0x14);
    hex_dump("Message hash", ecdsa_sign.message_hash,0x14);

    printf("\nUsing Public key...\n");
    hex_dump("Public.x", keypair+0x14,0x14);
    hex_dump("Public.y", keypair+0x28,0x14);
    // Build ecdsa verify message block
    memcpy(ecdsa_test.public_key.x,keypair+0x14,0x14);
    memcpy(ecdsa_test.public_key.y,keypair+0x28,0x14);
    memcpy(ecdsa_test.message_hash,ecdsa_sign.message_hash,0x14);
    memcpy(ecdsa_test.signature.r,signature.r,0x14);
    memcpy(ecdsa_test.signature.s,signature.s,0x14);

    res=sceUtilsBufferCopyWithRange(0,0,(u8*)ecdsa_test.public_key.x,0x64,0x11);
    printf("Signature check returned %d\n", res);
    if(res) {
        printf("Signature FAIL!\n");
    } else {
        printf("Signature VALID!\n");
    }
    printf("\nTesting Kirk1 ECDSA Verification and Decryption...\n");
    res=sceUtilsBufferCopyWithRange(sample_kirk1_ecdsa,320,(u8*)sample_kirk1_ecdsa,320,0x1);
    printf("Signature check returned %d\n", res);
    if(res) {
        printf("Signature FAIL!\n");
    } else {
        printf("Signature VALID!\n");
    }
    printf("%s\n",sample_kirk1_ecdsa);
    return 0;
}
Beispiel #20
0
static int DecryptPRX2(const u8 *inbuf, u8 *outbuf, u32 size, u32 tag)
{
	const TAG_INFO2 *pti = GetTagInfo2(tag);

	if (!pti)
	{
		return -1;
	}
	if (!HasKey(pti->code))
	{
		return MISSING_KEY;
	}

	// only type2 and type6 can be process by this code.
	if(pti->type!=2 && pti->type!=6)
		return -12;

	s32_le retsize = *(const s32_le *)&inbuf[0xB0];
	u8 tmp1[0x150] = {0};
	u8 tmp2[ROUNDUP16(0x90+0x14)] = {0};
	u8 tmp3[ROUNDUP16(0x90+0x14)] = {0};
	u8 tmp4[ROUNDUP16(0x20)] = {0};

	if (inbuf != outbuf)
		memcpy(outbuf, inbuf, size);

	if (size < 0x160)
	{
		return -2;
	}

	if (((int)size - 0x150) < retsize)
	{
		return -4;
	}

	memcpy(tmp1, outbuf, 0x150);

	int i;
	u8 *p = tmp2 + 0x14;

	// Writes 0x90 bytes to tmp2 + 0x14.
	for (i = 0; i < 9; i++)
	{
		memcpy(p+(i<<4), pti->key, 0x10);
		p[(i << 4)] = i;   // really? this is very odd
	}

	if (Scramble((u32_le  *)tmp2, 0x90, pti->code) < 0)
	{
		return -5;
	}

	memcpy(outbuf, tmp1+0xD0, 0x5C);
	memcpy(outbuf+0x5C, tmp1+0x140, 0x10);
	memcpy(outbuf+0x6C, tmp1+0x12C, 0x14);
	memcpy(outbuf+0x80, tmp1+0x080, 0x30);
	memcpy(outbuf+0xB0, tmp1+0x0C0, 0x10);
	memcpy(outbuf+0xC0, tmp1+0x0B0, 0x10);
	memcpy(outbuf+0xD0, tmp1+0x000, 0x80);

	memcpy(tmp3+0x14, outbuf+0x5C, 0x60);

	if (Scramble((u32_le  *)tmp3, 0x60, pti->code) < 0)
	{
		return -6;
	}

	memcpy(outbuf+0x5C, tmp3, 0x60);
	memcpy(tmp3, outbuf+0x6C, 0x14);
	memcpy(outbuf+0x70, outbuf+0x5C, 0x10);

	if(pti->type == 6)
	{
		memcpy(tmp4, outbuf+0x3C, 0x20);
		memcpy(outbuf+0x50, tmp4, 0x20);
		memset(outbuf+0x18, 0, 0x38);
	}else
		memset(outbuf+0x18, 0, 0x58);

	memcpy(outbuf+0x04, outbuf, 0x04);
	*((u32_le *)outbuf) = 0x014C;
	memcpy(outbuf+0x08, tmp2, 0x10);

	/* sha-1 */

	if (sceUtilsBufferCopyWithRange(outbuf, 3000000, outbuf, 3000000, 0x0B) != 0)
	{
		return -7;
	}

	if (memcmp(outbuf, tmp3, 0x14) != 0)
	{
		return -8;
	}

	for (i=0; i<0x40; i++)
	{
		tmp3[i+0x14] = outbuf[i+0x80] ^ tmp2[i+0x10];
	}

	if (Scramble((u32_le  *)tmp3, 0x40, pti->code) != 0)
	{
		return -9;
	}

	for (i=0; i<0x40; i++)
	{
		outbuf[i+0x40] = tmp3[i] ^ tmp2[i+0x50];
	}

	if (pti->type == 6)
	{
		memcpy(outbuf+0x80, tmp4, 0x20);
		memset(outbuf+0xA0, 0, 0x10);
		*(u32_le*)&outbuf[0xA4] = 1;
		*(u32_le*)&outbuf[0xA0] = 1;
	}
	else
	{
		memset(outbuf+0x80, 0, 0x30);
		*(u32_le*)&outbuf[0xA0] = 1;
	}

	memcpy(outbuf+0xB0, outbuf+0xC0, 0x10);
	memset(outbuf+0xC0, 0, 0x10);

	// The real decryption
	if (sceUtilsBufferCopyWithRange(outbuf, size, outbuf + 0x40, size - 0x40, 0x1) != 0)
	{
		return -1;
	}

	if (retsize < 0x150)
	{
		// Fill with 0
		memset(outbuf+retsize, 0, 0x150-retsize);
	}

	return retsize;
}
Beispiel #21
0
static int DecryptPRX1(const u8* pbIn, u8* pbOut, int cbTotal, u32 tag)
{
	int i;
	s32_le retsize;
	u8 bD0[0x80], b80[0x50], b00[0x80], bB0[0x20];

	const TAG_INFO *pti = GetTagInfo(tag);
	if (pti == NULL)
	{
		return -1;
	}
	if (!HasKey(pti->code) || 
		(pti->codeExtra != 0 && !HasKey(pti->codeExtra)))
	{
		return MISSING_KEY;
	}

	retsize = *(s32_le*)&pbIn[0xB0];

	for (i = 0; i < 0x14; i++)
	{
		if (pti->key[i] != 0)
			break;
	}

	// Scramble the key (!)
	//
	// NOTE: I can't make much sense out of this code. Scramble seems really odd, appears
	// to write to stuff that should be before the actual key.
	u8 key[0x90];
	memcpy(key, pti->key, 0x90);
	if (i == 0x14)
	{
		Scramble((u32_le *)key, 0x90, pti->code);
	}

	// build conversion into pbOut

	if (pbIn != pbOut)
		memcpy(pbOut, pbIn, cbTotal);

	memcpy(bD0, pbIn+0xD0, 0x80);
	memcpy(b80, pbIn+0x80, 0x50);
	memcpy(b00, pbIn+0x00, 0x80);
	memcpy(bB0, pbIn+0xB0, 0x20);

	memset(pbOut, 0, 0x150);
	memset(pbOut, 0x55, 0x40); // first $40 bytes ignored

	// step3 demangle in place
	u32_le* pl = (u32_le*)(pbOut+0x2C);
	pl[0] = 5; // number of ulongs in the header
	pl[1] = pl[2] = 0;
	pl[3] = pti->code; // initial seed for PRX
	pl[4] = 0x70;   // size

	// redo part of the SIG check (step2)
	u8 buffer1[0x150];
	memcpy(buffer1+0x00, bD0, 0x80);
	memcpy(buffer1+0x80, b80, 0x50);
	memcpy(buffer1+0xD0, b00, 0x80);
	if (pti->codeExtra != 0)
		ExtraV2Mangle(buffer1+0x10, pti->codeExtra);
	memcpy(pbOut+0x40, buffer1+0x40, 0x40);

	int ret;
	int iXOR;
	for (iXOR = 0; iXOR < 0x70; iXOR++)
#ifdef COMMON_BIG_ENDIAN
		pbOut[0x40+iXOR] = pbOut[0x40+iXOR] ^ key[(0x14+iXOR) ^3];
#else
		pbOut[0x40+iXOR] = pbOut[0x40+iXOR] ^ key[0x14+iXOR];
#endif

	ret = sceUtilsBufferCopyWithRange(pbOut+0x2C, 20+0x70, pbOut+0x2C, 20+0x70, 7);
	if (ret != 0)
	{
		return -1;
	}

	for (iXOR = 0x6F; iXOR >= 0; iXOR--)
#ifdef COMMON_BIG_ENDIAN
		pbOut[0x40+iXOR] = pbOut[0x2C+iXOR] ^ key[(0x20+iXOR) ^ 3];
#else
		pbOut[0x40+iXOR] = pbOut[0x2C+iXOR] ^ key[0x20+iXOR];
#endif

	memset(pbOut+0x80, 0, 0x30); // $40 bytes kept, clean up
	pbOut[0xA0] = 1;
	// copy unscrambled parts from header
	memcpy(pbOut+0xB0, bB0, 0x20); // file size + lots of zeros
	memcpy(pbOut+0xD0, b00, 0x80); // ~PSP header

	// step4: do the actual decryption of code block
	//  point 0x40 bytes into the buffer to key info
	ret = sceUtilsBufferCopyWithRange(pbOut, cbTotal, pbOut+0x40, cbTotal-0x40, 0x1);
	if (ret != 0)
	{
		return -1;
	}

	// return cbTotal - 0x150; // rounded up size
	return retsize;
}