static struct firmware *firmware_new(const char *path) { int ret; const char *sha1; struct firmware *firmware; const char *firmware_repository_path = config_get(CONFIG_REPOSITORY_PATH); ULOGD("indexing firmware %s", path); firmware = calloc(1, sizeof(*firmware)); if (firmware == NULL) return NULL; firmware->entity.folder = folder_find(FIRMWARES_FOLDER_NAME); if (ut_file_is_dir(path)) { firmware->path = realpath(path, NULL); if (firmware->path == NULL) { ret = -errno; ULOGE("strdup: %m"); goto err; } ULOGI("real path is %s", firmware->path); } else { ret = asprintf(&firmware->path, "%s/%s", firmware_repository_path, path); if (ret == -1) { firmware->path = NULL; ULOGE("asprintf error"); errno = -ENOMEM; goto err; } } /* force sha1 computation while in parallel section */ sha1 = compute_sha1(firmware); if (sha1 == NULL) goto err; ret = mount_firmware(firmware); if (ret < 0) ULOGW("read_firmware_info failed: %s\n", strerror(-ret)); ULOGD("indexing firmware %s done", path); return firmware; err: firmware_delete(&firmware); return NULL; }
static const char *firmware_sha1(struct folder_entity *entity) { struct firmware *firmware = to_firmware(entity); return compute_sha1(firmware); }
/* the result array must have size SHA1_SIZE */ void sha1 (const char * data, int dsize, char * result) { int i; if (dsize < 0) { printf ("error in sha1 computation; %d (%x) bytes requested\n", dsize, dsize); exit (1); } /* padding */ unsigned int bits = dsize * 8; /* number of full input blocks */ /* int input_blocks = ((dsize + SHA1_BLOCK_SIZE - 1) / SHA1_BLOCK_SIZE) - 1;*/ int input_blocks = dsize / SHA1_BLOCK_SIZE; char last1 [SHA1_BLOCK_SIZE]; /* next-to-last block, has data from input */ char last2 [SHA1_BLOCK_SIZE]; /* last block, may not be needed */ memset (last1, 0, sizeof (last1)); memset (last2, 0, sizeof (last2)); /* number of bytes in last1 (< SHA1_BLOCK_SIZE), and also index of byte * of last1 into which to write the 0x80 which ends the data */ int last_bytes = dsize % SHA1_BLOCK_SIZE; /* number of bytes left in last1 after writing any odd bytes into last1 */ int padding = SHA1_BLOCK_SIZE - last_bytes; /* number of bytes processed in the main loop */ int full_blocks_bytes = input_blocks * SHA1_BLOCK_SIZE; if (dsize > full_blocks_bytes) memcpy (last1, data + full_blocks_bytes, dsize - full_blocks_bytes); last1 [last_bytes] = 0x80; if (padding < 9) /* we extend if padding < 9 */ write_int (last2 + (SHA1_BLOCK_SIZE - 8), bits); else write_int (last1 + (SHA1_BLOCK_SIZE - 8), bits); uint160 hash; memcpy (hash.c, init_H1, sizeof (init_H1)); for (i = 0; i < input_blocks; i++) { compute_sha1 (((uint32_t *) (data + SHA1_BLOCK_SIZE * i)), &hash, 0); #ifdef DEBUG_PRINT printf ("sha1 is %08" PRIx32 " %08" PRIx32 " %08" PRIx32 " %08" PRIx32 " %08" PRIx32 "\n", hash.i [0], hash.i [1], hash.i [2], hash.i [3], hash.i [4]); print_data (hash.c, 20); #endif /* DEBUG_PRINT */ } compute_sha1 (((uint32_t *) last1), &hash, 0); if (padding < 9) compute_sha1 (((uint32_t *) last2), &hash, 0); #ifdef DEBUG_PRINT printf ("final sha1 is %08" PRIx32 " %08" PRIx32 " %08" PRIx32 " %08" PRIx32 " %08" PRIx32 "\n", hash.i [0], hash.i [1], hash.i [2], hash.i [3], hash.i [4]); print_data (hash.c, 20); #endif /* DEBUG_PRINT */ #if __BYTE_ORDER == __LITTLE_ENDIAN write_int32 (result , hash.i [0]); write_int32 (result + 4, hash.i [1]); write_int32 (result + 8, hash.i [2]); write_int32 (result + 12, hash.i [3]); write_int32 (result + 16, hash.i [4]); #else /* __BYTE_ORDER != __LITTLE_ENDIAN */ memcpy (result, hash.c, SHA1_SIZE); #endif /* __BYTE_ORDER == __LITTLE_ENDIAN */ }