From 5477f59de6b83b561d3ffef82ec1ed6cf4a3a6c1 Mon Sep 17 00:00:00 2001 From: juhosg Date: Fri, 19 Oct 2012 19:44:23 +0000 Subject: AA: package/mtd: add option for fixing seama images Backport of r33841. Signed-off-by: Gabor Juhos git-svn-id: svn://svn.openwrt.org/openwrt/branches/attitude_adjustment@33870 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- package/mtd/Makefile | 6 +- package/mtd/src/Makefile | 4 +- package/mtd/src/md5.c | 307 +++++++++++++++++++++++++++++++++++++++++++++++ package/mtd/src/md5.h | 65 ++++++++++ package/mtd/src/mtd.c | 12 ++ package/mtd/src/mtd.h | 1 + package/mtd/src/seama.c | 179 +++++++++++++++++++++++++++ package/mtd/src/seama.h | 108 +++++++++++++++++ 8 files changed, 678 insertions(+), 4 deletions(-) create mode 100644 package/mtd/src/md5.c create mode 100644 package/mtd/src/md5.h create mode 100644 package/mtd/src/seama.c create mode 100644 package/mtd/src/seama.h diff --git a/package/mtd/Makefile b/package/mtd/Makefile index 7ca6b0e62..1eb3b4a51 100644 --- a/package/mtd/Makefile +++ b/package/mtd/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2006-2010 OpenWrt.org +# Copyright (C) 2006-2012 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=mtd -PKG_RELEASE:=18 +PKG_RELEASE:=18.1 PKG_BUILD_DIR := $(KERNEL_BUILD_DIR)/$(PKG_NAME) STAMP_PREPARED := $(STAMP_PREPARED)_$(call confvar,CONFIG_MTD_REDBOOT_PARTS) @@ -23,7 +23,7 @@ define Package/mtd endef define Package/mtd/description - This package contains an utility useful to upgrade from other firmware or + This package contains an utility useful to upgrade from other firmware or older OpenWrt releases. endef diff --git a/package/mtd/src/Makefile b/package/mtd/src/Makefile index ca03f27a9..4e6aee8eb 100644 --- a/package/mtd/src/Makefile +++ b/package/mtd/src/Makefile @@ -2,10 +2,12 @@ CC = gcc CFLAGS += -Wall obj = mtd.o jffs2.o crc32.o +obj.seama = seama.o md5.o obj.ar71xx = trx.o obj.brcm = trx.o obj.brcm47xx = $(obj.brcm) obj.brcm63xx = imagetag.o +obj.ramips = $(obj.seama) ifdef FIS_SUPPORT obj += fis.o @@ -13,4 +15,4 @@ endif mtd: $(obj) $(obj.$(TARGET)) clean: - rm -f *.o jffs2 + rm -f *.o jffs2 diff --git a/package/mtd/src/md5.c b/package/mtd/src/md5.c new file mode 100644 index 000000000..203976038 --- /dev/null +++ b/package/mtd/src/md5.c @@ -0,0 +1,307 @@ + + +/* + *********************************************************************** + ** md5.c -- the source code for MD5 routines ** + ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** + ** Created: 2/17/90 RLR ** + ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. ** + *********************************************************************** + */ + +/* + *********************************************************************** + ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** + ** ** + ** License to copy and use this software is granted provided that ** + ** it is identified as the "RSA Data Security, Inc. MD5 Message- ** + ** Digest Algorithm" in all material mentioning or referencing this ** + ** software or this function. ** + ** ** + ** License is also granted to make and use derivative works ** + ** provided that such works are identified as "derived from the RSA ** + ** Data Security, Inc. MD5 Message-Digest Algorithm" in all ** + ** material mentioning or referencing the derived work. ** + ** ** + ** RSA Data Security, Inc. makes no representations concerning ** + ** either the merchantability of this software or the suitability ** + ** of this software for any particular purpose. It is provided "as ** + ** is" without express or implied warranty of any kind. ** + ** ** + ** These notices must be retained in any copies of any part of this ** + ** documentation and/or software. ** + *********************************************************************** + */ + +#include +#include "md5.h" + +/* + *********************************************************************** + ** Message-digest routines: ** + ** To form the message digest for a message M ** + ** (1) Initialize a context buffer mdContext using MD5_Init ** + ** (2) Call MD5_Update on mdContext and M ** + ** (3) Call MD5_Final on mdContext ** + ** The message digest is now in mdContext->digest[0...15] ** + *********************************************************************** + */ + +/* forward declaration */ +static void Transform (); + +static unsigned char PADDING[64] = { + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +/* F, G, H and I are basic MD5 functions */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE_LEFT rotates x left n bits */ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */ +/* Rotation is separate from addition to prevent recomputation */ +#define FF(a, b, c, d, x, s, ac) \ + {(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define GG(a, b, c, d, x, s, ac) \ + {(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define HH(a, b, c, d, x, s, ac) \ + {(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define II(a, b, c, d, x, s, ac) \ + {(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } + +#ifdef __STDC__ +#define UL(x) x##U +#else +#define UL(x) x +#endif + +/* The routine MD5_Init initializes the message-digest context + mdContext. All fields are set to zero. + */ +void MD5_Init (mdContext) +MD5_CTX *mdContext; +{ + mdContext->i[0] = mdContext->i[1] = (UINT4)0; + + /* Load magic initialization constants. + */ + mdContext->buf[0] = (UINT4)0x67452301; + mdContext->buf[1] = (UINT4)0xefcdab89; + mdContext->buf[2] = (UINT4)0x98badcfe; + mdContext->buf[3] = (UINT4)0x10325476; +} + +/* The routine MD5Update updates the message-digest context to + account for the presence of each of the characters inBuf[0..inLen-1] + in the message whose digest is being computed. + */ +void MD5_Update (mdContext, inBuf, inLen) +MD5_CTX *mdContext; +unsigned char *inBuf; +unsigned int inLen; +{ + UINT4 in[16]; + int mdi; + unsigned int i, ii; + + /* compute number of bytes mod 64 */ + mdi = (int)((mdContext->i[0] >> 3) & 0x3F); + + /* update number of bits */ + if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0]) + mdContext->i[1]++; + mdContext->i[0] += ((UINT4)inLen << 3); + mdContext->i[1] += ((UINT4)inLen >> 29); + + while (inLen--) { + /* add new character to buffer, increment mdi */ + mdContext->in[mdi++] = *inBuf++; + + /* transform if necessary */ + if (mdi == 0x40) { + for (i = 0, ii = 0; i < 16; i++, ii += 4) + in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | + (((UINT4)mdContext->in[ii+2]) << 16) | + (((UINT4)mdContext->in[ii+1]) << 8) | + ((UINT4)mdContext->in[ii]); + Transform (mdContext->buf, in); + mdi = 0; + } + } +} + +/* The routine MD5Final terminates the message-digest computation and + ends with the desired message digest in mdContext->digest[0...15]. + */ +void MD5_Final (hash, mdContext) +unsigned char hash[]; +MD5_CTX *mdContext; +{ + UINT4 in[16]; + int mdi; + unsigned int i, ii; + unsigned int padLen; + + /* save number of bits */ + in[14] = mdContext->i[0]; + in[15] = mdContext->i[1]; + + /* compute number of bytes mod 64 */ + mdi = (int)((mdContext->i[0] >> 3) & 0x3F); + + /* pad out to 56 mod 64 */ + padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi); + MD5_Update (mdContext, PADDING, padLen); + + /* append length in bits and transform */ + for (i = 0, ii = 0; i < 14; i++, ii += 4) + in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | + (((UINT4)mdContext->in[ii+2]) << 16) | + (((UINT4)mdContext->in[ii+1]) << 8) | + ((UINT4)mdContext->in[ii]); + Transform (mdContext->buf, in); + + /* store buffer in digest */ + for (i = 0, ii = 0; i < 4; i++, ii += 4) { + mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF); + mdContext->digest[ii+1] = + (unsigned char)((mdContext->buf[i] >> 8) & 0xFF); + mdContext->digest[ii+2] = + (unsigned char)((mdContext->buf[i] >> 16) & 0xFF); + mdContext->digest[ii+3] = + (unsigned char)((mdContext->buf[i] >> 24) & 0xFF); + } + memcpy(hash, mdContext->digest, 16); +} + +/* Basic MD5 step. Transforms buf based on in. + */ +static void Transform (buf, in) +UINT4 *buf; +UINT4 *in; +{ + UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; + + /* Round 1 */ +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 + FF ( a, b, c, d, in[ 0], S11, UL(3614090360)); /* 1 */ + FF ( d, a, b, c, in[ 1], S12, UL(3905402710)); /* 2 */ + FF ( c, d, a, b, in[ 2], S13, UL( 606105819)); /* 3 */ + FF ( b, c, d, a, in[ 3], S14, UL(3250441966)); /* 4 */ + FF ( a, b, c, d, in[ 4], S11, UL(4118548399)); /* 5 */ + FF ( d, a, b, c, in[ 5], S12, UL(1200080426)); /* 6 */ + FF ( c, d, a, b, in[ 6], S13, UL(2821735955)); /* 7 */ + FF ( b, c, d, a, in[ 7], S14, UL(4249261313)); /* 8 */ + FF ( a, b, c, d, in[ 8], S11, UL(1770035416)); /* 9 */ + FF ( d, a, b, c, in[ 9], S12, UL(2336552879)); /* 10 */ + FF ( c, d, a, b, in[10], S13, UL(4294925233)); /* 11 */ + FF ( b, c, d, a, in[11], S14, UL(2304563134)); /* 12 */ + FF ( a, b, c, d, in[12], S11, UL(1804603682)); /* 13 */ + FF ( d, a, b, c, in[13], S12, UL(4254626195)); /* 14 */ + FF ( c, d, a, b, in[14], S13, UL(2792965006)); /* 15 */ + FF ( b, c, d, a, in[15], S14, UL(1236535329)); /* 16 */ + + /* Round 2 */ +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 + GG ( a, b, c, d, in[ 1], S21, UL(4129170786)); /* 17 */ + GG ( d, a, b, c, in[ 6], S22, UL(3225465664)); /* 18 */ + GG ( c, d, a, b, in[11], S23, UL( 643717713)); /* 19 */ + GG ( b, c, d, a, in[ 0], S24, UL(3921069994)); /* 20 */ + GG ( a, b, c, d, in[ 5], S21, UL(3593408605)); /* 21 */ + GG ( d, a, b, c, in[10], S22, UL( 38016083)); /* 22 */ + GG ( c, d, a, b, in[15], S23, UL(3634488961)); /* 23 */ + GG ( b, c, d, a, in[ 4], S24, UL(3889429448)); /* 24 */ + GG ( a, b, c, d, in[ 9], S21, UL( 568446438)); /* 25 */ + GG ( d, a, b, c, in[14], S22, UL(3275163606)); /* 26 */ + GG ( c, d, a, b, in[ 3], S23, UL(4107603335)); /* 27 */ + GG ( b, c, d, a, in[ 8], S24, UL(1163531501)); /* 28 */ + GG ( a, b, c, d, in[13], S21, UL(2850285829)); /* 29 */ + GG ( d, a, b, c, in[ 2], S22, UL(4243563512)); /* 30 */ + GG ( c, d, a, b, in[ 7], S23, UL(1735328473)); /* 31 */ + GG ( b, c, d, a, in[12], S24, UL(2368359562)); /* 32 */ + + /* Round 3 */ +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 + HH ( a, b, c, d, in[ 5], S31, UL(4294588738)); /* 33 */ + HH ( d, a, b, c, in[ 8], S32, UL(2272392833)); /* 34 */ + HH ( c, d, a, b, in[11], S33, UL(1839030562)); /* 35 */ + HH ( b, c, d, a, in[14], S34, UL(4259657740)); /* 36 */ + HH ( a, b, c, d, in[ 1], S31, UL(2763975236)); /* 37 */ + HH ( d, a, b, c, in[ 4], S32, UL(1272893353)); /* 38 */ + HH ( c, d, a, b, in[ 7], S33, UL(4139469664)); /* 39 */ + HH ( b, c, d, a, in[10], S34, UL(3200236656)); /* 40 */ + HH ( a, b, c, d, in[13], S31, UL( 681279174)); /* 41 */ + HH ( d, a, b, c, in[ 0], S32, UL(3936430074)); /* 42 */ + HH ( c, d, a, b, in[ 3], S33, UL(3572445317)); /* 43 */ + HH ( b, c, d, a, in[ 6], S34, UL( 76029189)); /* 44 */ + HH ( a, b, c, d, in[ 9], S31, UL(3654602809)); /* 45 */ + HH ( d, a, b, c, in[12], S32, UL(3873151461)); /* 46 */ + HH ( c, d, a, b, in[15], S33, UL( 530742520)); /* 47 */ + HH ( b, c, d, a, in[ 2], S34, UL(3299628645)); /* 48 */ + + /* Round 4 */ +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + II ( a, b, c, d, in[ 0], S41, UL(4096336452)); /* 49 */ + II ( d, a, b, c, in[ 7], S42, UL(1126891415)); /* 50 */ + II ( c, d, a, b, in[14], S43, UL(2878612391)); /* 51 */ + II ( b, c, d, a, in[ 5], S44, UL(4237533241)); /* 52 */ + II ( a, b, c, d, in[12], S41, UL(1700485571)); /* 53 */ + II ( d, a, b, c, in[ 3], S42, UL(2399980690)); /* 54 */ + II ( c, d, a, b, in[10], S43, UL(4293915773)); /* 55 */ + II ( b, c, d, a, in[ 1], S44, UL(2240044497)); /* 56 */ + II ( a, b, c, d, in[ 8], S41, UL(1873313359)); /* 57 */ + II ( d, a, b, c, in[15], S42, UL(4264355552)); /* 58 */ + II ( c, d, a, b, in[ 6], S43, UL(2734768916)); /* 59 */ + II ( b, c, d, a, in[13], S44, UL(1309151649)); /* 60 */ + II ( a, b, c, d, in[ 4], S41, UL(4149444226)); /* 61 */ + II ( d, a, b, c, in[11], S42, UL(3174756917)); /* 62 */ + II ( c, d, a, b, in[ 2], S43, UL( 718787259)); /* 63 */ + II ( b, c, d, a, in[ 9], S44, UL(3951481745)); /* 64 */ + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} + +/* + *********************************************************************** + ** End of md5.c ** + ******************************** (cut) ******************************** + */ diff --git a/package/mtd/src/md5.h b/package/mtd/src/md5.h new file mode 100644 index 000000000..f7a0c9641 --- /dev/null +++ b/package/mtd/src/md5.h @@ -0,0 +1,65 @@ +/* + *********************************************************************** + ** md5.h -- header file for implementation of MD5 ** + ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** + ** Created: 2/17/90 RLR ** + ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version ** + ** Revised (for MD5): RLR 4/27/91 ** + ** -- G modified to have y&~z instead of y&z ** + ** -- FF, GG, HH modified to add in last register done ** + ** -- Access pattern: round 2 works mod 5, round 3 works mod 3 ** + ** -- distinct additive constant for each step ** + ** -- round 4 added, working mod 7 ** + *********************************************************************** + */ + +/* + *********************************************************************** + ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** + ** ** + ** License to copy and use this software is granted provided that ** + ** it is identified as the "RSA Data Security, Inc. MD5 Message- ** + ** Digest Algorithm" in all material mentioning or referencing this ** + ** software or this function. ** + ** ** + ** License is also granted to make and use derivative works ** + ** provided that such works are identified as "derived from the RSA ** + ** Data Security, Inc. MD5 Message-Digest Algorithm" in all ** + ** material mentioning or referencing the derived work. ** + ** ** + ** RSA Data Security, Inc. makes no representations concerning ** + ** either the merchantability of this software or the suitability ** + ** of this software for any particular purpose. It is provided "as ** + ** is" without express or implied warranty of any kind. ** + ** ** + ** These notices must be retained in any copies of any part of this ** + ** documentation and/or software. ** + *********************************************************************** + */ + +#ifndef __MD5_INCLUDE__ + +/* typedef a 32-bit type */ +#ifdef _LP64 +typedef unsigned int UINT4; +typedef int INT4; +#else +typedef unsigned long UINT4; +typedef long INT4; +#endif +#define _UINT4_T + +/* Data structure for MD5 (Message-Digest) computation */ +typedef struct { + UINT4 i[2]; /* number of _bits_ handled mod 2^64 */ + UINT4 buf[4]; /* scratch buffer */ + unsigned char in[64]; /* input buffer */ + unsigned char digest[16]; /* actual digest after MD5Final call */ +} MD5_CTX; + +void MD5_Init (); +void MD5_Update (); +void MD5_Final (); + +#define __MD5_INCLUDE__ +#endif /* __MD5_INCLUDE__ */ diff --git a/package/mtd/src/mtd.c b/package/mtd/src/mtd.c index 18efcf57c..9a6e65d0d 100644 --- a/package/mtd/src/mtd.c +++ b/package/mtd/src/mtd.c @@ -137,6 +137,7 @@ image_check(int imagefd, const char *mtd) if (trx_check) { ret = trx_check(imagefd, mtd, buf, &buflen); } + return ret; } @@ -520,6 +521,10 @@ static void usage(void) fprintf(stderr, " fixtrx fix the checksum in a trx header on first boot\n"); } + if (mtd_fixseama) { + fprintf(stderr, + " fixseama fix the checksum in a seama header on first boot\n"); + } fprintf(stderr, "Following options are available:\n" " -q quiet mode (once: no [w] on writing,\n" @@ -574,6 +579,7 @@ int main (int argc, char **argv) CMD_REFRESH, CMD_JFFS2WRITE, CMD_FIXTRX, + CMD_FIXSEAMA, } cmd = -1; erase[0] = NULL; @@ -662,6 +668,9 @@ int main (int argc, char **argv) } else if (((strcmp(argv[0], "fixtrx") == 0) && (argc == 2)) && mtd_fixtrx) { cmd = CMD_FIXTRX; device = argv[1]; + } else if (((strcmp(argv[0], "fixseama") == 0) && (argc == 2)) && mtd_fixseama) { + cmd = CMD_FIXSEAMA; + device = argv[1]; } else if ((strcmp(argv[0], "write") == 0) && (argc == 3)) { cmd = CMD_WRITE; device = argv[2]; @@ -738,6 +747,9 @@ int main (int argc, char **argv) if (mtd_fixtrx) { mtd_fixtrx(device, offset); } + case CMD_FIXSEAMA: + if (mtd_fixseama) + mtd_fixseama(device, 0); break; } diff --git a/package/mtd/src/mtd.h b/package/mtd/src/mtd.h index f82552a15..c2133fc37 100644 --- a/package/mtd/src/mtd.h +++ b/package/mtd/src/mtd.h @@ -25,4 +25,5 @@ extern void mtd_parse_jffs2data(const char *buf, const char *dir); extern int trx_fixup(int fd, const char *name) __attribute__ ((weak)); extern int trx_check(int imagefd, const char *mtd, char *buf, int *len) __attribute__ ((weak)); extern int mtd_fixtrx(const char *mtd, size_t offset) __attribute__ ((weak)); +extern int mtd_fixseama(const char *mtd, size_t offset) __attribute__ ((weak)); #endif /* __mtd_h */ diff --git a/package/mtd/src/seama.c b/package/mtd/src/seama.c new file mode 100644 index 000000000..b0c8bf3d0 --- /dev/null +++ b/package/mtd/src/seama.c @@ -0,0 +1,179 @@ +/* + * seama.c + * + * Copyright (C) 2011-2012 Gabor Juhos + * + * Based on the trx fixup code: + * Copyright (C) 2005 Mike Baker + * Copyright (C) 2008 Felix Fietkau + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "mtd.h" +#include "seama.h" +#include "md5.h" + +#if __BYTE_ORDER == __BIG_ENDIAN +#define STORE32_LE(X) ((((X) & 0x000000FF) << 24) | (((X) & 0x0000FF00) << 8) | (((X) & 0x00FF0000) >> 8) | (((X) & 0xFF000000) >> 24)) +#elif __BYTE_ORDER == __LITTLE_ENDIAN +#define STORE32_LE(X) (X) +#else +#error unknown endianness! +#endif + +ssize_t pread(int fd, void *buf, size_t count, off_t offset); +ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset); + +int +seama_fix_md5(char *buf, size_t len) +{ + struct seama_hdr *shdr; + char *data; + size_t msize; + size_t isize; + MD5_CTX ctx; + unsigned char digest[16]; + int i; + + if (len < sizeof(struct seama_hdr)) + return -1; + + shdr = (struct seama_hdr *) buf; + if (shdr->magic != htonl(SEAMA_MAGIC)) { + fprintf(stderr, "no SEAMA header found\n"); + return -1; + } + + isize = ntohl(shdr->size); + msize = ntohs(shdr->metasize); + if (isize == 0) { + /* the image contains no checksum */ + return -1; + } + + len -= sizeof(struct seama_hdr) + sizeof(digest) + msize; + if (isize > len) + isize = len; + + data = buf + sizeof(struct seama_hdr) + sizeof(digest) + msize; + + MD5_Init(&ctx); + MD5_Update(&ctx, data, isize); + MD5_Final(digest, &ctx); + + if (!memcmp(digest, &buf[sizeof(struct seama_hdr)], sizeof(digest))) { + if (quiet < 2) + fprintf(stderr, "the header is fixed already\n"); + return -1; + } + + if (quiet < 2) { + fprintf(stderr, "new size:%u, new MD5: ", isize); + for (i = 0; i < sizeof(digest); i++) + fprintf(stderr, "%02x", digest[i]); + + fprintf(stderr, "\n"); + } + + /* update the size in the image */ + shdr->size = htonl(isize); + + /* update the checksum in the image */ + for (i = 0; i < sizeof(digest); i++) + buf[sizeof(struct seama_hdr) + i] = digest[i]; + + return 0; +} + +int +mtd_fixseama(const char *mtd, size_t offset) +{ + int fd; + char *buf; + ssize_t res; + size_t block_offset; + + if (quiet < 2) + fprintf(stderr, "Trying to fix SEAMA header in %s at 0x%x...\n", + mtd, offset); + + block_offset = offset & ~(erasesize - 1); + offset -= block_offset; + + fd = mtd_check_open(mtd); + if(fd < 0) { + fprintf(stderr, "Could not open mtd device: %s\n", mtd); + exit(1); + } + + if (block_offset + erasesize > mtdsize) { + fprintf(stderr, "Offset too large, device size 0x%x\n", + mtdsize); + exit(1); + } + + buf = malloc(mtdsize); + if (!buf) { + perror("malloc"); + exit(1); + } + + res = pread(fd, buf, mtdsize, block_offset); + if (res != mtdsize) { + perror("pread"); + exit(1); + } + + if (seama_fix_md5(buf, mtdsize)) + goto out; + + if (mtd_erase_block(fd, block_offset)) { + fprintf(stderr, "Can't erease block at 0x%x (%s)\n", + block_offset, strerror(errno)); + exit(1); + } + + if (quiet < 2) + fprintf(stderr, "Rewriting block at 0x%x\n", block_offset); + + if (pwrite(fd, buf, erasesize, block_offset) != erasesize) { + fprintf(stderr, "Error writing block (%s)\n", strerror(errno)); + exit(1); + } + + if (quiet < 2) + fprintf(stderr, "Done.\n"); + +out: + close (fd); + sync(); + + return 0; +} + diff --git a/package/mtd/src/seama.h b/package/mtd/src/seama.h new file mode 100644 index 000000000..02683b6e9 --- /dev/null +++ b/package/mtd/src/seama.h @@ -0,0 +1,108 @@ +/* vi: set sw=4 ts=4: */ +/* + * (SEA)ttle i(MA)ge is the image which used in project seattle. + * + * Created by David Hsieh + * Copyright (C) 2008-2009 Alpha Networks, Inc. + * + * This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either' + * version 2.1 of the License, or (at your option) any later version. + * + * The GNU C Library is distributed in the hope that it will be useful,' + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the GNU C Library; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA. + */ + +#ifndef __SEAMA_HEADER_FILE__ +#define __SEAMA_HEADER_FILE__ + +#include + +#define SEAMA_MAGIC 0x5EA3A417 + +/* + * SEAMA looks like the following map. + * All the data of the header should be in network byte order. + * + * +-------------+-------------+------------ + * | SEAMA magic | ^ + * +-------------+-------------+ | + * | reserved | meta size | | + * +-------------+-------------+ header + * | image size (0 bytes) | | + * +-------------+-------------+ | + * ~ Meta data ~ v + * +-------------+-------------+------------ + * | SEAMA magic | ^ ^ + * +-------------+-------------+ | | + * | reserved | meta size | | | + * +-------------+-------------+ | | + * | image size | | | + * +-------------+-------------+ header | + * | | | | + * | 16 bytes of MD5 digest | | | + * | | | | + * | | | | + * +-------------+-------------+ | | + * ~ Meta data ~ v | + * +-------------+-------------+------- | + * | | | + * | Image of the 1st entity | | + * ~ ~ 1st entity + * | | | + * | | v + * +-------------+-------------+------------- + * | SEAMA magic | ^ ^ + * +-------------+-------------+ | | + * | reserved | meta size | | | + * +-------------+-------------+ | | + * | image size | | | + * +-------------+-------------+ header | + * | | | | + * | 16 bytes of MD5 digest | | | + * | | | | + * | | | | + * +-------------+-------------+ | | + * ~ Meta data ~ v | + * +-------------+-------------+------- | + * | | | + * | Image of the 2nd entity | | + * ~ ~ 2nd entity + * | | | + * | | v + * +-------------+-------------+------------- + */ + + +/* + * SEAMA header + * + * |<-------- 32 bits -------->| + * +-------------+-------------+ + * | SEAMA magic | + * +-------------+-------------+ + * | reserved | meta size | + * +-------------+-------------+ + * | image size | + * +-------------+-------------+ + */ +/* seama header */ +typedef struct seama_hdr seamahdr_t; +struct seama_hdr +{ + uint32_t magic; /* should always be SEAMA_MAGIC. */ + uint16_t reserved; /* reserved for */ + uint16_t metasize; /* size of the META data */ + uint32_t size; /* size of the image */ +} __attribute__ ((packed)); + + +#endif -- cgit v1.2.3