diff options
Diffstat (limited to 'package/mtd')
| -rw-r--r-- | package/mtd/Makefile | 9 | ||||
| -rw-r--r-- | package/mtd/src/Makefile | 4 | ||||
| l--------- | package/mtd/src/bcm_tag.h | 1 | ||||
| -rw-r--r-- | package/mtd/src/imagetag.c | 57 | ||||
| -rw-r--r-- | package/mtd/src/md5.c | 307 | ||||
| -rw-r--r-- | package/mtd/src/md5.h | 65 | ||||
| -rw-r--r-- | package/mtd/src/mtd.c | 13 | ||||
| -rw-r--r-- | package/mtd/src/mtd.h | 1 | ||||
| -rw-r--r-- | package/mtd/src/seama.c | 179 | ||||
| -rw-r--r-- | package/mtd/src/seama.h | 108 | 
10 files changed, 710 insertions, 34 deletions
| diff --git a/package/mtd/Makefile b/package/mtd/Makefile index 7ca6b0e62..f429128e0 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,11 +9,14 @@ include $(TOPDIR)/rules.mk  include $(INCLUDE_DIR)/kernel.mk  PKG_NAME:=mtd -PKG_RELEASE:=18 +PKG_RELEASE:=20  PKG_BUILD_DIR := $(KERNEL_BUILD_DIR)/$(PKG_NAME)  STAMP_PREPARED := $(STAMP_PREPARED)_$(call confvar,CONFIG_MTD_REDBOOT_PARTS) +PKG_LICENSE:=GPLv2 GPLv2+ +PKG_LICENSE_FILES:= +  include $(INCLUDE_DIR)/package.mk  define Package/mtd @@ -35,7 +38,7 @@ endef  target=$(firstword $(subst -, ,$(BOARD)))  MAKE_FLAGS += TARGET="$(target)" -TARGET_CFLAGS := -I$(LINUX_DIR)/include $(TARGET_CFLAGS) -Dtarget_$(target)=1 -Wall +TARGET_CFLAGS := $(TARGET_CFLAGS) -Dtarget_$(target)=1 -Wall  ifdef CONFIG_MTD_REDBOOT_PARTS    MAKE_FLAGS += FIS_SUPPORT=1 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/bcm_tag.h b/package/mtd/src/bcm_tag.h deleted file mode 120000 index 2e977a2d7..000000000 --- a/package/mtd/src/bcm_tag.h +++ /dev/null @@ -1 +0,0 @@ -../../../target/linux/brcm63xx/files/arch/mips/include/asm/mach-bcm63xx/bcm_tag.h
\ No newline at end of file diff --git a/package/mtd/src/imagetag.c b/package/mtd/src/imagetag.c index a4ce86d6e..a53c17a70 100644 --- a/package/mtd/src/imagetag.c +++ b/package/mtd/src/imagetag.c @@ -32,9 +32,10 @@  #include <sys/ioctl.h>  #include <mtd/mtd-user.h> +#include <linux/bcm963xx_tag.h> +  #include "mtd.h"  #include "crc32.h" -#include "bcm_tag.h"  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); @@ -112,28 +113,28 @@ trx_fixup(int fd, const char *name)  	tag = (struct bcm_tag *) (ptr); -	cfelen = strntoul(&tag->cfeLength[0], NULL, 10, IMAGE_LEN); +	cfelen = strntoul(&tag->cfe_length[0], NULL, 10, IMAGE_LEN);  	if (cfelen) {  	  fprintf(stderr, "Non-zero CFE length.  This is currently unsupported.\n");  	  exit(1);  	} -	headercrc = compute_crc32(CRC_START, offset, offsetof(struct bcm_tag, headerCRC), fd); -	if (headercrc != *(uint32_t *)(&tag->headerCRC[0])) { +	headercrc = compute_crc32(CRC_START, offset, offsetof(struct bcm_tag, header_crc), fd); +	if (headercrc != *(uint32_t *)(&tag->header_crc)) {  		fprintf(stderr, "Tag verify failed.  This may not be a valid image.\n");  		exit(1);  	} -	sprintf(&tag->flashRootLength[0], "%lu", 0); -	strncpy(&tag->totalLength[0], &tag->kernelLength[0], IMAGE_LEN); +	sprintf(&tag->root_length[0], "%u", 0); +	strncpy(&tag->total_length[0], &tag->kernel_length[0], IMAGE_LEN);  	imagestart = sizeof(tag); -	memcpy(&tag->imageCRC[0], &tag->kernelCRC[0], CRC_LEN); -	memcpy(&tag->fskernelCRC[0], &tag->kernelCRC[0], CRC_LEN); +	memcpy(&tag->image_crc, &tag->kernel_crc, sizeof(uint32_t)); +	memcpy(&tag->fskernel_crc, &tag->kernel_crc, sizeof(uint32_t));  	rootfscrc = CRC_START; -	memcpy(&tag->rootfsCRC[0], &rootfscrc, sizeof(uint32_t)); -	headercrc = crc32(CRC_START, tag, offsetof(struct bcm_tag, headerCRC)); -	memcpy(&tag->headerCRC[0], &headercrc, sizeof(uint32_t)); +	memcpy(&tag->rootfs_crc, &rootfscrc, sizeof(uint32_t)); +	headercrc = crc32(CRC_START, tag, offsetof(struct bcm_tag, header_crc)); +	memcpy(&tag->header_crc, &headercrc, sizeof(uint32_t));  	msync(ptr, sizeof(struct bcm_tag), MS_SYNC|MS_INVALIDATE);  	munmap(ptr, len); @@ -164,12 +165,12 @@ trx_check(int imagefd, const char *mtd, char *buf, int *len)  		fprintf(stdout, "Could not get image header, file too small (%d bytes)\n", *len);  		return 0;  	} -	headerCRC = crc32buf(buf, offsetof(struct bcm_tag, headerCRC)); -	if (*(uint32_t *)(&tag->headerCRC[0]) != headerCRC) { +	headerCRC = crc32buf(buf, offsetof(struct bcm_tag, header_crc)); +	if (*(uint32_t *)(&tag->header_crc) != headerCRC) {  	  if (quiet < 2) { -		fprintf(stderr, "Bad header CRC got %08lx, calculated %08lx\n", -				*(uint32_t *)(&tag->headerCRC[0]), headerCRC); +		fprintf(stderr, "Bad header CRC got %08x, calculated %08x\n", +				*(uint32_t *)(&tag->header_crc), headerCRC);  		fprintf(stderr, "This is not the correct file format; refusing to flash.\n"  				"Please specify the correct file or use -f to force.\n");  	  } @@ -183,7 +184,7 @@ trx_check(int imagefd, const char *mtd, char *buf, int *len)  		exit(1);  	} -	imageLen = strntoul(&tag->totalLength[0], NULL, 10, IMAGE_LEN); +	imageLen = strntoul(&tag->total_length[0], NULL, 10, IMAGE_LEN);  	if(mtdsize < imageLen) {  		fprintf(stderr, "Image too big for partition: %s\n", mtd); @@ -238,7 +239,7 @@ mtd_fixtrx(const char *mtd, size_t offset)  	tag = (struct bcm_tag *) (buf + offset); -	cfelen = strntoul(&tag->cfeLength[0], NULL, 10, IMAGE_LEN); +	cfelen = strntoul(tag->cfe_length, NULL, 10, IMAGE_LEN);  	if (cfelen) {  	  fprintf(stderr, "Non-zero CFE length.  This is currently unsupported.\n");  	  exit(1); @@ -248,8 +249,8 @@ mtd_fixtrx(const char *mtd, size_t offset)  	  fprintf(stderr, "Verifying we actually have an imagetag.\n");  	} -	headercrc = compute_crc32(CRC_START, offset, offsetof(struct bcm_tag, headerCRC), fd); -	if (headercrc != *(uint32_t *)(&tag->headerCRC[0])) { +	headercrc = compute_crc32(CRC_START, offset, offsetof(struct bcm_tag, header_crc), fd); +	if (headercrc != *(uint32_t *)(&tag->header_crc)) {  		fprintf(stderr, "Tag verify failed.  This may not be a valid image.\n");  		exit(1);  	} @@ -258,7 +259,7 @@ mtd_fixtrx(const char *mtd, size_t offset)  	  fprintf(stderr, "Checking current fixed status.\n");  	} -	rootfslen = strntoul(&tag->flashRootLength[0], NULL, 10, IMAGE_LEN); +	rootfslen = strntoul(&tag->root_length[0], NULL, 10, IMAGE_LEN);  	if (rootfslen == 0) {  	  if (quiet < 2)   		fprintf(stderr, "Header already fixed, exiting\n"); @@ -270,20 +271,20 @@ mtd_fixtrx(const char *mtd, size_t offset)  	  fprintf(stderr, "Setting root length to 0.\n");  	} -	sprintf(&tag->flashRootLength[0], "%lu", 0); -	strncpy(&tag->totalLength[0], &tag->kernelLength[0], IMAGE_LEN); +	sprintf(&tag->root_length[0], "%u", 0); +	strncpy(&tag->total_length[0], &tag->kernel_length[0], IMAGE_LEN);  	if (quiet < 2) {  	  fprintf(stderr, "Recalculating CRCs.\n");  	}  	imagestart = sizeof(tag); -	memcpy(&tag->imageCRC[0], &tag->kernelCRC[0], CRC_LEN); -	memcpy(&tag->fskernelCRC[0], &tag->kernelCRC[0], CRC_LEN); +	memcpy(&tag->image_crc, &tag->kernel_crc, sizeof(uint32_t)); +	memcpy(&tag->fskernel_crc, &tag->kernel_crc, sizeof(uint32_t));  	rootfscrc = CRC_START; -	memcpy(&tag->rootfsCRC[0], &rootfscrc, sizeof(uint32_t)); -	headercrc = crc32(CRC_START, tag, offsetof(struct bcm_tag, headerCRC)); -	memcpy(&tag->headerCRC[0], &headercrc, sizeof(uint32_t)); +	memcpy(&tag->rootfs_crc, &rootfscrc, sizeof(uint32_t)); +	headercrc = crc32(CRC_START, tag, offsetof(struct bcm_tag, header_crc)); +	memcpy(&tag->header_crc, &headercrc, sizeof(uint32_t));  	if (quiet < 2) {  	  fprintf(stderr, "Erasing imagetag block\n"); @@ -296,7 +297,7 @@ mtd_fixtrx(const char *mtd, size_t offset)  	if (quiet < 2) {  	  fprintf(stderr, "New image crc32: 0x%x, rewriting block\n",  -			  *(uint32_t *)(&tag->imageCRC[0])); +			  *(uint32_t *)(&tag->image_crc));  	  fprintf(stderr, "New header crc32: 0x%x, rewriting block\n", headercrc);    	} 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 <string.h> +#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..bdbaab51a 100644 --- a/package/mtd/src/mtd.c +++ b/package/mtd/src/mtd.c @@ -31,7 +31,6 @@  #include <sys/syscall.h>  #include <fcntl.h>  #include <errno.h> -#include <error.h>  #include <time.h>  #include <string.h>  #include <sys/ioctl.h> @@ -137,6 +136,7 @@ image_check(int imagefd, const char *mtd)  	if (trx_check) {  	  ret = trx_check(imagefd, mtd, buf, &buflen);  	} +  	return ret;  } @@ -520,6 +520,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 +578,7 @@ int main (int argc, char **argv)  		CMD_REFRESH,  		CMD_JFFS2WRITE,  		CMD_FIXTRX, +		CMD_FIXSEAMA,  	} cmd = -1;  	erase[0] = NULL; @@ -662,6 +667,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 +746,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 <juhosg@openwrt.org> + * + * Based on the trx fixup code: + *   Copyright (C) 2005 Mike Baker + *   Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org> + * + * 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 <stdio.h> +#include <stdlib.h> +#include <stddef.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <string.h> +#include <errno.h> +#include <arpa/inet.h> + +#include <sys/ioctl.h> +#include <mtd/mtd-user.h> +#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 <david_hsieh@alphanetworks.com> + *	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 <stdint.h> + +#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 | 
