Esempio n. 1
0
static int do_upg(void *buf, long size)
{
    int ret = get_key_and_sig(true, buf);
    if(ret != 0)
        return ret;
    struct upg_file_t *file = upg_read_memory(buf, size, g_key, g_sig, NULL,
        generic_std_printf);
    if(file == NULL)
        return ret;
    for(int i = 0; i < file->nr_files; i++)
    {
        if(!g_out_prefix)
            continue;
        char *str = malloc(strlen(g_out_prefix) + 32);
        sprintf(str, "%s%d.bin", g_out_prefix, i);
        FILE *f = fopen(str, "wb");
        if(!f)
        {
            cprintf(GREY, "Cannot open '%s' for writing\n", str);
            free(str);
            continue;
        }
        free(str);
        fwrite(file->files[i].data, 1, file->files[i].size, f);
        fclose(f);
    }
    upg_free(file);
    return 0;
}
Esempio n. 2
0
static int create_upg(int argc, char **argv)
{
    if(argc == 0)
    {
        cprintf(GREY, "You must specify a firmware filename\n");
        usage();
    }

    int ret = get_key_and_sig(false, NULL);
    if(ret != 0)
        return ret;

    struct upg_file_t *upg = upg_new();
    int nr_files = argc - 1;

    for(int i = 0; i < nr_files; i++)
    {
        FILE *f = fopen(argv[1 + i], "rb");
        if(f == NULL)
        {
            upg_free(upg);
            printf(GREY, "Cannot open input file '%s': %m\n", argv[i + 1]);
            return 1;
        }
        size_t size = filesize(f);
        void *buf = malloc(size);
        if(fread(buf, 1, size, f) != size)
        {
            cprintf(GREY, "Cannot read input file '%s': %m\n", argv[i + 1]);
            fclose(f);
            upg_free(upg);
            return 1;
        }
        fclose(f);
        upg_append(upg, buf, size);
    }

    size_t size = 0;
    void *buf = upg_write_memory(upg, g_key, g_sig, &size, NULL, generic_std_printf);
    upg_free(upg);
    if(buf == NULL)
    {
        cprintf(GREY, "Error creating UPG file\n");
        return 1;
    }
    FILE *fout = fopen(argv[0], "wb");
    if(fout == NULL)
    {
        cprintf(GREY, "Cannot open output firmware file: %m\n");
        free(buf);
        return 1;
    }
    if(fwrite(buf, 1, size, fout) != size)
    {
        cprintf(GREY, "Cannot write output file: %m\n");
        fclose(fout);
        free(buf);
        return 1;
    }
    fclose(fout);
    free(buf);
    return 0;
}
Esempio n. 3
0
static int create_upg(int argc, char **argv)
{
    if(argc == 0)
    {
        printf("You must specify a firmware filename\n");
        usage();
    }

    int ret = get_key_and_sig(false, NULL);
    if(ret != 0)
        return ret;

    FILE *fout = fopen(argv[0], "wb");
    if(fout == NULL)
    {
        printf("Cannot open output firmware file: %m\n");
        return 1;
    }

    int nr_files = argc - 1;
    FILE **files = malloc(nr_files * sizeof(FILE *));

    for(int i = 0; i < nr_files; i++)
    {
        files[i] = fopen(argv[1 + i], "rb");
        if(files[i] == NULL)
        {
            printf("Cannot open input file '%s': %m\n", argv[i + 1]);
            return 1;
        }
    }

    struct upg_md5_t md5;
    memset(&md5, 0, sizeof(md5));
    MD5_CTX c;
    MD5_Init(&c);
    // output a dummy md5 sum
    fwrite(&md5, 1, sizeof(md5), fout);
    // output the encrypted signature
    struct upg_header_t hdr;
    memcpy(hdr.sig, g_sig, 8);
    hdr.nr_files = nr_files;
    hdr.pad = 0;

    ret = fwp_write(&hdr, sizeof(hdr), &hdr, (void *)g_key);
    if(ret)
        return ret;
    MD5_Update(&c, &hdr, sizeof(hdr));
    fwrite(&hdr, 1, sizeof(hdr), fout);

    // output file headers
    long offset = sizeof(md5) + sizeof(hdr) + nr_files * sizeof(struct upg_entry_t);
    for(int i = 0; i < nr_files; i++)
    {
        struct upg_entry_t entry;
        entry.offset = offset;
        entry.size = filesize(files[i]);
        offset += ROUND_UP(entry.size, 8); // do it before encryption !!

        ret = fwp_write(&entry, sizeof(entry), &entry, (void *)g_key);
        if(ret)
            return ret;
        MD5_Update(&c, &entry, sizeof(entry));
        fwrite(&entry, 1, sizeof(entry), fout);
    }

    cprintf(BLUE, "Files\n");
    for(int i = 0; i < nr_files; i++)
    {
        long size = filesize(files[i]);
        long r_size = ROUND_UP(size, 8);
        cprintf(GREY, "  File");
        cprintf(RED, " %d\n", i);
        cprintf_field("    Offset: ", "0x%lx\n", ftell(fout));
        cprintf_field("    Size: ", "0x%lx\n", size);

        void *buf = malloc(r_size);
        memset(buf, 0, r_size);
        fread(buf, 1, size, files[i]);
        fclose(files[i]);

        ret = fwp_write(buf, r_size, buf, (void *)g_key);
        if(ret)
            return ret;
        MD5_Update(&c, buf, r_size);
        fwrite(buf, 1, r_size, fout);

        free(buf);
    }

    fseek(fout, 0, SEEK_SET);
    MD5_Final(md5.md5, &c);
    fwrite(&md5, 1, sizeof(md5), fout);
    fclose(fout);

    return 0;
}
Esempio n. 4
0
static int do_upg(void *buf, long size)
{
    struct upg_md5_t *md5 = buf;
    cprintf(BLUE, "Preliminary\n");
    cprintf(GREEN, "  MD5: ");
    for(int i = 0; i < 16; i++)
        cprintf(YELLOW, "%02x", md5->md5[i]);
    printf(" ");

    uint8_t actual_md5[MD5_DIGEST_LENGTH];
    {
        MD5_CTX c;
        MD5_Init(&c);
        MD5_Update(&c, md5 + 1, size - sizeof(struct upg_header_t));
        MD5_Final(actual_md5, &c);
    }
    check_field(memcmp(actual_md5, md5->md5, 16), 0, "Ok\n", "Mismatch\n");

    int ret = get_key_and_sig(true, md5 + 1);
    if(ret != 0)
        return ret;

    struct upg_header_t *hdr = (void *)(md5 + 1);
    ret = fwp_read(hdr, sizeof(struct upg_header_t), hdr, (void *)g_key);
    if(ret)
        return ret;

    cprintf(BLUE, "Header\n");
    cprintf_field("  Signature:", " ");
    for(int i = 0; i < 8; i++)
        cprintf(YELLOW, "%c", isprint(hdr->sig[i]) ? hdr->sig[i] : '.');
    if(g_sig)
    {
        check_field(memcmp(hdr->sig, g_sig, 8), 0, " OK\n", " Mismatch\n");
    }
    else
        cprintf(RED, " Can't check\n");
    cprintf_field("  Files: ", "%d\n", hdr->nr_files);
    cprintf_field("  Pad: ", "0x%x\n", hdr->pad);

    cprintf(BLUE, "Files\n");
    struct upg_entry_t *entry = (void *)(hdr + 1);
    for(unsigned i = 0; i < hdr->nr_files; i++, entry++)
    {
        int ret = fwp_read(entry, sizeof(struct upg_entry_t), entry, (void *)g_key);
        if(ret)
            return ret;
        cprintf(GREY, "  File");
        cprintf(RED, " %d\n", i);
        cprintf_field("    Offset: ", "0x%x\n", entry->offset);
        cprintf_field("    Size: ", "0x%x\n", entry->size);

        if(g_out_prefix)
        {
            char *str = malloc(strlen(g_out_prefix) + 32);
            sprintf(str, "%s%d.bin", g_out_prefix, i);
            FILE *f = fopen(str, "wb");
            if(f)
            {
                // round up size, there is some padding done with random data
                int crypt_size = ROUND_UP(entry->size, 8);
                int ret = fwp_read(buf + entry->offset, crypt_size,
                    buf + entry->offset, (void *)g_key);
                if(ret)
                    return ret;
                // but write the *good* amount of data
                fwrite(buf + entry->offset, 1, entry->size, f);
                fclose(f);
            }
            else
                cprintf(GREY, "Cannot open '%s' for writing\n", str);
        }
    }

    return 0;
}