BOOL aes_init(aes* a,int mode,int nk,char *key,char *iv) { /* Key=nk bytes */ /* currently NB,nk = 16, 24 or 32 */ /* Key Scheduler. Create expanded encryption key */ int i,j,k,N,nr; WORD CipherKey[8]; nk/=4; if (nk!=4 && nk!=6 && nk!=8) return FALSE; /* nr is number of rounds */ nr=6+nk; a->Nk=nk; a->Nr=nr; aes_reset(a,mode,iv); N=NB*(nr+1); for (i=j=0; i<nk; i++,j+=4) { CipherKey[i]=pack((BYTE *)&key[j]); } for (i=0; i<nk; i++) a->fkey[i]=CipherKey[i]; for (j=nk,k=0; j<N; j+=nk,k++) { a->fkey[j]=a->fkey[j-nk]^SubByte(ROTL24(a->fkey[j-1]))^rco[k]; if (nk<=6) { for (i=1; i<nk && (i+j)<N; i++) a->fkey[i+j]=a->fkey[i+j-nk]^a->fkey[i+j-1]; } else { for (i=1; i<4 && (i+j)<N; i++) a->fkey[i+j]=a->fkey[i+j-nk]^a->fkey[i+j-1]; if ((j+4)<N) a->fkey[j+4]=a->fkey[j+4-nk]^SubByte(a->fkey[j+3]); for (i=5; i<nk && (i+j)<N; i++) a->fkey[i+j]=a->fkey[i+j-nk]^a->fkey[i+j-1]; } } /* now for the expanded decrypt key in reverse order */ for (j=0; j<NB; j++) a->rkey[j+N-NB]=a->fkey[j]; for (i=NB; i<N-NB; i+=NB) { k=N-NB-i; for (j=0; j<NB; j++) a->rkey[k+j]=InvMixCol(a->fkey[i+j]); } for (j=N-NB; j<N; j++) a->rkey[j-N+NB]=a->fkey[j]; return TRUE; }
/** * \brief Initialize the AES module. * * \param p_aes Base address of the AES instance. * \param p_cfg Pointer to AES configuration. * */ void aes_init(Aes *const p_aes, struct aes_config *const p_cfg) { /* Sanity check arguments */ Assert(p_aes); Assert(p_cfg); /* Enable clock for AES */ sysclk_enable_peripheral_clock(ID_AES); /* Perform a software reset */ aes_reset(p_aes); /* Initialize the AES with new configurations */ aes_set_config(p_aes, p_cfg); /* Disable clock for AES */ sysclk_disable_peripheral_clock(ID_AES); }
s32 wad_install(FIL *fil) { u16 i; u32 br; struct wadheader hdr __attribute__((aligned(32))); f_lseek(fil, 0); ASSERT(!f_read(fil, &hdr, sizeof(hdr), &br)); ASSERT(br == sizeof(hdr)); u32 offset = 0; static u8 key[16] __attribute__((aligned(64))) = {0,}; static u8 iv[16] __attribute__((aligned(64))) = {0,}; ASSERT(hdr.hdr_size == 0x20); offset += ALIGN(hdr.hdr_size, 0x40); offset += ALIGN(hdr.certs_size, 0x40); struct tik *tik = memalign(32, hdr.tik_size); ASSERT(tik); f_lseek(fil, offset); ASSERT(!f_read(fil, tik, hdr.tik_size, &br)); ASSERT(br == hdr.tik_size); offset += ALIGN(hdr.tik_size, 0x40); struct tmd *tmd = memalign(32, hdr.tmd_size); ASSERT(tmd); f_lseek(fil, offset); ASSERT(!f_read(fil, tmd, hdr.tmd_size, &br)); ASSERT(br == hdr.tmd_size); offset += ALIGN(hdr.tmd_size, 0x40); hexdump(tik, hdr.tik_size); hexdump(tmd, hdr.tmd_size); otp_init(); // Get the title key aes_reset(); aes_set_key(otp.common_key); memcpy(iv, &tik->title_id, 8); aes_set_iv(iv); printf("common:\n"); hexdump(otp.common_key, 16); printf("iv:\n"); hexdump(iv, 16); printf("ctk:\n"); hexdump(tik->cipher_title_key, 16); memcpy(iv, tik->cipher_title_key, 16); aes_decrypt(iv, key, 1, 0); memset(iv, 0, 16); printf("title key:\n"); hexdump(key, 16); printf("es_addtitle: %d\n", es_addtitle(tmd, tik)); printf("num contents: %d\n", tmd->num_contents); printf("%08x %08x\n", tmd, tik); for(i = 0; i < tmd->num_contents; i++) { #ifdef MSPACES u8 *content = mspace_memalign(mem2space, 32, ALIGN(tmd->contents[i].size, 0x40)); #else u8 *content = (void *)0x91000000;//memalign(32, ALIGN(tmd->contents[i].size, 0x40)); #endif ASSERT(content); f_lseek(fil, offset); printf("read content --> %08x size %08x", content, (u32) tmd->contents[i].size); ASSERT(!f_read(fil, content, ALIGN(tmd->contents[i].size, 0x40), &br)); printf("done\n"); ASSERT(br == ALIGN(tmd->contents[i].size, 0x40)); memcpy(iv, &tmd->contents[i].index, 2); aes_reset(); aes_set_key(key); aes_set_iv(iv); printf("an IV:\n"); hexdump(iv, 16); aes_decrypt(content, content, ALIGN(tmd->contents[i].size, 0x40) / 16, 0); printf("decrypted "); ASSERT(!es_addtitlecontent(tmd, tmd->contents[i].index, content, tmd->contents[i].size)); offset += ALIGN(tmd->contents[i].size, 0x40); #ifdef MSPACES mspace_free(mem2space, content); #else //free(content); #endif } free(tmd); free(tik); return 0; }