Normalize line endings

This commit is contained in:
Braden McDaniel 2013-11-01 16:06:06 -04:00
parent f84e0d6086
commit d9461a9401
15 changed files with 3643 additions and 3643 deletions

82
AUTHORS
View file

@ -1,41 +1,41 @@
FriiDump came to existance thanks to the work by a lot of people, most of which
are probably not aware of this fact ;). So here is proper credit:
The DVD seed bruteforcing algorithm and code were taken from unscrambler 0.4
by Victor Muñoz (xt5@ingenieria-inversa.cl,
http://www.ingenieria-inversa.cl/?lp_lang_pref=en).
The theoritical basis of the dumping methods were suggested in several comments
to Victor's post. The most important comments came from Victor himself (xt5),
FuzzyLogic and svpe.
The code to actually perform the dumping was derived from the work of Kevin
East, AKA SeventhSon (kev@kev.nu, http://www.kev.nu/360/), which, in turn,
derives from work by a lot of other people. See his page for full details.
Many hints were taken from RawDump, whose author is unknown.
A program that helped me a lot to understand the drive cache behaviour is
PLScsi by Pat LaVarre (http://members.aol.com/plscsi/).
Nintendo disc structure information was taken from:
- http://www.gc-linux.org/docs/yagcd.html
- http://www.wiili.org/index.php/GameCube_Optical_Disc
Code to tell whether a Wii disc contains an update or was inspired by a program
by wiidevel@stacktic.org. Sorry but I cannot find the URL anymore :(.
Other minor pieces of code were taken from tcpdump (www.tcpdump.org), Python
(www.python.org) and the glibc printf manpage.
GDR8163B and Windows testing was performed by tasso85.
Thanks also go out to the ConsoleTribe staff for giving me the possibility to
use their forum for the program support.
Glue, endless hours spent understanding drive cache behaviour and rest of the
code are by me, Arep <arep@no.net>.
Finally, obvious thanks go out to Nintendo for making all of their great
consoles, who constantly help me to waste the rest of my spare time I do not
spend coding ;).
FriiDump came to existance thanks to the work by a lot of people, most of which
are probably not aware of this fact ;). So here is proper credit:
The DVD seed bruteforcing algorithm and code were taken from unscrambler 0.4
by Victor Muñoz (xt5@ingenieria-inversa.cl,
http://www.ingenieria-inversa.cl/?lp_lang_pref=en).
The theoritical basis of the dumping methods were suggested in several comments
to Victor's post. The most important comments came from Victor himself (xt5),
FuzzyLogic and svpe.
The code to actually perform the dumping was derived from the work of Kevin
East, AKA SeventhSon (kev@kev.nu, http://www.kev.nu/360/), which, in turn,
derives from work by a lot of other people. See his page for full details.
Many hints were taken from RawDump, whose author is unknown.
A program that helped me a lot to understand the drive cache behaviour is
PLScsi by Pat LaVarre (http://members.aol.com/plscsi/).
Nintendo disc structure information was taken from:
- http://www.gc-linux.org/docs/yagcd.html
- http://www.wiili.org/index.php/GameCube_Optical_Disc
Code to tell whether a Wii disc contains an update or was inspired by a program
by wiidevel@stacktic.org. Sorry but I cannot find the URL anymore :(.
Other minor pieces of code were taken from tcpdump (www.tcpdump.org), Python
(www.python.org) and the glibc printf manpage.
GDR8163B and Windows testing was performed by tasso85.
Thanks also go out to the ConsoleTribe staff for giving me the possibility to
use their forum for the program support.
Glue, endless hours spent understanding drive cache behaviour and rest of the
code are by me, Arep <arep@no.net>.
Finally, obvious thanks go out to Nintendo for making all of their great
consoles, who constantly help me to waste the rest of my spare time I do not
spend coding ;).

106
docs/NEWS
View file

@ -1,53 +1,53 @@
Since last official version original method 1 have been renamed to method 0
and it undergone certain changes. Methods 2, 3, 4 have been renamed to 7, 8
and 9 respectively. Method 0 should work with all drives as long as they
are supported by one of memory dump commands, so if drive is unrecognized it
is preferable to keep method at 0, and try all commands. If one of such
combinations turns out to work, you can proceed then testing other methods
with this commad. In case none of commands work, you could try to determine
drive's Read Buffer command's parameters with supplied 'BruteForce3C.exe'.
Generally program's overall bahaviour regarding commandline haven't changed
and you should be able to use same options as with official versions, though
in case you were using unrecognized drive, which would nevertheless work with
Hitachi command, you'll need to set command to 2 now (e.g. --command 2) and
method to 7, 8 or 9.
Performance have increased since official release and should be now about the
same as with 'RawDump'.
Regarding supported drives:
1. Hitachi-LG GDR8161B, GDR8162B, GDR8163B, GDR8164B, GDR8082N
Those drives can read GC/Wii media without swapping. Expected performance is
1600..1900 MB/h for *4B, *3B and 2100..2600 MB/h for *2B, *1B. Custom memory
dump command is used, which returns 2064 bytes of data. It was reproted that
they can not read other (e.g. PC) discs this way though, this needs
confirmation.
2. Lite-On LH-18A1H, DVDRW LH-18A1P, DVDRW LH-20A1H, DVDRW LH-20A1P
Reading performance for PC DVDs can go up to 5000 MB/h, which means program's
core as well as new methods are capable to output data at least at this rate.
Reading performance for GC was about 1600..1700 MB/h so likely this slowdown is
caused by drive logic itself. Though I only had one GC game to test with, so
possibly better results can be achieved depending on media. Best results were
obtained, when using method 5 with parameter 16,27 (--method5=16,27). This
combination isn't set as default because it can cause noticable delays
depending on medium quality and to make methods more general for use with other
devices. Lite-On won't read GC/Wii DVDs at all without swapping. Lite-On
returns 2384 bytes of data (2064 + ECC) by means of vendor specific READ BUFFER
command. Tested with models LH-18A1H, LH-18A1P and LH-20A1H.
3. Plextor
Plextor would return 2064 bytes of already unscrambled data with READ BUFFER
command. It works good with ordinary DVDs but due the lack of streamed reading
support is practically useless for GC/Wii dumping because of very low
performance. Works nevertheless and could be used for some experiments and
testing. Results from PX-760A.
4. Toshiba Samsung SH-D162A, SH-D162B, SH-D162C, SH-D162D
Returns 2384 data bytes per sector like Lite-On does. Appears to support
streamed reading but performance with tested model (SH-D162D) was somewhat low
and unstable even with ordinary DVDs. Looks promising, if only good-working
method could be determined. Latest drives added, definitely need more testing
at this point.
Since last official version original method 1 have been renamed to method 0
and it undergone certain changes. Methods 2, 3, 4 have been renamed to 7, 8
and 9 respectively. Method 0 should work with all drives as long as they
are supported by one of memory dump commands, so if drive is unrecognized it
is preferable to keep method at 0, and try all commands. If one of such
combinations turns out to work, you can proceed then testing other methods
with this commad. In case none of commands work, you could try to determine
drive's Read Buffer command's parameters with supplied 'BruteForce3C.exe'.
Generally program's overall bahaviour regarding commandline haven't changed
and you should be able to use same options as with official versions, though
in case you were using unrecognized drive, which would nevertheless work with
Hitachi command, you'll need to set command to 2 now (e.g. --command 2) and
method to 7, 8 or 9.
Performance have increased since official release and should be now about the
same as with 'RawDump'.
Regarding supported drives:
1. Hitachi-LG GDR8161B, GDR8162B, GDR8163B, GDR8164B, GDR8082N
Those drives can read GC/Wii media without swapping. Expected performance is
1600..1900 MB/h for *4B, *3B and 2100..2600 MB/h for *2B, *1B. Custom memory
dump command is used, which returns 2064 bytes of data. It was reproted that
they can not read other (e.g. PC) discs this way though, this needs
confirmation.
2. Lite-On LH-18A1H, DVDRW LH-18A1P, DVDRW LH-20A1H, DVDRW LH-20A1P
Reading performance for PC DVDs can go up to 5000 MB/h, which means program's
core as well as new methods are capable to output data at least at this rate.
Reading performance for GC was about 1600..1700 MB/h so likely this slowdown is
caused by drive logic itself. Though I only had one GC game to test with, so
possibly better results can be achieved depending on media. Best results were
obtained, when using method 5 with parameter 16,27 (--method5=16,27). This
combination isn't set as default because it can cause noticable delays
depending on medium quality and to make methods more general for use with other
devices. Lite-On won't read GC/Wii DVDs at all without swapping. Lite-On
returns 2384 bytes of data (2064 + ECC) by means of vendor specific READ BUFFER
command. Tested with models LH-18A1H, LH-18A1P and LH-20A1H.
3. Plextor
Plextor would return 2064 bytes of already unscrambled data with READ BUFFER
command. It works good with ordinary DVDs but due the lack of streamed reading
support is practically useless for GC/Wii dumping because of very low
performance. Works nevertheless and could be used for some experiments and
testing. Results from PX-760A.
4. Toshiba Samsung SH-D162A, SH-D162B, SH-D162C, SH-D162D
Returns 2384 data bytes per sector like Lite-On does. Appears to support
streamed reading but performance with tested model (SH-D162D) was somewhat low
and unstable even with ordinary DVDs. Looks promising, if only good-working
method could be determined. Latest drives added, definitely need more testing
at this point.

View file

@ -1,64 +1,64 @@
FriiDump 0.5.3 - Copyright (C) 2007 Arep
This software comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions; see COPYING for details.
Official support forum: http://wii.console-tribe.com
Forum for this UNOFFICIAL VERSION: http://forum.redump.org
Available command line options:
-h, --help Show this help
-a, --autodump Dump the disc to an ISO file with an
automatically-generated name, resuming the dump
if possible
-g, --gui Use more verbose output that can be easily
parsed by a GUI frontend
-d, --device <device> Dump disc from device <device>
-p, --stop Instruct device to stop disc rotation
-c, --command <nr> Force memory dump command:
0 - vanilla 2064
1 - vanilla 2384
2 - Hitachi
3 - Lite-On
4 - Renesas
-x, --speed <x> Set streaming speed (1, 24, 32, 64, etc.,
where 1 = 150 KiB/s and so on)
-T, --type <nr> Force disc type:
0 - GameCube
1 - Wii
2 - Wii_DL
3 - DVD
-S, --size <sectors> Force disc size
-r, --raw <file> Output to file <file> in raw format (2064-byte
sectors)
-i, --iso <file> Output to file <file> in ISO format (2048-byte
sectors)
-u, --unscramble <file> Convert (unscramble) raw image contained in
<file> to ISO format
-H, --nohash Do not compute CRC32/MD5/SHA-1 hashes
for generated files
-s, --resume Resume partial dump
- General -----------------------------------
-0, --method0[=<req>,<exp>] Use dumping method 0 (Optional argument
specifies how many sectors to request from disc
and read from cache at a time. Values should be
separated with a comma. Default 16,16)
- Non-Streaming -----------------------------
-1, --method1[=<req>,<exp>] Use dumping method 1 (Default 16,16)
-2, --method2[=<req>,<exp>] Use dumping method 2 (Default 16,16)
-3, --method3[=<req>,<exp>] Use dumping method 3 (Default 16,16)
- Streaming ---------------------------------
-4, --method4[=<req>,<exp>] Use dumping method 4 (Default 27,27)
-5, --method5[=<req>,<exp>] Use dumping method 5 (Default 27,27)
-6, --method6[=<req>,<exp>] Use dumping method 6 (Default 27,27)
- Hitachi -----------------------------------
-7, --method7 Use dumping method 7 (Read and dump 5 blocks
at a time, using streaming read)
-8, --method8 Use dumping method 8 (Read and dump 5 blocks
at a time, using streaming read, using DMA)
-9, --method9 Use dumping method 9 (Read and dump 5 blocks
at a time, using streaming read, using DMA and
some speed tricks)
FriiDump 0.5.3 - Copyright (C) 2007 Arep
This software comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions; see COPYING for details.
Official support forum: http://wii.console-tribe.com
Forum for this UNOFFICIAL VERSION: http://forum.redump.org
Available command line options:
-h, --help Show this help
-a, --autodump Dump the disc to an ISO file with an
automatically-generated name, resuming the dump
if possible
-g, --gui Use more verbose output that can be easily
parsed by a GUI frontend
-d, --device <device> Dump disc from device <device>
-p, --stop Instruct device to stop disc rotation
-c, --command <nr> Force memory dump command:
0 - vanilla 2064
1 - vanilla 2384
2 - Hitachi
3 - Lite-On
4 - Renesas
-x, --speed <x> Set streaming speed (1, 24, 32, 64, etc.,
where 1 = 150 KiB/s and so on)
-T, --type <nr> Force disc type:
0 - GameCube
1 - Wii
2 - Wii_DL
3 - DVD
-S, --size <sectors> Force disc size
-r, --raw <file> Output to file <file> in raw format (2064-byte
sectors)
-i, --iso <file> Output to file <file> in ISO format (2048-byte
sectors)
-u, --unscramble <file> Convert (unscramble) raw image contained in
<file> to ISO format
-H, --nohash Do not compute CRC32/MD5/SHA-1 hashes
for generated files
-s, --resume Resume partial dump
- General -----------------------------------
-0, --method0[=<req>,<exp>] Use dumping method 0 (Optional argument
specifies how many sectors to request from disc
and read from cache at a time. Values should be
separated with a comma. Default 16,16)
- Non-Streaming -----------------------------
-1, --method1[=<req>,<exp>] Use dumping method 1 (Default 16,16)
-2, --method2[=<req>,<exp>] Use dumping method 2 (Default 16,16)
-3, --method3[=<req>,<exp>] Use dumping method 3 (Default 16,16)
- Streaming ---------------------------------
-4, --method4[=<req>,<exp>] Use dumping method 4 (Default 27,27)
-5, --method5[=<req>,<exp>] Use dumping method 5 (Default 27,27)
-6, --method6[=<req>,<exp>] Use dumping method 6 (Default 27,27)
- Hitachi -----------------------------------
-7, --method7 Use dumping method 7 (Read and dump 5 blocks
at a time, using streaming read)
-8, --method8 Use dumping method 8 (Read and dump 5 blocks
at a time, using streaming read, using DMA)
-9, --method9 Use dumping method 9 (Read and dump 5 blocks
at a time, using streaming read, using DMA and
some speed tricks)

View file

@ -1,105 +1,105 @@
# Create a library called "Hello" which includes the source file "hello.cxx".
# The extension is already found. Any number of sources could be listed here.
add_library (
friidumplib
${libfriidump_type}
#SHARED
#STATIC
brickblocker.h
brickblocker.c
byteorder.h
constants.h
disc.h
disc.c
dumper.h
dumper.c
dvd_drive.h
dvd_drive.c
hitachi.c
ecma-267.h
ecma-267.c
lite-on.c
misc.h
misc.c
renesas.c
rs.h
rs.c
unscrambler.h
unscrambler.c
vanilla_2064.c
vanilla_2384.c
win32compat.h
win32compat.c
)
set_target_properties (friidumplib PROPERTIES OUTPUT_NAME "friidump")
include_directories (
${FriiDump_SOURCE_DIR}/libmultihash
)
# Make sure the linker can find the Hello library once it is built.
link_directories (
${FriiDump_BINARY_DIR}/libmultihash
)
# Link the executable to the Hello library.
target_link_libraries (
friidumplib
multihashlib
)
# Before making a release, the LTVERSION string should be modified.
# The string is of the form CURRENT:REVISION:AGE.
#
# CURRENT (C)
# The most recent interface number that this library implements.
#
# REVISION (R)
# The implementation number that this library implements.
#
# AGE (A)
# The difference between the newest and oldest interfaces that this
# library implements. In other works, the library implements all the
# interface numbers in the range from number 'CURRENT - AGE' to
# 'CURRENT'.
#
# This means that:
#
# - If interfaces have been changed or added, but binary compatibility has
# been preserved, change to C+1:0:A+1
#
# - If binary compatibility has been broken (eg removed or changed
# interfaces) change to C+1:0:0
#
# - If the interface is the same as the previous version, change to C:R+1:A
#
#set_target_properties (friidumplib PROPERTIES SOVERSION 1.0.0)
# Windows stuff to correctly build DLL or static library
#get_target_property (libfriidump_type friidumplib TYPE)
if (WIN32)
if (libfriidump_type STREQUAL "SHARED")
# MESSAGE ("Building libfriidump DLL")
ADD_DEFINITIONS (-DFRIIDUMPLIB_BUILD_DLL)
set_target_properties (friidumplib PROPERTIES DEFINE_SYMBOL FRIIDUMPLIB_EXPORTS)
install (
TARGETS friidumplib
RUNTIME DESTINATION /
#ARCHIVE DESTINATION lib
)
endif (libfriidump_type STREQUAL "SHARED")
else (WIN32)
# Install stuff, only if a shared library is being built
if (libfriidump_type STREQUAL "SHARED")
install (
TARGETS friidumplib
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib/static
)
endif (libfriidump_type STREQUAL "SHARED")
endif (WIN32)
# Create a library called "Hello" which includes the source file "hello.cxx".
# The extension is already found. Any number of sources could be listed here.
add_library (
friidumplib
${libfriidump_type}
#SHARED
#STATIC
brickblocker.h
brickblocker.c
byteorder.h
constants.h
disc.h
disc.c
dumper.h
dumper.c
dvd_drive.h
dvd_drive.c
hitachi.c
ecma-267.h
ecma-267.c
lite-on.c
misc.h
misc.c
renesas.c
rs.h
rs.c
unscrambler.h
unscrambler.c
vanilla_2064.c
vanilla_2384.c
win32compat.h
win32compat.c
)
set_target_properties (friidumplib PROPERTIES OUTPUT_NAME "friidump")
include_directories (
${FriiDump_SOURCE_DIR}/libmultihash
)
# Make sure the linker can find the Hello library once it is built.
link_directories (
${FriiDump_BINARY_DIR}/libmultihash
)
# Link the executable to the Hello library.
target_link_libraries (
friidumplib
multihashlib
)
# Before making a release, the LTVERSION string should be modified.
# The string is of the form CURRENT:REVISION:AGE.
#
# CURRENT (C)
# The most recent interface number that this library implements.
#
# REVISION (R)
# The implementation number that this library implements.
#
# AGE (A)
# The difference between the newest and oldest interfaces that this
# library implements. In other works, the library implements all the
# interface numbers in the range from number 'CURRENT - AGE' to
# 'CURRENT'.
#
# This means that:
#
# - If interfaces have been changed or added, but binary compatibility has
# been preserved, change to C+1:0:A+1
#
# - If binary compatibility has been broken (eg removed or changed
# interfaces) change to C+1:0:0
#
# - If the interface is the same as the previous version, change to C:R+1:A
#
#set_target_properties (friidumplib PROPERTIES SOVERSION 1.0.0)
# Windows stuff to correctly build DLL or static library
#get_target_property (libfriidump_type friidumplib TYPE)
if (WIN32)
if (libfriidump_type STREQUAL "SHARED")
# MESSAGE ("Building libfriidump DLL")
ADD_DEFINITIONS (-DFRIIDUMPLIB_BUILD_DLL)
set_target_properties (friidumplib PROPERTIES DEFINE_SYMBOL FRIIDUMPLIB_EXPORTS)
install (
TARGETS friidumplib
RUNTIME DESTINATION /
#ARCHIVE DESTINATION lib
)
endif (libfriidump_type STREQUAL "SHARED")
else (WIN32)
# Install stuff, only if a shared library is being built
if (libfriidump_type STREQUAL "SHARED")
install (
TARGETS friidumplib
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib/static
)
endif (libfriidump_type STREQUAL "SHARED")
endif (WIN32)

File diff suppressed because it is too large Load diff

View file

@ -1,109 +1,109 @@
/*
unscrambler 0.4: unscramble not standard IVs scrambled DVDs thru
bruteforce, intended for Gamecube/WII Optical Disks.
Copyright (C) 2006 Victor Muñoz (xt5@ingenieria-inversa.cl)
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "ecma-267.h"
/* EDC stuff */
unsigned int edc_table[256] = {
0x00000000, 0x80000011, 0x80000033, 0x00000022, 0x80000077, 0x00000066, 0x00000044, 0x80000055,
0x800000FF, 0x000000EE, 0x000000CC, 0x800000DD, 0x00000088, 0x80000099, 0x800000BB, 0x000000AA,
0x800001EF, 0x000001FE, 0x000001DC, 0x800001CD, 0x00000198, 0x80000189, 0x800001AB, 0x000001BA,
0x00000110, 0x80000101, 0x80000123, 0x00000132, 0x80000167, 0x00000176, 0x00000154, 0x80000145,
0x800003CF, 0x000003DE, 0x000003FC, 0x800003ED, 0x000003B8, 0x800003A9, 0x8000038B, 0x0000039A,
0x00000330, 0x80000321, 0x80000303, 0x00000312, 0x80000347, 0x00000356, 0x00000374, 0x80000365,
0x00000220, 0x80000231, 0x80000213, 0x00000202, 0x80000257, 0x00000246, 0x00000264, 0x80000275,
0x800002DF, 0x000002CE, 0x000002EC, 0x800002FD, 0x000002A8, 0x800002B9, 0x8000029B, 0x0000028A,
0x8000078F, 0x0000079E, 0x000007BC, 0x800007AD, 0x000007F8, 0x800007E9, 0x800007CB, 0x000007DA,
0x00000770, 0x80000761, 0x80000743, 0x00000752, 0x80000707, 0x00000716, 0x00000734, 0x80000725,
0x00000660, 0x80000671, 0x80000653, 0x00000642, 0x80000617, 0x00000606, 0x00000624, 0x80000635,
0x8000069F, 0x0000068E, 0x000006AC, 0x800006BD, 0x000006E8, 0x800006F9, 0x800006DB, 0x000006CA,
0x00000440, 0x80000451, 0x80000473, 0x00000462, 0x80000437, 0x00000426, 0x00000404, 0x80000415,
0x800004BF, 0x000004AE, 0x0000048C, 0x8000049D, 0x000004C8, 0x800004D9, 0x800004FB, 0x000004EA,
0x800005AF, 0x000005BE, 0x0000059C, 0x8000058D, 0x000005D8, 0x800005C9, 0x800005EB, 0x000005FA,
0x00000550, 0x80000541, 0x80000563, 0x00000572, 0x80000527, 0x00000536, 0x00000514, 0x80000505,
0x80000F0F, 0x00000F1E, 0x00000F3C, 0x80000F2D, 0x00000F78, 0x80000F69, 0x80000F4B, 0x00000F5A,
0x00000FF0, 0x80000FE1, 0x80000FC3, 0x00000FD2, 0x80000F87, 0x00000F96, 0x00000FB4, 0x80000FA5,
0x00000EE0, 0x80000EF1, 0x80000ED3, 0x00000EC2, 0x80000E97, 0x00000E86, 0x00000EA4, 0x80000EB5,
0x80000E1F, 0x00000E0E, 0x00000E2C, 0x80000E3D, 0x00000E68, 0x80000E79, 0x80000E5B, 0x00000E4A,
0x00000CC0, 0x80000CD1, 0x80000CF3, 0x00000CE2, 0x80000CB7, 0x00000CA6, 0x00000C84, 0x80000C95,
0x80000C3F, 0x00000C2E, 0x00000C0C, 0x80000C1D, 0x00000C48, 0x80000C59, 0x80000C7B, 0x00000C6A,
0x80000D2F, 0x00000D3E, 0x00000D1C, 0x80000D0D, 0x00000D58, 0x80000D49, 0x80000D6B, 0x00000D7A,
0x00000DD0, 0x80000DC1, 0x80000DE3, 0x00000DF2, 0x80000DA7, 0x00000DB6, 0x00000D94, 0x80000D85,
0x00000880, 0x80000891, 0x800008B3, 0x000008A2, 0x800008F7, 0x000008E6, 0x000008C4, 0x800008D5,
0x8000087F, 0x0000086E, 0x0000084C, 0x8000085D, 0x00000808, 0x80000819, 0x8000083B, 0x0000082A,
0x8000096F, 0x0000097E, 0x0000095C, 0x8000094D, 0x00000918, 0x80000909, 0x8000092B, 0x0000093A,
0x00000990, 0x80000981, 0x800009A3, 0x000009B2, 0x800009E7, 0x000009F6, 0x000009D4, 0x800009C5,
0x80000B4F, 0x00000B5E, 0x00000B7C, 0x80000B6D, 0x00000B38, 0x80000B29, 0x80000B0B, 0x00000B1A,
0x00000BB0, 0x80000BA1, 0x80000B83, 0x00000B92, 0x80000BC7, 0x00000BD6, 0x00000BF4, 0x80000BE5,
0x00000AA0, 0x80000AB1, 0x80000A93, 0x00000A82, 0x80000AD7, 0x00000AC6, 0x00000AE4, 0x80000AF5,
0x80000A5F, 0x00000A4E, 0x00000A6C, 0x80000A7D, 0x00000A28, 0x80000A39, 0x80000A1B, 0x00000A0AL
};
u32 edc_calc(u32 edc, u8 *ptr, u32 len) {
while (len--) edc=edc_table[((edc>>24)^*ptr++)&0xFF]^(edc<<8);
return edc;
}
/* end of EDC stuff */
/* LFSR stuff */
u16 ecma267_ivs[]= {
0x0001, 0x5500, 0x0002, 0x2A00,
0x0004, 0x5400, 0x0008, 0x2800,
0x0010, 0x5000, 0x0020, 0x2001,
0x0040, 0x4002, 0x0080, 0x0005
};
unsigned short LFSR;
void LFSR_ecma_init(int iv) {
LFSR=ecma267_ivs[iv];
}
void LFSR_init(u16 seed) {
LFSR=seed;
}
int LFSR_tick() {
int ret;
int n;
ret=LFSR>>14;
n=ret^((LFSR>>10)&1);
LFSR=((LFSR<<1)|n)&0x7FFF;
return ret;
}
unsigned char LFSR_byte() {
u8 ret;
int i;
ret=0;
for(i=0; i<8; i++) ret=(ret<<1)|LFSR_tick();
return ret;
}
/* end of LFSR stuff */
/*
unscrambler 0.4: unscramble not standard IVs scrambled DVDs thru
bruteforce, intended for Gamecube/WII Optical Disks.
Copyright (C) 2006 Victor Muñoz (xt5@ingenieria-inversa.cl)
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "ecma-267.h"
/* EDC stuff */
unsigned int edc_table[256] = {
0x00000000, 0x80000011, 0x80000033, 0x00000022, 0x80000077, 0x00000066, 0x00000044, 0x80000055,
0x800000FF, 0x000000EE, 0x000000CC, 0x800000DD, 0x00000088, 0x80000099, 0x800000BB, 0x000000AA,
0x800001EF, 0x000001FE, 0x000001DC, 0x800001CD, 0x00000198, 0x80000189, 0x800001AB, 0x000001BA,
0x00000110, 0x80000101, 0x80000123, 0x00000132, 0x80000167, 0x00000176, 0x00000154, 0x80000145,
0x800003CF, 0x000003DE, 0x000003FC, 0x800003ED, 0x000003B8, 0x800003A9, 0x8000038B, 0x0000039A,
0x00000330, 0x80000321, 0x80000303, 0x00000312, 0x80000347, 0x00000356, 0x00000374, 0x80000365,
0x00000220, 0x80000231, 0x80000213, 0x00000202, 0x80000257, 0x00000246, 0x00000264, 0x80000275,
0x800002DF, 0x000002CE, 0x000002EC, 0x800002FD, 0x000002A8, 0x800002B9, 0x8000029B, 0x0000028A,
0x8000078F, 0x0000079E, 0x000007BC, 0x800007AD, 0x000007F8, 0x800007E9, 0x800007CB, 0x000007DA,
0x00000770, 0x80000761, 0x80000743, 0x00000752, 0x80000707, 0x00000716, 0x00000734, 0x80000725,
0x00000660, 0x80000671, 0x80000653, 0x00000642, 0x80000617, 0x00000606, 0x00000624, 0x80000635,
0x8000069F, 0x0000068E, 0x000006AC, 0x800006BD, 0x000006E8, 0x800006F9, 0x800006DB, 0x000006CA,
0x00000440, 0x80000451, 0x80000473, 0x00000462, 0x80000437, 0x00000426, 0x00000404, 0x80000415,
0x800004BF, 0x000004AE, 0x0000048C, 0x8000049D, 0x000004C8, 0x800004D9, 0x800004FB, 0x000004EA,
0x800005AF, 0x000005BE, 0x0000059C, 0x8000058D, 0x000005D8, 0x800005C9, 0x800005EB, 0x000005FA,
0x00000550, 0x80000541, 0x80000563, 0x00000572, 0x80000527, 0x00000536, 0x00000514, 0x80000505,
0x80000F0F, 0x00000F1E, 0x00000F3C, 0x80000F2D, 0x00000F78, 0x80000F69, 0x80000F4B, 0x00000F5A,
0x00000FF0, 0x80000FE1, 0x80000FC3, 0x00000FD2, 0x80000F87, 0x00000F96, 0x00000FB4, 0x80000FA5,
0x00000EE0, 0x80000EF1, 0x80000ED3, 0x00000EC2, 0x80000E97, 0x00000E86, 0x00000EA4, 0x80000EB5,
0x80000E1F, 0x00000E0E, 0x00000E2C, 0x80000E3D, 0x00000E68, 0x80000E79, 0x80000E5B, 0x00000E4A,
0x00000CC0, 0x80000CD1, 0x80000CF3, 0x00000CE2, 0x80000CB7, 0x00000CA6, 0x00000C84, 0x80000C95,
0x80000C3F, 0x00000C2E, 0x00000C0C, 0x80000C1D, 0x00000C48, 0x80000C59, 0x80000C7B, 0x00000C6A,
0x80000D2F, 0x00000D3E, 0x00000D1C, 0x80000D0D, 0x00000D58, 0x80000D49, 0x80000D6B, 0x00000D7A,
0x00000DD0, 0x80000DC1, 0x80000DE3, 0x00000DF2, 0x80000DA7, 0x00000DB6, 0x00000D94, 0x80000D85,
0x00000880, 0x80000891, 0x800008B3, 0x000008A2, 0x800008F7, 0x000008E6, 0x000008C4, 0x800008D5,
0x8000087F, 0x0000086E, 0x0000084C, 0x8000085D, 0x00000808, 0x80000819, 0x8000083B, 0x0000082A,
0x8000096F, 0x0000097E, 0x0000095C, 0x8000094D, 0x00000918, 0x80000909, 0x8000092B, 0x0000093A,
0x00000990, 0x80000981, 0x800009A3, 0x000009B2, 0x800009E7, 0x000009F6, 0x000009D4, 0x800009C5,
0x80000B4F, 0x00000B5E, 0x00000B7C, 0x80000B6D, 0x00000B38, 0x80000B29, 0x80000B0B, 0x00000B1A,
0x00000BB0, 0x80000BA1, 0x80000B83, 0x00000B92, 0x80000BC7, 0x00000BD6, 0x00000BF4, 0x80000BE5,
0x00000AA0, 0x80000AB1, 0x80000A93, 0x00000A82, 0x80000AD7, 0x00000AC6, 0x00000AE4, 0x80000AF5,
0x80000A5F, 0x00000A4E, 0x00000A6C, 0x80000A7D, 0x00000A28, 0x80000A39, 0x80000A1B, 0x00000A0AL
};
u32 edc_calc(u32 edc, u8 *ptr, u32 len) {
while (len--) edc=edc_table[((edc>>24)^*ptr++)&0xFF]^(edc<<8);
return edc;
}
/* end of EDC stuff */
/* LFSR stuff */
u16 ecma267_ivs[]= {
0x0001, 0x5500, 0x0002, 0x2A00,
0x0004, 0x5400, 0x0008, 0x2800,
0x0010, 0x5000, 0x0020, 0x2001,
0x0040, 0x4002, 0x0080, 0x0005
};
unsigned short LFSR;
void LFSR_ecma_init(int iv) {
LFSR=ecma267_ivs[iv];
}
void LFSR_init(u16 seed) {
LFSR=seed;
}
int LFSR_tick() {
int ret;
int n;
ret=LFSR>>14;
n=ret^((LFSR>>10)&1);
LFSR=((LFSR<<1)|n)&0x7FFF;
return ret;
}
unsigned char LFSR_byte() {
u8 ret;
int i;
ret=0;
for(i=0; i<8; i++) ret=(ret<<1)|LFSR_tick();
return ret;
}
/* end of LFSR stuff */

View file

@ -1,47 +1,47 @@
/*
unscrambler 0.4: unscramble not standard IVs scrambled DVDs thru
bruteforce, intended for Gamecube/WII Optical Disks.
Copyright (C) 2006 Victor Muñoz (xt5@ingenieria-inversa.cl)
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
typedef unsigned int u32;
typedef int s32;
typedef unsigned short u16;
typedef short s16;
typedef unsigned char u8;
typedef char s8;
/* EDC stuff */
u32 edc_calc(u32 edc, u8 *ptr, u32 len);
/* end of EDC stuff */
/* LFSR stuff */
void LFSR_ecma_init(int iv);
void LFSR_init(u16 seed);
int LFSR_tick();
u8 LFSR_byte();
/* end of LFSR stuff */
/*
unscrambler 0.4: unscramble not standard IVs scrambled DVDs thru
bruteforce, intended for Gamecube/WII Optical Disks.
Copyright (C) 2006 Victor Muñoz (xt5@ingenieria-inversa.cl)
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
typedef unsigned int u32;
typedef int s32;
typedef unsigned short u16;
typedef short s16;
typedef unsigned char u8;
typedef char s8;
/* EDC stuff */
u32 edc_calc(u32 edc, u8 *ptr, u32 len);
/* end of EDC stuff */
/* LFSR stuff */
void LFSR_ecma_init(int iv);
void LFSR_init(u16 seed);
int LFSR_tick();
u8 LFSR_byte();
/* end of LFSR stuff */

View file

@ -1,316 +1,316 @@
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#define mm 8 /* RS code over GF(2**mm) - change to suit */
#define n 256 /* n = size of the field */
#define nn 182 /* nn=2**mm -1 length of codeword */
#define kk 172 /* kk = nn-2*tt */ /* Degree of g(x) = 2*tt */
//#define NN n-1
//#define FCR 0
//#define PRIM 1
#define _NROOTS nn-kk
//#define PAD NN-nn
//#define A0 NN
//#define IPRIM 1
const int NN = n-1;
const int FCR = 0;
const int PRIM = 1;
const int NROOTS = nn-kk;
const int PAD = (n-1)-nn;
const int A0 = n-1;
const int IPRIM = 1;
#ifndef min
#define min(a,b) ((a) < (b) ? (a) : (b))
#endif
/**** Primitive polynomial ****/
int pp [mm+1] = { 1, 0, 1, 1, 1, 0, 0, 0, 1}; /* 1+x^2+x^3+x^4+x^8 */
/* generator polynomial, tables for Galois field */
int alpha_to[n], index_of[n], gg[nn-kk+1];
int b0 = 1;
/* data[] is the info vector, bb[] is the parity vector, recd[] is the
noise corrupted received vector */
int recd[nn], data[kk], bb[nn-kk];
int modnn(int x){
while (x >= 0xff) {
x -= 0xff;
x = (x >> 0xff) + (x & 0xff);
}
return x;
}
void generate_gf()
{
register int i, mask ;
mask = 1 ;
alpha_to[mm] = 0 ;
for (i=0; i<mm; i++)
{ alpha_to[i] = mask ;
index_of[alpha_to[i]] = i ;
if (pp[i]!=0) /* If pp[i] == 1 then, term @^i occurs in poly-repr of @^mm */
alpha_to[mm] ^= mask ; /* Bit-wise EXOR operation */
mask <<= 1 ; /* single left-shift */
}
index_of[alpha_to[mm]] = mm ;
/* Have obtained poly-repr of @^mm. Poly-repr of @^(i+1) is given by
poly-repr of @^i shifted left one-bit and accounting for any @^mm
term that may occur when poly-repr of @^i is shifted. */
mask >>= 1 ;
for (i=mm+1; i<255; i++)
{ if (alpha_to[i-1] >= mask)
alpha_to[i] = alpha_to[mm] ^ ((alpha_to[i-1]^mask)<<1) ;
else alpha_to[i] = alpha_to[i-1]<<1 ;
index_of[alpha_to[i]] = i ;
}
index_of[0] = A0 ;//-1
}
void gen_poly()
/* Obtain the generator polynomial of the tt-error correcting, length */
{
register int i, j, root;
gg[0] = 1;
for (i = 0,root=0*1; i < nn-kk; i++,root += 1) {
gg[i+1] = 1;
for (j = i; j > 0; j--){
if (gg[j] != 0)
gg[j] = gg[j-1] ^ alpha_to[modnn(index_of[gg[j]] + root)];
else
gg[j] = gg[j-1];
}
gg[0] = alpha_to[modnn(index_of[gg[0]] + root)];
}
for (i=0; i <= nn-kk; i++) {
gg[i] = index_of[gg[i]];
}
}
void rs_encode(unsigned char *data, unsigned char *bb)
{
register int i,j ;
int feedback;
for (i=0; i<NROOTS; i++) bb[i] = 0; //nullify result
for(i=0;i<NN-NROOTS-PAD;i++){
feedback = index_of[data[i] ^ bb[0]];
if(feedback != A0){ /* feedback term is non-zero */
for(j=1;j<NROOTS;j++) {
bb[j] ^= alpha_to[modnn(feedback + gg[NROOTS-j])];
}
}
/* Shift */
memmove(&bb[0],&bb[1], NROOTS-1);
//for (j=0; j<NROOTS-1; j++) bb[j] = bb[j+1];
if(feedback != A0)
bb[NROOTS-1] = alpha_to[modnn(feedback + gg[0])];
else
bb[NROOTS-1] = 0;
}
}
///*
int rs_decode(unsigned char *data, int *eras_pos, int no_eras){
int deg_lambda, el, deg_omega;
int i, j, r,k;
unsigned char u,q,tmp,num1,num2,den,discr_r;
unsigned char lambda[_NROOTS+1], s[_NROOTS];
unsigned char b[_NROOTS+1], t[_NROOTS+1], omega[_NROOTS+1];
unsigned char root[_NROOTS], reg[_NROOTS+1], loc[_NROOTS];
int syn_error, count;
// form the syndromes; i.e., evaluate data(x) at roots of g(x)
for(i=0;i<NROOTS;i++)
s[i] = data[0];
for(j=1;j<NN-PAD;j++){
for(i=0;i<NROOTS;i++){
if(s[i] == 0){
s[i] = data[j];
} else {
s[i] = data[j] ^ alpha_to[modnn(index_of[s[i]] + (FCR+i)*PRIM)];
}
}
}
// Convert syndromes to index form, checking for nonzero condition
syn_error = 0;
for(i=0;i<NROOTS;i++){
syn_error |= s[i];
s[i] = index_of[s[i]];
}
if (!syn_error) {
// if syndrome is zero, data[] is a codeword and there are no
// errors to correct. So return data[] unmodified
//
count = 0;
goto finish;
}
memset(&lambda[1],0,NROOTS*sizeof(lambda[0]));
lambda[0] = 1;
if (no_eras > 0) {
/* Init lambda to be the erasure locator polynomial */
lambda[1] = alpha_to[modnn(PRIM*(NN-1-eras_pos[0]))];
for (i = 1; i < no_eras; i++) {
u = modnn(PRIM*(NN-1-eras_pos[i]));
for (j = i+1; j > 0; j--) {
tmp = index_of[lambda[j - 1]];
if(tmp != A0)
lambda[j] ^= alpha_to[modnn(u + tmp)];
}
}
}
for(i=0;i<NROOTS+1;i++)
b[i] = index_of[lambda[i]];
/*
* Begin Berlekamp-Massey algorithm to determine error+erasure
* locator polynomial
*/
r = no_eras;
el = no_eras;
while (++r <= NROOTS) { /* r is the step number */
/* Compute discrepancy at the r-th step in poly-form */
discr_r = 0;
for (i = 0; i < r; i++){
if ((lambda[i] != 0) && (s[r-i-1] != A0)) {
discr_r ^= alpha_to[modnn(index_of[lambda[i]] + s[r-i-1])];
}
}
discr_r = index_of[discr_r]; /* Index form */
if (discr_r == A0) {
/* 2 lines below: B(x) <-- x*B(x) */
memmove(&b[1],b,NROOTS*sizeof(b[0]));
b[0] = A0;
} else {
/* 7 lines below: T(x) <-- lambda(x) - discr_r*x*b(x) */
t[0] = lambda[0];
for (i = 0 ; i < NROOTS; i++) {
if(b[i] != A0)
t[i+1] = lambda[i+1] ^ alpha_to[modnn(discr_r + b[i])];
else
t[i+1] = lambda[i+1];
}
if (2 * el <= r + no_eras - 1) {
el = r + no_eras - el;
/*
* 2 lines below: B(x) <-- inv(discr_r) *
* lambda(x)
*/
for (i = 0; i <= NROOTS; i++)
b[i] = (lambda[i] == 0) ? A0 : modnn(index_of[lambda[i]] - discr_r + NN);
} else {
/* 2 lines below: B(x) <-- x*B(x) */
memmove(&b[1],b,NROOTS*sizeof(b[0]));
b[0] = A0;
}
memcpy(lambda,t,(NROOTS+1)*sizeof(t[0]));
}
}
/* Convert lambda to index form and compute deg(lambda(x)) */
deg_lambda = 0;
for(i=0;i<NROOTS+1;i++){
lambda[i] = index_of[lambda[i]];
if(lambda[i] != A0)
deg_lambda = i;
}
/* Find roots of the error+erasure locator polynomial by Chien search */
memcpy(&reg[1],&lambda[1],NROOTS*sizeof(reg[0]));
count = 0; /* Number of roots of lambda(x) */
for (i = 1,k=IPRIM-1; i <= NN; i++,k = modnn(k+IPRIM)) {
q = 1; /* lambda[0] is always 0 */
for (j = deg_lambda; j > 0; j--){
if (reg[j] != A0) {
reg[j] = modnn(reg[j] + j);
q ^= alpha_to[reg[j]];
}
}
if (q != 0)
continue; /* Not a root */
/* store root (index-form) and error location number */
root[count] = i;
loc[count] = k;
/* If we've already found max possible roots,
* abort the search to save time
*/
if(++count == deg_lambda)
break;
}
if (deg_lambda != count) {
/*
* deg(lambda) unequal to number of roots => uncorrectable
* error detected
*/
count = -1;
goto finish;
}
/*
* Compute err+eras evaluator poly omega(x) = s(x)*lambda(x) (modulo
* x**NROOTS). in index form. Also find deg(omega).
*/
deg_omega = deg_lambda-1;
for (i = 0; i <= deg_omega;i++){
tmp = 0;
for(j=i;j >= 0; j--){
if ((s[i - j] != A0) && (lambda[j] != A0))
tmp ^= alpha_to[modnn(s[i - j] + lambda[j])];
}
omega[i] = index_of[tmp];
}
/*
* Compute error values in poly-form. num1 = omega(inv(X(l))), num2 =
* inv(X(l))**(FCR-1) and den = lambda_pr(inv(X(l))) all in poly-form
*/
for (j = count-1; j >=0; j--) {
num1 = 0;
for (i = deg_omega; i >= 0; i--) {
if (omega[i] != A0)
num1 ^= alpha_to[modnn(omega[i] + i * root[j])];
}
num2 = alpha_to[modnn(root[j] * (FCR - 1) + NN)];
den = 0;
/* lambda[i+1] for i even is the formal derivative lambda_pr of lambda[i] */
for (i = min(deg_lambda,NROOTS-1) & ~1; i >= 0; i -=2) {
if(lambda[i+1] != A0)
den ^= alpha_to[modnn(lambda[i+1] + i * root[j])];
}
/* Apply error to data */
if (num1 != 0 && loc[j] >= PAD) {
data[loc[j]-PAD] ^= alpha_to[modnn(index_of[num1] + index_of[num2] + NN - index_of[den])];
}
}
finish:
if(eras_pos != NULL){
for(i=0;i<count;i++)
eras_pos[i] = loc[i];
}
return count;
}
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#define mm 8 /* RS code over GF(2**mm) - change to suit */
#define n 256 /* n = size of the field */
#define nn 182 /* nn=2**mm -1 length of codeword */
#define kk 172 /* kk = nn-2*tt */ /* Degree of g(x) = 2*tt */
//#define NN n-1
//#define FCR 0
//#define PRIM 1
#define _NROOTS nn-kk
//#define PAD NN-nn
//#define A0 NN
//#define IPRIM 1
const int NN = n-1;
const int FCR = 0;
const int PRIM = 1;
const int NROOTS = nn-kk;
const int PAD = (n-1)-nn;
const int A0 = n-1;
const int IPRIM = 1;
#ifndef min
#define min(a,b) ((a) < (b) ? (a) : (b))
#endif
/**** Primitive polynomial ****/
int pp [mm+1] = { 1, 0, 1, 1, 1, 0, 0, 0, 1}; /* 1+x^2+x^3+x^4+x^8 */
/* generator polynomial, tables for Galois field */
int alpha_to[n], index_of[n], gg[nn-kk+1];
int b0 = 1;
/* data[] is the info vector, bb[] is the parity vector, recd[] is the
noise corrupted received vector */
int recd[nn], data[kk], bb[nn-kk];
int modnn(int x){
while (x >= 0xff) {
x -= 0xff;
x = (x >> 0xff) + (x & 0xff);
}
return x;
}
void generate_gf()
{
register int i, mask ;
mask = 1 ;
alpha_to[mm] = 0 ;
for (i=0; i<mm; i++)
{ alpha_to[i] = mask ;
index_of[alpha_to[i]] = i ;
if (pp[i]!=0) /* If pp[i] == 1 then, term @^i occurs in poly-repr of @^mm */
alpha_to[mm] ^= mask ; /* Bit-wise EXOR operation */
mask <<= 1 ; /* single left-shift */
}
index_of[alpha_to[mm]] = mm ;
/* Have obtained poly-repr of @^mm. Poly-repr of @^(i+1) is given by
poly-repr of @^i shifted left one-bit and accounting for any @^mm
term that may occur when poly-repr of @^i is shifted. */
mask >>= 1 ;
for (i=mm+1; i<255; i++)
{ if (alpha_to[i-1] >= mask)
alpha_to[i] = alpha_to[mm] ^ ((alpha_to[i-1]^mask)<<1) ;
else alpha_to[i] = alpha_to[i-1]<<1 ;
index_of[alpha_to[i]] = i ;
}
index_of[0] = A0 ;//-1
}
void gen_poly()
/* Obtain the generator polynomial of the tt-error correcting, length */
{
register int i, j, root;
gg[0] = 1;
for (i = 0,root=0*1; i < nn-kk; i++,root += 1) {
gg[i+1] = 1;
for (j = i; j > 0; j--){
if (gg[j] != 0)
gg[j] = gg[j-1] ^ alpha_to[modnn(index_of[gg[j]] + root)];
else
gg[j] = gg[j-1];
}
gg[0] = alpha_to[modnn(index_of[gg[0]] + root)];
}
for (i=0; i <= nn-kk; i++) {
gg[i] = index_of[gg[i]];
}
}
void rs_encode(unsigned char *data, unsigned char *bb)
{
register int i,j ;
int feedback;
for (i=0; i<NROOTS; i++) bb[i] = 0; //nullify result
for(i=0;i<NN-NROOTS-PAD;i++){
feedback = index_of[data[i] ^ bb[0]];
if(feedback != A0){ /* feedback term is non-zero */
for(j=1;j<NROOTS;j++) {
bb[j] ^= alpha_to[modnn(feedback + gg[NROOTS-j])];
}
}
/* Shift */
memmove(&bb[0],&bb[1], NROOTS-1);
//for (j=0; j<NROOTS-1; j++) bb[j] = bb[j+1];
if(feedback != A0)
bb[NROOTS-1] = alpha_to[modnn(feedback + gg[0])];
else
bb[NROOTS-1] = 0;
}
}
///*
int rs_decode(unsigned char *data, int *eras_pos, int no_eras){
int deg_lambda, el, deg_omega;
int i, j, r,k;
unsigned char u,q,tmp,num1,num2,den,discr_r;
unsigned char lambda[_NROOTS+1], s[_NROOTS];
unsigned char b[_NROOTS+1], t[_NROOTS+1], omega[_NROOTS+1];
unsigned char root[_NROOTS], reg[_NROOTS+1], loc[_NROOTS];
int syn_error, count;
// form the syndromes; i.e., evaluate data(x) at roots of g(x)
for(i=0;i<NROOTS;i++)
s[i] = data[0];
for(j=1;j<NN-PAD;j++){
for(i=0;i<NROOTS;i++){
if(s[i] == 0){
s[i] = data[j];
} else {
s[i] = data[j] ^ alpha_to[modnn(index_of[s[i]] + (FCR+i)*PRIM)];
}
}
}
// Convert syndromes to index form, checking for nonzero condition
syn_error = 0;
for(i=0;i<NROOTS;i++){
syn_error |= s[i];
s[i] = index_of[s[i]];
}
if (!syn_error) {
// if syndrome is zero, data[] is a codeword and there are no
// errors to correct. So return data[] unmodified
//
count = 0;
goto finish;
}
memset(&lambda[1],0,NROOTS*sizeof(lambda[0]));
lambda[0] = 1;
if (no_eras > 0) {
/* Init lambda to be the erasure locator polynomial */
lambda[1] = alpha_to[modnn(PRIM*(NN-1-eras_pos[0]))];
for (i = 1; i < no_eras; i++) {
u = modnn(PRIM*(NN-1-eras_pos[i]));
for (j = i+1; j > 0; j--) {
tmp = index_of[lambda[j - 1]];
if(tmp != A0)
lambda[j] ^= alpha_to[modnn(u + tmp)];
}
}
}
for(i=0;i<NROOTS+1;i++)
b[i] = index_of[lambda[i]];
/*
* Begin Berlekamp-Massey algorithm to determine error+erasure
* locator polynomial
*/
r = no_eras;
el = no_eras;
while (++r <= NROOTS) { /* r is the step number */
/* Compute discrepancy at the r-th step in poly-form */
discr_r = 0;
for (i = 0; i < r; i++){
if ((lambda[i] != 0) && (s[r-i-1] != A0)) {
discr_r ^= alpha_to[modnn(index_of[lambda[i]] + s[r-i-1])];
}
}
discr_r = index_of[discr_r]; /* Index form */
if (discr_r == A0) {
/* 2 lines below: B(x) <-- x*B(x) */
memmove(&b[1],b,NROOTS*sizeof(b[0]));
b[0] = A0;
} else {
/* 7 lines below: T(x) <-- lambda(x) - discr_r*x*b(x) */
t[0] = lambda[0];
for (i = 0 ; i < NROOTS; i++) {
if(b[i] != A0)
t[i+1] = lambda[i+1] ^ alpha_to[modnn(discr_r + b[i])];
else
t[i+1] = lambda[i+1];
}
if (2 * el <= r + no_eras - 1) {
el = r + no_eras - el;
/*
* 2 lines below: B(x) <-- inv(discr_r) *
* lambda(x)
*/
for (i = 0; i <= NROOTS; i++)
b[i] = (lambda[i] == 0) ? A0 : modnn(index_of[lambda[i]] - discr_r + NN);
} else {
/* 2 lines below: B(x) <-- x*B(x) */
memmove(&b[1],b,NROOTS*sizeof(b[0]));
b[0] = A0;
}
memcpy(lambda,t,(NROOTS+1)*sizeof(t[0]));
}
}
/* Convert lambda to index form and compute deg(lambda(x)) */
deg_lambda = 0;
for(i=0;i<NROOTS+1;i++){
lambda[i] = index_of[lambda[i]];
if(lambda[i] != A0)
deg_lambda = i;
}
/* Find roots of the error+erasure locator polynomial by Chien search */
memcpy(&reg[1],&lambda[1],NROOTS*sizeof(reg[0]));
count = 0; /* Number of roots of lambda(x) */
for (i = 1,k=IPRIM-1; i <= NN; i++,k = modnn(k+IPRIM)) {
q = 1; /* lambda[0] is always 0 */
for (j = deg_lambda; j > 0; j--){
if (reg[j] != A0) {
reg[j] = modnn(reg[j] + j);
q ^= alpha_to[reg[j]];
}
}
if (q != 0)
continue; /* Not a root */
/* store root (index-form) and error location number */
root[count] = i;
loc[count] = k;
/* If we've already found max possible roots,
* abort the search to save time
*/
if(++count == deg_lambda)
break;
}
if (deg_lambda != count) {
/*
* deg(lambda) unequal to number of roots => uncorrectable
* error detected
*/
count = -1;
goto finish;
}
/*
* Compute err+eras evaluator poly omega(x) = s(x)*lambda(x) (modulo
* x**NROOTS). in index form. Also find deg(omega).
*/
deg_omega = deg_lambda-1;
for (i = 0; i <= deg_omega;i++){
tmp = 0;
for(j=i;j >= 0; j--){
if ((s[i - j] != A0) && (lambda[j] != A0))
tmp ^= alpha_to[modnn(s[i - j] + lambda[j])];
}
omega[i] = index_of[tmp];
}
/*
* Compute error values in poly-form. num1 = omega(inv(X(l))), num2 =
* inv(X(l))**(FCR-1) and den = lambda_pr(inv(X(l))) all in poly-form
*/
for (j = count-1; j >=0; j--) {
num1 = 0;
for (i = deg_omega; i >= 0; i--) {
if (omega[i] != A0)
num1 ^= alpha_to[modnn(omega[i] + i * root[j])];
}
num2 = alpha_to[modnn(root[j] * (FCR - 1) + NN)];
den = 0;
/* lambda[i+1] for i even is the formal derivative lambda_pr of lambda[i] */
for (i = min(deg_lambda,NROOTS-1) & ~1; i >= 0; i -=2) {
if(lambda[i+1] != A0)
den ^= alpha_to[modnn(lambda[i+1] + i * root[j])];
}
/* Apply error to data */
if (num1 != 0 && loc[j] >= PAD) {
data[loc[j]-PAD] ^= alpha_to[modnn(index_of[num1] + index_of[num2] + NN - index_of[den])];
}
}
finish:
if(eras_pos != NULL){
for(i=0;i<count;i++)
eras_pos[i] = loc[i];
}
return count;
}

View file

@ -1,10 +1,10 @@
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
int modnn(int x);
void generate_gf();
void gen_poly();
void rs_encode(unsigned char *data, unsigned char *bb);
int rs_decode(unsigned char *data, int *eras_pos, int no_eras);
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
int modnn(int x);
void generate_gf();
void gen_poly();
void rs_encode(unsigned char *data, unsigned char *bb);
int rs_decode(unsigned char *data, int *eras_pos, int no_eras);

View file

@ -1,370 +1,370 @@
/***************************************************************************
* Copyright (C) 2007 by Arep *
* Support is provided through the forums at *
* http://wii.console-tribe.com *
* *
* 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. *
***************************************************************************/
/*! \file
* \brief Unscrambler for Nintendo GameCube/Wii discs.
*
* As Nintendo GameCube/Wii discs use the standars DVD-ROM scrambling algorithm, but with different, unknown, seeds, the actual seeds have to be brute-forced.
* The functions in this file take care of the brute-forcing and of the actual unscrambling of the read sectors.
*
* The code in this file has been derived from unscrambler 0.4, Copyright (C) 2006 Victor Muñoz (xt5@ingenieria-inversa.cl), GPL v2+,
* http://www.ingenieria-inversa.cl/?lp_lang_pref=en .
*/
#include "misc.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "constants.h"
#include "byteorder.h"
#include "ecma-267.h"
#include "unscrambler.h"
// #define unscramblerdebug(...) debug (__VA_ARGS__);
#define unscramblerdebug(...)
/*! \brief Size of the seeds cache (Do not touch) */
#define MAX_SEEDS 4
/*! \brief Number of bytes of a sector on which the EDC is calculated */
#define EDC_LENGTH (RAW_SECTOR_SIZE - 4) /* The EDC value is contained in the bottom 4 bytes of a frame */
/*! \brief A structure that represents a seed
*/
typedef struct t_seed {
int seed; //!< The seed, in numeric format.
unsigned char streamcipher[SECTOR_SIZE]; //!< The stream cipher generated from the seed through the LFSR.
} t_seed;
/*! \brief A structure that represents an unscrambler
*/
struct unscrambler_s {
t_seed seeds[(MAX_SEEDS + 1) * 16]; //!< The seeds cache.
bool bruteforce_seeds; //!< If true, whenever a seed for a sector is not cached, it will be found via a bruteforce attack, otherwise an error will be returned.
};
void unscrambler_set_disctype (u_int8_t disc_type){
disctype = disc_type;
// fprintf (stdout,"%d",disctype);
}
/**
* Adds a seed to the cache, calculating its streamcipher.
* @param seeds The seed cache.
* @param seed The seed to add.
* @return A structure representing the added seed, or NULL if it could not be added.
*/
static t_seed *add_seed (t_seed *seeds, unsigned short seed) {
int i;
t_seed *out;
unscramblerdebug ("Caching seed %04x\n", seed);
if (seeds -> seed == -2) {
out = NULL;
} else {
seeds -> seed = seed;
LFSR_init (seed);
for (i = 0; i < SECTOR_SIZE; i++)
seeds -> streamcipher[i] = LFSR_byte ();
out = seeds;
}
return (out);
}
/**
* Tests if the specified seed is the one used for the specified sector block: the check is done comparing the generated EDC with the one at the bottom of each
* sector. Sectors are processed in blocks, as the same seed is used for 16 consecutive sectors.
* @param buf The sector.
* @param j The seed.
* @return true if the seed is correct, false otherwise.
*/
static bool test_seed (u_int8_t *buf, int j) {
int i;
u_int8_t tmp[RAW_SECTOR_SIZE];
u_int32_t edc_calculated, edc_correct;
bool out;
memcpy (tmp, buf, RAW_SECTOR_SIZE);
LFSR_init (j);
for (i = 12; i < EDC_LENGTH; i++)
tmp[i] ^= LFSR_byte ();
edc_calculated = edc_calc (0x00000000, tmp, EDC_LENGTH);
edc_correct = my_ntohl (*((u_int32_t *) (&tmp[EDC_LENGTH])));
if (edc_calculated == edc_correct)
out = true;
else
out = false;
return (out);
}
/**
* Unscramble a complete block, using an already-cached seed.
* @param seed The seed to use for the unscrambling.
* @param _bin The 16-sector block to unscramble (RAW_BLOCK_SIZE).
* @param _bout The unscrambled 16-sector block (BLOCK_SIZE).
* @return True if the unscrambling was successful, false otherwise.
*/
static bool unscramble_frame (t_seed *seed, u_int8_t *_bin, u_int8_t *_bout) {
int i, j;
u_int8_t tmp[RAW_SECTOR_SIZE], *bin, *bout;
u_int32_t *_4bin, *_4cipher, edc_calculated, edc_correct;
bool out;
out = true;
for(j = 0; j < 16; j++) {
bin = &_bin[RAW_SECTOR_SIZE * j];
bout = &_bout[SECTOR_SIZE * j];
memcpy (tmp, bin, RAW_SECTOR_SIZE);
_4bin = (u_int32_t *) &tmp[12]; /* Scrambled data begin at byte 12 */
_4cipher = (u_int32_t *) seed -> streamcipher;
for (i = 0; i < 512; i++) /* Well, the scrambling algorithm is just a bitwise XOR... */
_4bin[i] ^= _4cipher[i];
//memcpy (bout, tmp + 6, SECTOR_SIZE); // copy CPR_MAI bytes
if (disctype==3) { //Regular
memcpy (bout, tmp + 12, SECTOR_SIZE); // DVD: copy 2048 bytes (starting from CPR_MAI)
}
else { //Nintendo
memcpy (bout, tmp + 6, SECTOR_SIZE); // Nintendo: copy 2048 bytes (up to CPR_MAI)
memcpy (&_bin[(RAW_SECTOR_SIZE * j)+2054], &tmp[2054], 6);
}
edc_calculated = edc_calc (0x00000000, tmp, EDC_LENGTH);
edc_correct = my_ntohl (*((u_int32_t *) (&tmp[EDC_LENGTH])));
if (edc_calculated != edc_correct) {
debug ("Bad EDC (%08x), must be %08x (sector = %d)", edc_calculated, edc_correct, j);
out = false;
}
}
return (out);
}
/**
* Initializes the seed cache.
* @param u The unscrambler structure.
*/
static void unscrambler_init_seeds (unscrambler *u) {
int i, j;
for (i = 0; i < 16; i++) {
for (j = 0; j < MAX_SEEDS; j++)
u -> seeds[i * MAX_SEEDS + j].seed = -1;
u -> seeds[i * MAX_SEEDS + j].seed = -2; // TODO Check what this does
}
return;
}
/**
* Creates a new structure representing an unscrambler.
* @return The newly-created structure, to be used with the other commands.
*/
unscrambler *unscrambler_new (void) {
unscrambler *u;
u = (unscrambler *) malloc (sizeof (unscrambler));
unscrambler_init_seeds (u);
u -> bruteforce_seeds = true;
return (u);
}
/**
* Frees resources used by an unscrambler structure and destroys it.
* @param u The unscrambler structure.
* @return NULL.
*/
void *unscrambler_destroy (unscrambler *u) {
my_free (u);
return (NULL);
}
void unscrambler_set_bruteforce (unscrambler *u, bool b) {
u -> bruteforce_seeds = b;
debug ("Seed bruteforcing %s", b ? "enabled" : "disabled");
return;
}
/**
* Unscrambles a 16-sector block.
* @param u The unscrambler structure.
* @param sector_no The number of the first sector in the block.
* @param inbuf The 16-sector block to unscramble. Each block must be RAW_SECTOR_SIZE bytes long, so that the total size is RAW_BLOCK_SIZE.
* @param outbuf The unscrambled 16-sector block. Each block will be SECTOR_SIZE bytes long, so that the total size is BLOCK_SIZE.
* @return True if the unscrambling was successful, false otherwise.
*/
bool unscrambler_unscramble_16sectors (unscrambler *u, u_int32_t sector_no, u_int8_t *inbuf, u_int8_t *outbuf) {
t_seed *seeds;
t_seed *current_seed;
int j;
bool out;
out = true;
seeds = &(u -> seeds[((sector_no / 16) & 0x0F) * MAX_SEEDS]);
/* Try to find the seed used for this sector */
current_seed = NULL;
while (!current_seed && (seeds -> seed) >= 0) {
if (test_seed (inbuf, seeds -> seed))
current_seed = seeds;
else
seeds++;
}
if (!current_seed && u -> bruteforce_seeds) {
/* The seed is not cached, yet. Try to find it with brute force... */
unscramblerdebug ("Brute-forcing seed for sector %d...", sector_no);
for (j = 0; !current_seed && j < 0x7FFF; j++) {
if (test_seed (inbuf, j)) {
if (!(current_seed = add_seed (seeds, j))) {
error ("No enough cache space for caching seed");
out = false;
}
}
}
if (current_seed)
unscramblerdebug ("Seed found: %04x", --j);
}
if (current_seed) {
/* OK, somehow seed was found: unscramble frame, write it and go on */
if (!unscramble_frame (current_seed, inbuf, outbuf)) {
error ("Error unscrambling frame %u\n", sector_no);
out = false;
} else {
out = true;
}
} else {
/* Well, we only get here if there are read errors */
error ("Cannot find seed for frame %u", sector_no);
out = false;
}
return (out);
}
/**
* Unscrambles a complete file.
* @param u The unscrambler structure.
* @param infile The input file name.
* @param outfile The output file name.
* @param progress A function to be called repeatedly during the operation, useful to report progress data/statistics.
* @param progress_data Data to be passed as-is to the progress function.
* @return True if the unscrambling was successful, false otherwise.
*/
bool unscrambler_unscramble_file (unscrambler *u, char *infile, char *outfile, unscrambler_progress_func progress, void *progress_data, u_int32_t *current_sector) {
FILE *in, *outfp;
bool out;
u_int8_t b_in[RAW_BLOCK_SIZE], b_out[BLOCK_SIZE];
size_t r;
my_off_t filesize;
int s;
u_int32_t total_sectors;
out = false;
if(!(in = fopen (infile ? infile : "", "rb"))) {
error ("Cannot open input file \"%s\"", infile);
} else if (!(outfp = fopen (outfile ? outfile : "", "wb"))) {
error ("Cannot open output file \"%s\"", outfile);
fclose (in);
} else {
/* Find out how many sectors we need to process */
my_fseek (in, 0, SEEK_END);
filesize = my_ftell (in);
total_sectors = (u_int32_t) (filesize / RAW_SECTOR_SIZE);
rewind (in);
/* First call to progress function */
if (progress)
progress (true, 0, total_sectors, progress_data);
s = 0, out = true;
while ((r = fread (b_in, 1, RAW_BLOCK_SIZE, in)) > 0 && out) {
if (r < RAW_BLOCK_SIZE) {
warning ("Short block read (%u bytes), padding with zeroes!", r);
memset (b_in + r, 0, sizeof (b_in) - r);
}
if (unscrambler_unscramble_16sectors (u, s, b_in, b_out)) {
clearerr (outfp);
if (!b_out) {
error ("NULL buffer");
out = false;
*(current_sector) = s;
}
else fwrite (b_out, SECTOR_SIZE, SECTORS_PER_BLOCK, outfp);
if (ferror (outfp)) {
error ("fwrite() to ISO output file failed");
out = false;
*(current_sector) = s;
}
} else {
debug ("unscrambler_unscramble_16sectors() failed");
out = false;
*(current_sector) = s;
}
s += 16;
if ((s % 320 == 0) || (s == total_sectors)) { //speedhack
if (progress)
progress (false, s, total_sectors, progress_data);
}
}
if (out) {
debug ("Image successfully unscrambled");
}
fclose (in);
fclose (outfp);
}
return (out);
}
/***************************************************************************
* Copyright (C) 2007 by Arep *
* Support is provided through the forums at *
* http://wii.console-tribe.com *
* *
* 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. *
***************************************************************************/
/*! \file
* \brief Unscrambler for Nintendo GameCube/Wii discs.
*
* As Nintendo GameCube/Wii discs use the standars DVD-ROM scrambling algorithm, but with different, unknown, seeds, the actual seeds have to be brute-forced.
* The functions in this file take care of the brute-forcing and of the actual unscrambling of the read sectors.
*
* The code in this file has been derived from unscrambler 0.4, Copyright (C) 2006 Victor Muñoz (xt5@ingenieria-inversa.cl), GPL v2+,
* http://www.ingenieria-inversa.cl/?lp_lang_pref=en .
*/
#include "misc.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "constants.h"
#include "byteorder.h"
#include "ecma-267.h"
#include "unscrambler.h"
// #define unscramblerdebug(...) debug (__VA_ARGS__);
#define unscramblerdebug(...)
/*! \brief Size of the seeds cache (Do not touch) */
#define MAX_SEEDS 4
/*! \brief Number of bytes of a sector on which the EDC is calculated */
#define EDC_LENGTH (RAW_SECTOR_SIZE - 4) /* The EDC value is contained in the bottom 4 bytes of a frame */
/*! \brief A structure that represents a seed
*/
typedef struct t_seed {
int seed; //!< The seed, in numeric format.
unsigned char streamcipher[SECTOR_SIZE]; //!< The stream cipher generated from the seed through the LFSR.
} t_seed;
/*! \brief A structure that represents an unscrambler
*/
struct unscrambler_s {
t_seed seeds[(MAX_SEEDS + 1) * 16]; //!< The seeds cache.
bool bruteforce_seeds; //!< If true, whenever a seed for a sector is not cached, it will be found via a bruteforce attack, otherwise an error will be returned.
};
void unscrambler_set_disctype (u_int8_t disc_type){
disctype = disc_type;
// fprintf (stdout,"%d",disctype);
}
/**
* Adds a seed to the cache, calculating its streamcipher.
* @param seeds The seed cache.
* @param seed The seed to add.
* @return A structure representing the added seed, or NULL if it could not be added.
*/
static t_seed *add_seed (t_seed *seeds, unsigned short seed) {
int i;
t_seed *out;
unscramblerdebug ("Caching seed %04x\n", seed);
if (seeds -> seed == -2) {
out = NULL;
} else {
seeds -> seed = seed;
LFSR_init (seed);
for (i = 0; i < SECTOR_SIZE; i++)
seeds -> streamcipher[i] = LFSR_byte ();
out = seeds;
}
return (out);
}
/**
* Tests if the specified seed is the one used for the specified sector block: the check is done comparing the generated EDC with the one at the bottom of each
* sector. Sectors are processed in blocks, as the same seed is used for 16 consecutive sectors.
* @param buf The sector.
* @param j The seed.
* @return true if the seed is correct, false otherwise.
*/
static bool test_seed (u_int8_t *buf, int j) {
int i;
u_int8_t tmp[RAW_SECTOR_SIZE];
u_int32_t edc_calculated, edc_correct;
bool out;
memcpy (tmp, buf, RAW_SECTOR_SIZE);
LFSR_init (j);
for (i = 12; i < EDC_LENGTH; i++)
tmp[i] ^= LFSR_byte ();
edc_calculated = edc_calc (0x00000000, tmp, EDC_LENGTH);
edc_correct = my_ntohl (*((u_int32_t *) (&tmp[EDC_LENGTH])));
if (edc_calculated == edc_correct)
out = true;
else
out = false;
return (out);
}
/**
* Unscramble a complete block, using an already-cached seed.
* @param seed The seed to use for the unscrambling.
* @param _bin The 16-sector block to unscramble (RAW_BLOCK_SIZE).
* @param _bout The unscrambled 16-sector block (BLOCK_SIZE).
* @return True if the unscrambling was successful, false otherwise.
*/
static bool unscramble_frame (t_seed *seed, u_int8_t *_bin, u_int8_t *_bout) {
int i, j;
u_int8_t tmp[RAW_SECTOR_SIZE], *bin, *bout;
u_int32_t *_4bin, *_4cipher, edc_calculated, edc_correct;
bool out;
out = true;
for(j = 0; j < 16; j++) {
bin = &_bin[RAW_SECTOR_SIZE * j];
bout = &_bout[SECTOR_SIZE * j];
memcpy (tmp, bin, RAW_SECTOR_SIZE);
_4bin = (u_int32_t *) &tmp[12]; /* Scrambled data begin at byte 12 */
_4cipher = (u_int32_t *) seed -> streamcipher;
for (i = 0; i < 512; i++) /* Well, the scrambling algorithm is just a bitwise XOR... */
_4bin[i] ^= _4cipher[i];
//memcpy (bout, tmp + 6, SECTOR_SIZE); // copy CPR_MAI bytes
if (disctype==3) { //Regular
memcpy (bout, tmp + 12, SECTOR_SIZE); // DVD: copy 2048 bytes (starting from CPR_MAI)
}
else { //Nintendo
memcpy (bout, tmp + 6, SECTOR_SIZE); // Nintendo: copy 2048 bytes (up to CPR_MAI)
memcpy (&_bin[(RAW_SECTOR_SIZE * j)+2054], &tmp[2054], 6);
}
edc_calculated = edc_calc (0x00000000, tmp, EDC_LENGTH);
edc_correct = my_ntohl (*((u_int32_t *) (&tmp[EDC_LENGTH])));
if (edc_calculated != edc_correct) {
debug ("Bad EDC (%08x), must be %08x (sector = %d)", edc_calculated, edc_correct, j);
out = false;
}
}
return (out);
}
/**
* Initializes the seed cache.
* @param u The unscrambler structure.
*/
static void unscrambler_init_seeds (unscrambler *u) {
int i, j;
for (i = 0; i < 16; i++) {
for (j = 0; j < MAX_SEEDS; j++)
u -> seeds[i * MAX_SEEDS + j].seed = -1;
u -> seeds[i * MAX_SEEDS + j].seed = -2; // TODO Check what this does
}
return;
}
/**
* Creates a new structure representing an unscrambler.
* @return The newly-created structure, to be used with the other commands.
*/
unscrambler *unscrambler_new (void) {
unscrambler *u;
u = (unscrambler *) malloc (sizeof (unscrambler));
unscrambler_init_seeds (u);
u -> bruteforce_seeds = true;
return (u);
}
/**
* Frees resources used by an unscrambler structure and destroys it.
* @param u The unscrambler structure.
* @return NULL.
*/
void *unscrambler_destroy (unscrambler *u) {
my_free (u);
return (NULL);
}
void unscrambler_set_bruteforce (unscrambler *u, bool b) {
u -> bruteforce_seeds = b;
debug ("Seed bruteforcing %s", b ? "enabled" : "disabled");
return;
}
/**
* Unscrambles a 16-sector block.
* @param u The unscrambler structure.
* @param sector_no The number of the first sector in the block.
* @param inbuf The 16-sector block to unscramble. Each block must be RAW_SECTOR_SIZE bytes long, so that the total size is RAW_BLOCK_SIZE.
* @param outbuf The unscrambled 16-sector block. Each block will be SECTOR_SIZE bytes long, so that the total size is BLOCK_SIZE.
* @return True if the unscrambling was successful, false otherwise.
*/
bool unscrambler_unscramble_16sectors (unscrambler *u, u_int32_t sector_no, u_int8_t *inbuf, u_int8_t *outbuf) {
t_seed *seeds;
t_seed *current_seed;
int j;
bool out;
out = true;
seeds = &(u -> seeds[((sector_no / 16) & 0x0F) * MAX_SEEDS]);
/* Try to find the seed used for this sector */
current_seed = NULL;
while (!current_seed && (seeds -> seed) >= 0) {
if (test_seed (inbuf, seeds -> seed))
current_seed = seeds;
else
seeds++;
}
if (!current_seed && u -> bruteforce_seeds) {
/* The seed is not cached, yet. Try to find it with brute force... */
unscramblerdebug ("Brute-forcing seed for sector %d...", sector_no);
for (j = 0; !current_seed && j < 0x7FFF; j++) {
if (test_seed (inbuf, j)) {
if (!(current_seed = add_seed (seeds, j))) {
error ("No enough cache space for caching seed");
out = false;
}
}
}
if (current_seed)
unscramblerdebug ("Seed found: %04x", --j);
}
if (current_seed) {
/* OK, somehow seed was found: unscramble frame, write it and go on */
if (!unscramble_frame (current_seed, inbuf, outbuf)) {
error ("Error unscrambling frame %u\n", sector_no);
out = false;
} else {
out = true;
}
} else {
/* Well, we only get here if there are read errors */
error ("Cannot find seed for frame %u", sector_no);
out = false;
}
return (out);
}
/**
* Unscrambles a complete file.
* @param u The unscrambler structure.
* @param infile The input file name.
* @param outfile The output file name.
* @param progress A function to be called repeatedly during the operation, useful to report progress data/statistics.
* @param progress_data Data to be passed as-is to the progress function.
* @return True if the unscrambling was successful, false otherwise.
*/
bool unscrambler_unscramble_file (unscrambler *u, char *infile, char *outfile, unscrambler_progress_func progress, void *progress_data, u_int32_t *current_sector) {
FILE *in, *outfp;
bool out;
u_int8_t b_in[RAW_BLOCK_SIZE], b_out[BLOCK_SIZE];
size_t r;
my_off_t filesize;
int s;
u_int32_t total_sectors;
out = false;
if(!(in = fopen (infile ? infile : "", "rb"))) {
error ("Cannot open input file \"%s\"", infile);
} else if (!(outfp = fopen (outfile ? outfile : "", "wb"))) {
error ("Cannot open output file \"%s\"", outfile);
fclose (in);
} else {
/* Find out how many sectors we need to process */
my_fseek (in, 0, SEEK_END);
filesize = my_ftell (in);
total_sectors = (u_int32_t) (filesize / RAW_SECTOR_SIZE);
rewind (in);
/* First call to progress function */
if (progress)
progress (true, 0, total_sectors, progress_data);
s = 0, out = true;
while ((r = fread (b_in, 1, RAW_BLOCK_SIZE, in)) > 0 && out) {
if (r < RAW_BLOCK_SIZE) {
warning ("Short block read (%u bytes), padding with zeroes!", r);
memset (b_in + r, 0, sizeof (b_in) - r);
}
if (unscrambler_unscramble_16sectors (u, s, b_in, b_out)) {
clearerr (outfp);
if (!b_out) {
error ("NULL buffer");
out = false;
*(current_sector) = s;
}
else fwrite (b_out, SECTOR_SIZE, SECTORS_PER_BLOCK, outfp);
if (ferror (outfp)) {
error ("fwrite() to ISO output file failed");
out = false;
*(current_sector) = s;
}
} else {
debug ("unscrambler_unscramble_16sectors() failed");
out = false;
*(current_sector) = s;
}
s += 16;
if ((s % 320 == 0) || (s == total_sectors)) { //speedhack
if (progress)
progress (false, s, total_sectors, progress_data);
}
}
if (out) {
debug ("Image successfully unscrambled");
}
fclose (in);
fclose (outfp);
}
return (out);
}

View file

@ -1,77 +1,77 @@
# Create a library called "Hello" which includes the source file "hello.cxx".
# The extension is already found. Any number of sources could be listed here.
add_library (
multihashlib
${libmultihash_type}
#SHARED
#STATIC
crc32.c
edonkey.c
md4.c
md5.c
multihash.c
sha1.c
crc32.h
edonkey.h
md4.h
md5.h
multihash.h
sha1.h
)
set_target_properties (multihashlib PROPERTIES OUTPUT_NAME "multihash")
# Before making a release, the LTVERSION string should be modified.
# The string is of the form CURRENT:REVISION:AGE.
#
# CURRENT (C)
# The most recent interface number that this library implements.
#
# REVISION (R)
# The implementation number that this library implements.
#
# AGE (A)
# The difference between the newest and oldest interfaces that this
# library implements. In other works, the library implements all the
# interface numbers in the range from number 'CURRENT - AGE' to
# 'CURRENT'.
#
# This means that:
#
# - If interfaces have been changed or added, but binary compatibility has
# been preserved, change to C+1:0:A+1
#
# - If binary compatibility has been broken (eg removed or changed
# interfaces) change to C+1:0:0
#
# - If the interface is the same as the previous version, change to C:R+1:A
#
set_target_properties (multihashlib PROPERTIES SOVERSION 1.0.0)
#get_target_property(libhash_type multihashlib TYPE)
if (WIN32)
if (libhash_type STREQUAL "SHARED")
# MESSAGE ("Building libmultihash DLL")
ADD_DEFINITIONS (-DMULTIHASH_BUILD_DLL)
set_target_properties (multihashlib PROPERTIES DEFINE_SYMBOL MULTIHASH_EXPORTS)
install (
TARGETS multihashlib
RUNTIME DESTINATION /
#ARCHIVE DESTINATION lib
)
endif (libhash_type STREQUAL "SHARED")
else (WIN32)
# Install stuff, only if a shared library is being built
if (libhash_type STREQUAL "SHARED")
install (
TARGETS multihashlib
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib/static
)
endif (libhash_type STREQUAL "SHARED")
endif (WIN32)
# Create a library called "Hello" which includes the source file "hello.cxx".
# The extension is already found. Any number of sources could be listed here.
add_library (
multihashlib
${libmultihash_type}
#SHARED
#STATIC
crc32.c
edonkey.c
md4.c
md5.c
multihash.c
sha1.c
crc32.h
edonkey.h
md4.h
md5.h
multihash.h
sha1.h
)
set_target_properties (multihashlib PROPERTIES OUTPUT_NAME "multihash")
# Before making a release, the LTVERSION string should be modified.
# The string is of the form CURRENT:REVISION:AGE.
#
# CURRENT (C)
# The most recent interface number that this library implements.
#
# REVISION (R)
# The implementation number that this library implements.
#
# AGE (A)
# The difference between the newest and oldest interfaces that this
# library implements. In other works, the library implements all the
# interface numbers in the range from number 'CURRENT - AGE' to
# 'CURRENT'.
#
# This means that:
#
# - If interfaces have been changed or added, but binary compatibility has
# been preserved, change to C+1:0:A+1
#
# - If binary compatibility has been broken (eg removed or changed
# interfaces) change to C+1:0:0
#
# - If the interface is the same as the previous version, change to C:R+1:A
#
set_target_properties (multihashlib PROPERTIES SOVERSION 1.0.0)
#get_target_property(libhash_type multihashlib TYPE)
if (WIN32)
if (libhash_type STREQUAL "SHARED")
# MESSAGE ("Building libmultihash DLL")
ADD_DEFINITIONS (-DMULTIHASH_BUILD_DLL)
set_target_properties (multihashlib PROPERTIES DEFINE_SYMBOL MULTIHASH_EXPORTS)
install (
TARGETS multihashlib
RUNTIME DESTINATION /
#ARCHIVE DESTINATION lib
)
endif (libhash_type STREQUAL "SHARED")
else (WIN32)
# Install stuff, only if a shared library is being built
if (libhash_type STREQUAL "SHARED")
install (
TARGETS multihashlib
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib/static
)
endif (libhash_type STREQUAL "SHARED")
endif (WIN32)

View file

@ -1,120 +1,120 @@
/*
* Copyright (c) 1995, Edward B. Hamrick
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that
*
* (i) the above copyright notice and the text in this "C" comment block
* appear in all copies of the software and related documentation, and
*
* (ii) any modifications to this source file must be sent, via e-mail
* to the copyright owner (currently hamrick@primenet.com) within
* 30 days of such modification.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL EDWARD B. HAMRICK BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
* THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "crc32.h"
/* This is a pre-computed table to make crc computations efficient */
static unsigned long crctable[] = {
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL,
0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L,
0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L,
0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L,
0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L,
0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL,
0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L,
0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L,
0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L,
0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L,
0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L,
0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL,
0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL,
0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL,
0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L,
0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L,
0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL,
0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L,
0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL,
0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L,
0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL,
0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L,
0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L,
0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L,
0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L,
0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL,
0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL,
0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L,
0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L,
0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL,
0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L,
0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL,
0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L,
0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL,
0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L,
0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L,
0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL,
0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L,
0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL,
0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL,
0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L,
0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L,
0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL,
0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L,
0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L,
0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L,
0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL,
0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L,
0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L,
0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL,
0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L,
0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL
};
/*
* This CRC algorithm is the same as that used in zip. Normally it
* should be initialized with 0xffffffff, and the final CRC stored
* should be crc ^ 0xffffffff.
*
* It implements the polynomial:
*
* x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1
*/
unsigned long CrcUpdate( /* returns updated crc */
unsigned long crc, /* starting crc */
unsigned char *buffer, /* buffer to use to update crc */
long length /* length of buffer */
)
{
long i;
for (i=0; i<length; i++)
{
crc = crctable[buffer[i] ^ ((unsigned char) crc)] ^ (crc >> 8);
}
return crc;
}
/*
* Copyright (c) 1995, Edward B. Hamrick
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that
*
* (i) the above copyright notice and the text in this "C" comment block
* appear in all copies of the software and related documentation, and
*
* (ii) any modifications to this source file must be sent, via e-mail
* to the copyright owner (currently hamrick@primenet.com) within
* 30 days of such modification.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL EDWARD B. HAMRICK BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
* THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "crc32.h"
/* This is a pre-computed table to make crc computations efficient */
static unsigned long crctable[] = {
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL,
0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L,
0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L,
0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L,
0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L,
0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL,
0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L,
0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L,
0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L,
0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L,
0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L,
0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL,
0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL,
0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL,
0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L,
0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L,
0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL,
0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L,
0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL,
0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L,
0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL,
0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L,
0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L,
0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L,
0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L,
0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL,
0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL,
0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L,
0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L,
0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL,
0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L,
0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL,
0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L,
0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL,
0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L,
0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L,
0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL,
0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L,
0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL,
0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL,
0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L,
0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L,
0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL,
0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L,
0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L,
0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L,
0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL,
0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L,
0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L,
0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL,
0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L,
0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL
};
/*
* This CRC algorithm is the same as that used in zip. Normally it
* should be initialized with 0xffffffff, and the final CRC stored
* should be crc ^ 0xffffffff.
*
* It implements the polynomial:
*
* x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1
*/
unsigned long CrcUpdate( /* returns updated crc */
unsigned long crc, /* starting crc */
unsigned char *buffer, /* buffer to use to update crc */
long length /* length of buffer */
)
{
long i;
for (i=0; i<length; i++)
{
crc = crctable[buffer[i] ^ ((unsigned char) crc)] ^ (crc >> 8);
}
return crc;
}

View file

@ -1,53 +1,53 @@
/*
* Copyright (c) 1995, Edward B. Hamrick
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that
*
* (i) the above copyright notice and the text in this "C" comment block
* appear in all copies of the software and related documentation, and
*
* (ii) any modifications to this source file must be sent, via e-mail
* to the copyright owner (currently hamrick@primenet.com) within
* 30 days of such modification.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL EDWARD B. HAMRICK BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
* THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* This CRC algorithm is the same as that used in zip. Normally it
* should be initialized with 0xffffffff, and the final CRC stored
* should be crc ^ 0xffffffff.
*
* It implements the polynomial:
*
* x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1
*/
#ifndef __CRC_H
#define __CRC_H
#ifdef __cplusplus
extern "C" {
#endif
unsigned long CrcUpdate( /* returns updated crc */
unsigned long crc, /* starting crc */
unsigned char *buffer, /* buffer to use to update crc */
long length /* length of buffer */
);
#ifdef __cplusplus
}
#endif
#endif
/*
* Copyright (c) 1995, Edward B. Hamrick
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that
*
* (i) the above copyright notice and the text in this "C" comment block
* appear in all copies of the software and related documentation, and
*
* (ii) any modifications to this source file must be sent, via e-mail
* to the copyright owner (currently hamrick@primenet.com) within
* 30 days of such modification.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL EDWARD B. HAMRICK BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
* THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* This CRC algorithm is the same as that used in zip. Normally it
* should be initialized with 0xffffffff, and the final CRC stored
* should be crc ^ 0xffffffff.
*
* It implements the polynomial:
*
* x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1
*/
#ifndef __CRC_H
#define __CRC_H
#ifdef __cplusplus
extern "C" {
#endif
unsigned long CrcUpdate( /* returns updated crc */
unsigned long crc, /* starting crc */
unsigned char *buffer, /* buffer to use to update crc */
long length /* length of buffer */
);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -1,477 +1,477 @@
/*
**********************************************************************
** md5.c **
** RSA Data Security, Inc. MD5 Message Digest Algorithm **
** Created: 2/17/90 RLR **
** Revised: 1/91 SRD,AJ,BSK,JT Reference C Version **
**********************************************************************
*/
/*
**********************************************************************
** 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 the following line if the md5.h header file is separate -- */
#include "md5.h"
/* 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 and H are basic MD5 functions: selection, majority, parity */
#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); \
}
void MD5Init (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;
}
void MD5Update (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;
}
}
}
void MD5Final (mdContext)
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);
MD5Update (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);
}
}
/* Basic MD5 step. Transform 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, 3614090360U); /* 1 */
FF ( d, a, b, c, in[ 1], S12, 3905402710U); /* 2 */
FF ( c, d, a, b, in[ 2], S13, 606105819U); /* 3 */
FF ( b, c, d, a, in[ 3], S14, 3250441966U); /* 4 */
FF ( a, b, c, d, in[ 4], S11, 4118548399U); /* 5 */
FF ( d, a, b, c, in[ 5], S12, 1200080426U); /* 6 */
FF ( c, d, a, b, in[ 6], S13, 2821735955U); /* 7 */
FF ( b, c, d, a, in[ 7], S14, 4249261313U); /* 8 */
FF ( a, b, c, d, in[ 8], S11, 1770035416U); /* 9 */
FF ( d, a, b, c, in[ 9], S12, 2336552879U); /* 10 */
FF ( c, d, a, b, in[10], S13, 4294925233U); /* 11 */
FF ( b, c, d, a, in[11], S14, 2304563134U); /* 12 */
FF ( a, b, c, d, in[12], S11, 1804603682U); /* 13 */
FF ( d, a, b, c, in[13], S12, 4254626195U); /* 14 */
FF ( c, d, a, b, in[14], S13, 2792965006U); /* 15 */
FF ( b, c, d, a, in[15], S14, 1236535329U); /* 16 */
/* Round 2 */
#define S21 5
#define S22 9
#define S23 14
#define S24 20
GG ( a, b, c, d, in[ 1], S21, 4129170786U); /* 17 */
GG ( d, a, b, c, in[ 6], S22, 3225465664U); /* 18 */
GG ( c, d, a, b, in[11], S23, 643717713U); /* 19 */
GG ( b, c, d, a, in[ 0], S24, 3921069994U); /* 20 */
GG ( a, b, c, d, in[ 5], S21, 3593408605U); /* 21 */
GG ( d, a, b, c, in[10], S22, 38016083U); /* 22 */
GG ( c, d, a, b, in[15], S23, 3634488961U); /* 23 */
GG ( b, c, d, a, in[ 4], S24, 3889429448U); /* 24 */
GG ( a, b, c, d, in[ 9], S21, 568446438U); /* 25 */
GG ( d, a, b, c, in[14], S22, 3275163606U); /* 26 */
GG ( c, d, a, b, in[ 3], S23, 4107603335U); /* 27 */
GG ( b, c, d, a, in[ 8], S24, 1163531501U); /* 28 */
GG ( a, b, c, d, in[13], S21, 2850285829U); /* 29 */
GG ( d, a, b, c, in[ 2], S22, 4243563512U); /* 30 */
GG ( c, d, a, b, in[ 7], S23, 1735328473U); /* 31 */
GG ( b, c, d, a, in[12], S24, 2368359562U); /* 32 */
/* Round 3 */
#define S31 4
#define S32 11
#define S33 16
#define S34 23
HH ( a, b, c, d, in[ 5], S31, 4294588738U); /* 33 */
HH ( d, a, b, c, in[ 8], S32, 2272392833U); /* 34 */
HH ( c, d, a, b, in[11], S33, 1839030562U); /* 35 */
HH ( b, c, d, a, in[14], S34, 4259657740U); /* 36 */
HH ( a, b, c, d, in[ 1], S31, 2763975236U); /* 37 */
HH ( d, a, b, c, in[ 4], S32, 1272893353U); /* 38 */
HH ( c, d, a, b, in[ 7], S33, 4139469664U); /* 39 */
HH ( b, c, d, a, in[10], S34, 3200236656U); /* 40 */
HH ( a, b, c, d, in[13], S31, 681279174U); /* 41 */
HH ( d, a, b, c, in[ 0], S32, 3936430074U); /* 42 */
HH ( c, d, a, b, in[ 3], S33, 3572445317U); /* 43 */
HH ( b, c, d, a, in[ 6], S34, 76029189U); /* 44 */
HH ( a, b, c, d, in[ 9], S31, 3654602809U); /* 45 */
HH ( d, a, b, c, in[12], S32, 3873151461U); /* 46 */
HH ( c, d, a, b, in[15], S33, 530742520U); /* 47 */
HH ( b, c, d, a, in[ 2], S34, 3299628645U); /* 48 */
/* Round 4 */
#define S41 6
#define S42 10
#define S43 15
#define S44 21
II ( a, b, c, d, in[ 0], S41, 4096336452U); /* 49 */
II ( d, a, b, c, in[ 7], S42, 1126891415U); /* 50 */
II ( c, d, a, b, in[14], S43, 2878612391U); /* 51 */
II ( b, c, d, a, in[ 5], S44, 4237533241U); /* 52 */
II ( a, b, c, d, in[12], S41, 1700485571U); /* 53 */
II ( d, a, b, c, in[ 3], S42, 2399980690U); /* 54 */
II ( c, d, a, b, in[10], S43, 4293915773U); /* 55 */
II ( b, c, d, a, in[ 1], S44, 2240044497U); /* 56 */
II ( a, b, c, d, in[ 8], S41, 1873313359U); /* 57 */
II ( d, a, b, c, in[15], S42, 4264355552U); /* 58 */
II ( c, d, a, b, in[ 6], S43, 2734768916U); /* 59 */
II ( b, c, d, a, in[13], S44, 1309151649U); /* 60 */
II ( a, b, c, d, in[ 4], S41, 4149444226U); /* 61 */
II ( d, a, b, c, in[11], S42, 3174756917U); /* 62 */
II ( c, d, a, b, in[ 2], S43, 718787259U); /* 63 */
II ( b, c, d, a, in[ 9], S44, 3951481745U); /* 64 */
buf[0] += a;
buf[1] += b;
buf[2] += c;
buf[3] += d;
}
/*
**********************************************************************
** End of md5.c **
******************************* (cut) ********************************
*/
#if 0
/*
**********************************************************************
** md5driver.c -- sample routines to test **
** RSA Data Security, Inc. MD5 message digest algorithm. **
** Created: 2/16/90 RLR **
** Updated: 1/91 SRD **
**********************************************************************
*/
/*
**********************************************************************
** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
** **
** 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 <stdio.h>
#include <sys/types.h>
#include <time.h>
#include <string.h>
/* -- include the following file if the file md5.h is separate -- */
/* #include "md5.h" */
/* Prints message digest buffer in mdContext as 32 hexadecimal digits.
Order is from low-order byte to high-order byte of digest.
Each byte is printed with high-order hexadecimal digit first.
*/
static void MDPrint (mdContext)
MD5_CTX *mdContext;
{
int i;
for (i = 0; i < 16; i++)
printf ("%02x", mdContext->digest[i]);
}
/* size of test block */
#define TEST_BLOCK_SIZE 1000
/* number of blocks to process */
#define TEST_BLOCKS 10000
/* number of test bytes = TEST_BLOCK_SIZE * TEST_BLOCKS */
static long TEST_BYTES = (long)TEST_BLOCK_SIZE * (long)TEST_BLOCKS;
/* A time trial routine, to measure the speed of MD5.
Measures wall time required to digest TEST_BLOCKS * TEST_BLOCK_SIZE
characters.
*/
static void MDTimeTrial ()
{
MD5_CTX mdContext;
time_t endTime, startTime;
unsigned char data[TEST_BLOCK_SIZE];
unsigned int i;
/* initialize test data */
for (i = 0; i < TEST_BLOCK_SIZE; i++)
data[i] = (unsigned char)(i & 0xFF);
/* start timer */
printf ("MD5 time trial. Processing %ld characters...\n", TEST_BYTES);
time (&startTime);
/* digest data in TEST_BLOCK_SIZE byte blocks */
MD5Init (&mdContext);
for (i = TEST_BLOCKS; i > 0; i--)
MD5Update (&mdContext, data, TEST_BLOCK_SIZE);
MD5Final (&mdContext);
/* stop timer, get time difference */
time (&endTime);
MDPrint (&mdContext);
printf (" is digest of test input.\n");
printf
("Seconds to process test input: %ld\n", (long)(endTime-startTime));
printf
("Characters processed per second: %ld\n",
TEST_BYTES/(endTime-startTime));
}
/* Computes the message digest for string inString.
Prints out message digest, a space, the string (in quotes) and a
carriage return.
*/
static void MDString (inString)
char *inString;
{
MD5_CTX mdContext;
unsigned int len = strlen (inString);
MD5Init (&mdContext);
MD5Update (&mdContext, inString, len);
MD5Final (&mdContext);
MDPrint (&mdContext);
printf (" \"%s\"\n\n", inString);
}
/* Computes the message digest for a specified file.
Prints out message digest, a space, the file name, and a carriage
return.
*/
static void MDFile (filename)
char *filename;
{
FILE *inFile = fopen (filename, "rb");
MD5_CTX mdContext;
int bytes;
unsigned char data[1024];
if (inFile == NULL) {
printf ("%s can't be opened.\n", filename);
return;
}
MD5Init (&mdContext);
while ((bytes = fread (data, 1, 1024, inFile)) != 0)
MD5Update (&mdContext, data, bytes);
MD5Final (&mdContext);
MDPrint (&mdContext);
printf (" %s\n", filename);
fclose (inFile);
}
/* Writes the message digest of the data from stdin onto stdout,
followed by a carriage return.
*/
static void MDFilter ()
{
MD5_CTX mdContext;
int bytes;
unsigned char data[16];
MD5Init (&mdContext);
while ((bytes = fread (data, 1, 16, stdin)) != 0)
MD5Update (&mdContext, data, bytes);
MD5Final (&mdContext);
MDPrint (&mdContext);
printf ("\n");
}
/* Runs a standard suite of test data.
*/
static void MDTestSuite ()
{
printf ("MD5 test suite results:\n\n");
MDString ("");
MDString ("a");
MDString ("abc");
MDString ("message digest");
MDString ("abcdefghijklmnopqrstuvwxyz");
MDString
("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
MDString
("1234567890123456789012345678901234567890\
1234567890123456789012345678901234567890");
/* Contents of file foo are "abc" */
MDFile ("foo");
}
void main (argc, argv)
int argc;
char *argv[];
{
int i;
/* For each command line argument in turn:
** filename -- prints message digest and name of file
** -sstring -- prints message digest and contents of string
** -t -- prints time trial statistics for 1M characters
** -x -- execute a standard suite of test data
** (no args) -- writes messages digest of stdin onto stdout
*/
if (argc == 1)
MDFilter ();
else
for (i = 1; i < argc; i++)
if (argv[i][0] == '-' && argv[i][1] == 's')
MDString (argv[i] + 2);
else if (strcmp (argv[i], "-t") == 0)
MDTimeTrial ();
else if (strcmp (argv[i], "-x") == 0)
MDTestSuite ();
else MDFile (argv[i]);
}
/*
**********************************************************************
** End of md5driver.c **
******************************* (cut) ********************************
*/
#endif
/*
**********************************************************************
** md5.c **
** RSA Data Security, Inc. MD5 Message Digest Algorithm **
** Created: 2/17/90 RLR **
** Revised: 1/91 SRD,AJ,BSK,JT Reference C Version **
**********************************************************************
*/
/*
**********************************************************************
** 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 the following line if the md5.h header file is separate -- */
#include "md5.h"
/* 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 and H are basic MD5 functions: selection, majority, parity */
#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); \
}
void MD5Init (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;
}
void MD5Update (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;
}
}
}
void MD5Final (mdContext)
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);
MD5Update (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);
}
}
/* Basic MD5 step. Transform 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, 3614090360U); /* 1 */
FF ( d, a, b, c, in[ 1], S12, 3905402710U); /* 2 */
FF ( c, d, a, b, in[ 2], S13, 606105819U); /* 3 */
FF ( b, c, d, a, in[ 3], S14, 3250441966U); /* 4 */
FF ( a, b, c, d, in[ 4], S11, 4118548399U); /* 5 */
FF ( d, a, b, c, in[ 5], S12, 1200080426U); /* 6 */
FF ( c, d, a, b, in[ 6], S13, 2821735955U); /* 7 */
FF ( b, c, d, a, in[ 7], S14, 4249261313U); /* 8 */
FF ( a, b, c, d, in[ 8], S11, 1770035416U); /* 9 */
FF ( d, a, b, c, in[ 9], S12, 2336552879U); /* 10 */
FF ( c, d, a, b, in[10], S13, 4294925233U); /* 11 */
FF ( b, c, d, a, in[11], S14, 2304563134U); /* 12 */
FF ( a, b, c, d, in[12], S11, 1804603682U); /* 13 */
FF ( d, a, b, c, in[13], S12, 4254626195U); /* 14 */
FF ( c, d, a, b, in[14], S13, 2792965006U); /* 15 */
FF ( b, c, d, a, in[15], S14, 1236535329U); /* 16 */
/* Round 2 */
#define S21 5
#define S22 9
#define S23 14
#define S24 20
GG ( a, b, c, d, in[ 1], S21, 4129170786U); /* 17 */
GG ( d, a, b, c, in[ 6], S22, 3225465664U); /* 18 */
GG ( c, d, a, b, in[11], S23, 643717713U); /* 19 */
GG ( b, c, d, a, in[ 0], S24, 3921069994U); /* 20 */
GG ( a, b, c, d, in[ 5], S21, 3593408605U); /* 21 */
GG ( d, a, b, c, in[10], S22, 38016083U); /* 22 */
GG ( c, d, a, b, in[15], S23, 3634488961U); /* 23 */
GG ( b, c, d, a, in[ 4], S24, 3889429448U); /* 24 */
GG ( a, b, c, d, in[ 9], S21, 568446438U); /* 25 */
GG ( d, a, b, c, in[14], S22, 3275163606U); /* 26 */
GG ( c, d, a, b, in[ 3], S23, 4107603335U); /* 27 */
GG ( b, c, d, a, in[ 8], S24, 1163531501U); /* 28 */
GG ( a, b, c, d, in[13], S21, 2850285829U); /* 29 */
GG ( d, a, b, c, in[ 2], S22, 4243563512U); /* 30 */
GG ( c, d, a, b, in[ 7], S23, 1735328473U); /* 31 */
GG ( b, c, d, a, in[12], S24, 2368359562U); /* 32 */
/* Round 3 */
#define S31 4
#define S32 11
#define S33 16
#define S34 23
HH ( a, b, c, d, in[ 5], S31, 4294588738U); /* 33 */
HH ( d, a, b, c, in[ 8], S32, 2272392833U); /* 34 */
HH ( c, d, a, b, in[11], S33, 1839030562U); /* 35 */
HH ( b, c, d, a, in[14], S34, 4259657740U); /* 36 */
HH ( a, b, c, d, in[ 1], S31, 2763975236U); /* 37 */
HH ( d, a, b, c, in[ 4], S32, 1272893353U); /* 38 */
HH ( c, d, a, b, in[ 7], S33, 4139469664U); /* 39 */
HH ( b, c, d, a, in[10], S34, 3200236656U); /* 40 */
HH ( a, b, c, d, in[13], S31, 681279174U); /* 41 */
HH ( d, a, b, c, in[ 0], S32, 3936430074U); /* 42 */
HH ( c, d, a, b, in[ 3], S33, 3572445317U); /* 43 */
HH ( b, c, d, a, in[ 6], S34, 76029189U); /* 44 */
HH ( a, b, c, d, in[ 9], S31, 3654602809U); /* 45 */
HH ( d, a, b, c, in[12], S32, 3873151461U); /* 46 */
HH ( c, d, a, b, in[15], S33, 530742520U); /* 47 */
HH ( b, c, d, a, in[ 2], S34, 3299628645U); /* 48 */
/* Round 4 */
#define S41 6
#define S42 10
#define S43 15
#define S44 21
II ( a, b, c, d, in[ 0], S41, 4096336452U); /* 49 */
II ( d, a, b, c, in[ 7], S42, 1126891415U); /* 50 */
II ( c, d, a, b, in[14], S43, 2878612391U); /* 51 */
II ( b, c, d, a, in[ 5], S44, 4237533241U); /* 52 */
II ( a, b, c, d, in[12], S41, 1700485571U); /* 53 */
II ( d, a, b, c, in[ 3], S42, 2399980690U); /* 54 */
II ( c, d, a, b, in[10], S43, 4293915773U); /* 55 */
II ( b, c, d, a, in[ 1], S44, 2240044497U); /* 56 */
II ( a, b, c, d, in[ 8], S41, 1873313359U); /* 57 */
II ( d, a, b, c, in[15], S42, 4264355552U); /* 58 */
II ( c, d, a, b, in[ 6], S43, 2734768916U); /* 59 */
II ( b, c, d, a, in[13], S44, 1309151649U); /* 60 */
II ( a, b, c, d, in[ 4], S41, 4149444226U); /* 61 */
II ( d, a, b, c, in[11], S42, 3174756917U); /* 62 */
II ( c, d, a, b, in[ 2], S43, 718787259U); /* 63 */
II ( b, c, d, a, in[ 9], S44, 3951481745U); /* 64 */
buf[0] += a;
buf[1] += b;
buf[2] += c;
buf[3] += d;
}
/*
**********************************************************************
** End of md5.c **
******************************* (cut) ********************************
*/
#if 0
/*
**********************************************************************
** md5driver.c -- sample routines to test **
** RSA Data Security, Inc. MD5 message digest algorithm. **
** Created: 2/16/90 RLR **
** Updated: 1/91 SRD **
**********************************************************************
*/
/*
**********************************************************************
** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
** **
** 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 <stdio.h>
#include <sys/types.h>
#include <time.h>
#include <string.h>
/* -- include the following file if the file md5.h is separate -- */
/* #include "md5.h" */
/* Prints message digest buffer in mdContext as 32 hexadecimal digits.
Order is from low-order byte to high-order byte of digest.
Each byte is printed with high-order hexadecimal digit first.
*/
static void MDPrint (mdContext)
MD5_CTX *mdContext;
{
int i;
for (i = 0; i < 16; i++)
printf ("%02x", mdContext->digest[i]);
}
/* size of test block */
#define TEST_BLOCK_SIZE 1000
/* number of blocks to process */
#define TEST_BLOCKS 10000
/* number of test bytes = TEST_BLOCK_SIZE * TEST_BLOCKS */
static long TEST_BYTES = (long)TEST_BLOCK_SIZE * (long)TEST_BLOCKS;
/* A time trial routine, to measure the speed of MD5.
Measures wall time required to digest TEST_BLOCKS * TEST_BLOCK_SIZE
characters.
*/
static void MDTimeTrial ()
{
MD5_CTX mdContext;
time_t endTime, startTime;
unsigned char data[TEST_BLOCK_SIZE];
unsigned int i;
/* initialize test data */
for (i = 0; i < TEST_BLOCK_SIZE; i++)
data[i] = (unsigned char)(i & 0xFF);
/* start timer */
printf ("MD5 time trial. Processing %ld characters...\n", TEST_BYTES);
time (&startTime);
/* digest data in TEST_BLOCK_SIZE byte blocks */
MD5Init (&mdContext);
for (i = TEST_BLOCKS; i > 0; i--)
MD5Update (&mdContext, data, TEST_BLOCK_SIZE);
MD5Final (&mdContext);
/* stop timer, get time difference */
time (&endTime);
MDPrint (&mdContext);
printf (" is digest of test input.\n");
printf
("Seconds to process test input: %ld\n", (long)(endTime-startTime));
printf
("Characters processed per second: %ld\n",
TEST_BYTES/(endTime-startTime));
}
/* Computes the message digest for string inString.
Prints out message digest, a space, the string (in quotes) and a
carriage return.
*/
static void MDString (inString)
char *inString;
{
MD5_CTX mdContext;
unsigned int len = strlen (inString);
MD5Init (&mdContext);
MD5Update (&mdContext, inString, len);
MD5Final (&mdContext);
MDPrint (&mdContext);
printf (" \"%s\"\n\n", inString);
}
/* Computes the message digest for a specified file.
Prints out message digest, a space, the file name, and a carriage
return.
*/
static void MDFile (filename)
char *filename;
{
FILE *inFile = fopen (filename, "rb");
MD5_CTX mdContext;
int bytes;
unsigned char data[1024];
if (inFile == NULL) {
printf ("%s can't be opened.\n", filename);
return;
}
MD5Init (&mdContext);
while ((bytes = fread (data, 1, 1024, inFile)) != 0)
MD5Update (&mdContext, data, bytes);
MD5Final (&mdContext);
MDPrint (&mdContext);
printf (" %s\n", filename);
fclose (inFile);
}
/* Writes the message digest of the data from stdin onto stdout,
followed by a carriage return.
*/
static void MDFilter ()
{
MD5_CTX mdContext;
int bytes;
unsigned char data[16];
MD5Init (&mdContext);
while ((bytes = fread (data, 1, 16, stdin)) != 0)
MD5Update (&mdContext, data, bytes);
MD5Final (&mdContext);
MDPrint (&mdContext);
printf ("\n");
}
/* Runs a standard suite of test data.
*/
static void MDTestSuite ()
{
printf ("MD5 test suite results:\n\n");
MDString ("");
MDString ("a");
MDString ("abc");
MDString ("message digest");
MDString ("abcdefghijklmnopqrstuvwxyz");
MDString
("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
MDString
("1234567890123456789012345678901234567890\
1234567890123456789012345678901234567890");
/* Contents of file foo are "abc" */
MDFile ("foo");
}
void main (argc, argv)
int argc;
char *argv[];
{
int i;
/* For each command line argument in turn:
** filename -- prints message digest and name of file
** -sstring -- prints message digest and contents of string
** -t -- prints time trial statistics for 1M characters
** -x -- execute a standard suite of test data
** (no args) -- writes messages digest of stdin onto stdout
*/
if (argc == 1)
MDFilter ();
else
for (i = 1; i < argc; i++)
if (argv[i][0] == '-' && argv[i][1] == 's')
MDString (argv[i] + 2);
else if (strcmp (argv[i], "-t") == 0)
MDTimeTrial ();
else if (strcmp (argv[i], "-x") == 0)
MDTestSuite ();
else MDFile (argv[i]);
}
/*
**********************************************************************
** End of md5driver.c **
******************************* (cut) ********************************
*/
#endif

View file

@ -1,127 +1,127 @@
/***************************************************************************
* Copyright (C) 2007 by SukkoPera *
* sukkopera@sukkology.net *
* *
* 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. *
***************************************************************************/
#ifndef MULTIHASH_H_INCLUDED
#define MULTIHASH_H_INCLUDED
#ifdef WIN32
#include <windows.h>
/* Definition of the types we use for Windows */
#define u_int8_t BYTE
#define u_int16_t WORD
#define u_int32_t DWORD
/* Some functions have different names */
#define snprintf _snprintf
/* Stuff to export library symbols */
#ifdef MULTIHASH_BUILD_DLL
#ifdef MULTIHASH_EXPORTS
#define MULTIHASH_EXPORT __declspec(dllexport) /* Building the lib */
#else
#define MULTIHASH_EXPORT __declspec(dllimport) /* Building user code */
#endif
#else
#define MULTIHASH_EXPORT
#endif
#else /* !WIN32 */
#define MULTIHASH_EXPORT
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define USE_CRC32
#define USE_MD4
#define USE_MD5
#define USE_ED2K
#define USE_SHA1
#ifdef USE_CRC32
#include <sys/types.h>
#include "crc32.h"
#define LEN_CRC32 8
#endif
#ifdef USE_MD4
#include "md4.h"
#define LEN_MD4 32
#define MD4_DIGESTSIZE 16
#endif
#ifdef USE_MD5
#include "md5.h"
#define LEN_MD5 32
#endif
#ifdef USE_ED2K
#include "edonkey.h"
#define LEN_ED2K 32
#endif
#ifdef USE_SHA1
#include "sha1.h"
#define LEN_SHA1 40
#endif
/* This must be as long as the longest hash (in bytes) */
#define MAX_DIGESTSIZE 20
typedef struct {
#ifdef USE_CRC32
u_int32_t crc32;
char crc32_s[LEN_CRC32 + 1];
#endif
#ifdef USE_MD4
md4_context md4;
char md4_s[LEN_MD4 + 1];
#endif
#ifdef USE_MD5
MD5_CTX md5;
char md5_s[LEN_MD5 + 1];
#endif
#ifdef USE_ED2K
ed2khash_context ed2k;
char ed2k_s[LEN_ED2K + 1];
#endif
#ifdef USE_SHA1
SHA1_CTX sha1;
char sha1_s[LEN_SHA1 + 1];
#endif
} multihash;
/* Prototypes */
MULTIHASH_EXPORT void multihash_init (multihash *mh);
MULTIHASH_EXPORT void multihash_update (multihash *mh, unsigned char *data, int bytes);
MULTIHASH_EXPORT void multihash_finish (multihash *mh);
MULTIHASH_EXPORT int multihash_file (multihash *mh, char *filename);
#ifdef __cplusplus
}
#endif
#endif
/***************************************************************************
* Copyright (C) 2007 by SukkoPera *
* sukkopera@sukkology.net *
* *
* 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. *
***************************************************************************/
#ifndef MULTIHASH_H_INCLUDED
#define MULTIHASH_H_INCLUDED
#ifdef WIN32
#include <windows.h>
/* Definition of the types we use for Windows */
#define u_int8_t BYTE
#define u_int16_t WORD
#define u_int32_t DWORD
/* Some functions have different names */
#define snprintf _snprintf
/* Stuff to export library symbols */
#ifdef MULTIHASH_BUILD_DLL
#ifdef MULTIHASH_EXPORTS
#define MULTIHASH_EXPORT __declspec(dllexport) /* Building the lib */
#else
#define MULTIHASH_EXPORT __declspec(dllimport) /* Building user code */
#endif
#else
#define MULTIHASH_EXPORT
#endif
#else /* !WIN32 */
#define MULTIHASH_EXPORT
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define USE_CRC32
#define USE_MD4
#define USE_MD5
#define USE_ED2K
#define USE_SHA1
#ifdef USE_CRC32
#include <sys/types.h>
#include "crc32.h"
#define LEN_CRC32 8
#endif
#ifdef USE_MD4
#include "md4.h"
#define LEN_MD4 32
#define MD4_DIGESTSIZE 16
#endif
#ifdef USE_MD5
#include "md5.h"
#define LEN_MD5 32
#endif
#ifdef USE_ED2K
#include "edonkey.h"
#define LEN_ED2K 32
#endif
#ifdef USE_SHA1
#include "sha1.h"
#define LEN_SHA1 40
#endif
/* This must be as long as the longest hash (in bytes) */
#define MAX_DIGESTSIZE 20
typedef struct {
#ifdef USE_CRC32
u_int32_t crc32;
char crc32_s[LEN_CRC32 + 1];
#endif
#ifdef USE_MD4
md4_context md4;
char md4_s[LEN_MD4 + 1];
#endif
#ifdef USE_MD5
MD5_CTX md5;
char md5_s[LEN_MD5 + 1];
#endif
#ifdef USE_ED2K
ed2khash_context ed2k;
char ed2k_s[LEN_ED2K + 1];
#endif
#ifdef USE_SHA1
SHA1_CTX sha1;
char sha1_s[LEN_SHA1 + 1];
#endif
} multihash;
/* Prototypes */
MULTIHASH_EXPORT void multihash_init (multihash *mh);
MULTIHASH_EXPORT void multihash_update (multihash *mh, unsigned char *data, int bytes);
MULTIHASH_EXPORT void multihash_finish (multihash *mh);
MULTIHASH_EXPORT int multihash_file (multihash *mh, char *filename);
#ifdef __cplusplus
}
#endif
#endif