CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/Tools/SaveTool/hash.c
Views: 1401
/*1* PSP Software Development Kit - http://www.pspdev.org2* -----------------------------------------------------------------------3* Licensed under the BSD license, see LICENSE in PSPSDK root for details.4*5* hash.c - Hashing routines using sceChnnlsv6*7* Copyright (c) 2005 Jim Paris <[email protected]>8* Coypright (c) 2005 psp1239*10* $Id: hash.c 1560 2005-12-10 01:16:32Z jim $11*/1213#include "hash.h"14#include "psf.h"15#include <stdio.h>16#include <stdlib.h>17#include <string.h>18#include <malloc.h>19#include <pspchnnlsv.h>20#include "kernelcall/kernelcall.h"2122static inline int align16(unsigned int v)23{24return ((v + 0xF) >> 4) << 4;25}2627/* Update the hashes in the param.sfo data, using28the given file hash, and by computing the param.sfo hashes.29filehash must be a multiple of 16 bytes, and is reused to30store other hashes. The filename is e.g. "DATA.BIN". */31int update_hashes(unsigned char *data,32int len,33const char *filename,34unsigned char *filehash,35int encryptmode)36{37int alignedLen = align16(len);38unsigned char *datafile, *savedata_params;39int listLen, paramsLen;40int ret;4142/* Locate SAVEDATA_PARAM section in the param.sfo. */43if ((ret = find_psf_section("SAVEDATA_PARAMS", data, 0x1330,44&savedata_params, ¶msLen)) < 0) {45return ret - 100;46}4748/* Locate the pointer for this DATA.BIN equivalent */49if ((ret = find_psf_section("SAVEDATA_FILE_LIST", data, 0x1330,50&datafile, &listLen)) < 0) {51return ret - 200;52}5354if ((ret = find_psf_datafile(filename, datafile,55listLen, &datafile)) < 0) {56return ret - 300;57}5859/* Check minimum sizes based on where we want to write */60if ((listLen < 0x20) || (paramsLen < 0x80)) {61return -1;62}6364/* Clear params and insert file hash */65memset(savedata_params, 0, paramsLen);66memcpy(datafile + 0x0D, filehash, 0x10);6768/* Compute 11D0 hash over entire file */69if ((ret = build_hash(filehash, data, len, alignedLen,70(encryptmode & 2) ? 4 : 2, NULL)) < 0) { // Not sure about "2"71return ret - 400;72}7374/* Copy 11D0 hash to param.sfo and set flag indicating it's there */75memcpy(savedata_params + 0x20, filehash, 0x10);76*savedata_params |= 0x01;7778/* If new encryption mode, compute and insert the 1220 hash. */79if (encryptmode & 2) {8081/* Enable the hash bit first */82*savedata_params |= 0x20;8384if ((ret = build_hash(filehash, data, len, alignedLen,853, 0)) < 0) {86return ret - 500;87}88memcpy(savedata_params + 0x70, filehash, 0x10);89}9091/* Compute and insert the 11C0 hash. */92if ((ret = build_hash(filehash, data, len, alignedLen, 1, 0)) < 0) {93return ret - 600;94}95memcpy(savedata_params + 0x10, filehash, 0x10);9697/* All done. */98return 0;99}100101/* Build a single hash using the given data and mode.102data and alignedLen must be multiples of 0x10.103cryptkey is NULL for savedata. */104int build_hash(unsigned char *output,105unsigned char *data,106unsigned int len,107unsigned int alignedLen,108int mode,109unsigned char *cryptkey)110{111pspChnnlsvContext1 ctx1;112113/* Set up buffers */114memset(&ctx1, 0, sizeof(pspChnnlsvContext1));115memset(output, 0, 0x10);116memset(data + len, 0, alignedLen - len);117118/* Perform the magic */119if (sceChnnlsv_E7833020_(&ctx1, mode & 0xFF) < 0)120return -1;121if (sceChnnlsv_F21A1FCA_(&ctx1, data, alignedLen) < 0)122return -2;123if (sceChnnlsv_C4C494F8_(&ctx1, output, cryptkey) < 0)124return -3;125126/* All done. */127return 0;128}129130131