mirror of
https://github.com/NohamR/TrollDecrypt-tvOS.git
synced 2026-07-11 22:41:37 +00:00
Initial Commit
This commit is contained in:
25
Makefile
Normal file
25
Makefile
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
TARGET := iphone:clang:latest:14.0
|
||||||
|
INSTALL_TARGET_PROCESSES = TrollDecrypt
|
||||||
|
|
||||||
|
GO_EASY_ON_ME = 1
|
||||||
|
PACKAGE_FORMAT = ipa
|
||||||
|
|
||||||
|
include $(THEOS)/makefiles/common.mk
|
||||||
|
|
||||||
|
APPLICATION_NAME = TrollDecrypt
|
||||||
|
|
||||||
|
TrollDecrypt_FILES = SSZipArchive/minizip/unzip.c SSZipArchive/minizip/crypt.c SSZipArchive/minizip/ioapi_buf.c SSZipArchive/minizip/ioapi_mem.c SSZipArchive/minizip/ioapi.c SSZipArchive/minizip/minishared.c SSZipArchive/minizip/zip.c SSZipArchive/minizip/aes/aes_ni.c SSZipArchive/minizip/aes/aescrypt.c SSZipArchive/minizip/aes/aeskey.c SSZipArchive/minizip/aes/aestab.c SSZipArchive/minizip/aes/fileenc.c SSZipArchive/minizip/aes/hmac.c SSZipArchive/minizip/aes/prng.c SSZipArchive/minizip/aes/pwd2key.c SSZipArchive/minizip/aes/sha1.c SSZipArchive/SSZipArchive.m
|
||||||
|
TrollDecrypt_FILES += main.m TDAppDelegate.m TDRootViewController.m TDDumpDecrypted.m TDUtils.m TDFileManagerViewController.m
|
||||||
|
TrollDecrypt_FRAMEWORKS = UIKit CoreGraphics MobileCoreServices
|
||||||
|
TrollDecrypt_CFLAGS = -fobjc-arc
|
||||||
|
TrollDecrypt_CODESIGN_FLAGS = -Sentitlements.plist
|
||||||
|
|
||||||
|
include $(THEOS_MAKE_PATH)/application.mk
|
||||||
|
|
||||||
|
after-stage::
|
||||||
|
rm -rf Payload
|
||||||
|
mkdir -p $(THEOS_STAGING_DIR)/Payload
|
||||||
|
ldid -Sentitlements.plist $(THEOS_STAGING_DIR)/Applications/TrollDecrypt.app/TrollDecrypt
|
||||||
|
cp -a $(THEOS_STAGING_DIR)/Applications/* $(THEOS_STAGING_DIR)/Payload
|
||||||
|
mv $(THEOS_STAGING_DIR)/Payload .
|
||||||
|
zip -q -r TrollDecrypt.ipa Payload
|
||||||
BIN
Payload/TrollDecrypt.app/AppIcon60x60.png
Normal file
BIN
Payload/TrollDecrypt.app/AppIcon60x60.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.4 KiB |
BIN
Payload/TrollDecrypt.app/AppIcon76x76~ipad.png
Normal file
BIN
Payload/TrollDecrypt.app/AppIcon76x76~ipad.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.9 KiB |
68
Payload/TrollDecrypt.app/Info.plist
Normal file
68
Payload/TrollDecrypt.app/Info.plist
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>TrollDecrypt</string>
|
||||||
|
<key>CFBundleIcons</key>
|
||||||
|
<dict>
|
||||||
|
<key>CFBundlePrimaryIcon</key>
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleIconFiles</key>
|
||||||
|
<array>
|
||||||
|
<string>AppIcon60x60</string>
|
||||||
|
</array>
|
||||||
|
<key>UIPrerenderedIcon</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<key>CFBundleIcons~ipad</key>
|
||||||
|
<dict>
|
||||||
|
<key>CFBundlePrimaryIcon</key>
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleIconFiles</key>
|
||||||
|
<array>
|
||||||
|
<string>AppIcon60x60</string>
|
||||||
|
<string>AppIcon76x76~ipad</string>
|
||||||
|
</array>
|
||||||
|
<key>UIPrerenderedIcon</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>com.fiore.trolldecrypt</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleSignature</key>
|
||||||
|
<string>????</string>
|
||||||
|
<key>CFBundleSupportedPlatforms</key>
|
||||||
|
<array>
|
||||||
|
<string>iPhoneOS</string>
|
||||||
|
</array>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>1.0</string>
|
||||||
|
<key>LSRequiresIPhoneOS</key>
|
||||||
|
<true/>
|
||||||
|
<key>UIDeviceFamily</key>
|
||||||
|
<array>
|
||||||
|
<integer>1</integer>
|
||||||
|
<integer>2</integer>
|
||||||
|
</array>
|
||||||
|
<key>UIRequiredDeviceCapabilities</key>
|
||||||
|
<array>
|
||||||
|
<string>armv7</string>
|
||||||
|
</array>
|
||||||
|
<key>UILaunchStoryboardName</key>
|
||||||
|
<string>LaunchScreen</string>
|
||||||
|
<key>UISupportedInterfaceOrientations</key>
|
||||||
|
<array>
|
||||||
|
<string>UIInterfaceOrientationPortrait</string>
|
||||||
|
</array>
|
||||||
|
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||||
|
<array>
|
||||||
|
<string>UIInterfaceOrientationPortrait</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
BIN
Payload/TrollDecrypt.app/TrollDecrypt
Normal file
BIN
Payload/TrollDecrypt.app/TrollDecrypt
Normal file
Binary file not shown.
BIN
Resources/AppIcon60x60.png
Normal file
BIN
Resources/AppIcon60x60.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.4 KiB |
BIN
Resources/AppIcon76x76~ipad.png
Normal file
BIN
Resources/AppIcon76x76~ipad.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.9 KiB |
68
Resources/Info.plist
Normal file
68
Resources/Info.plist
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>TrollDecrypt</string>
|
||||||
|
<key>CFBundleIcons</key>
|
||||||
|
<dict>
|
||||||
|
<key>CFBundlePrimaryIcon</key>
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleIconFiles</key>
|
||||||
|
<array>
|
||||||
|
<string>AppIcon60x60</string>
|
||||||
|
</array>
|
||||||
|
<key>UIPrerenderedIcon</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<key>CFBundleIcons~ipad</key>
|
||||||
|
<dict>
|
||||||
|
<key>CFBundlePrimaryIcon</key>
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleIconFiles</key>
|
||||||
|
<array>
|
||||||
|
<string>AppIcon60x60</string>
|
||||||
|
<string>AppIcon76x76~ipad</string>
|
||||||
|
</array>
|
||||||
|
<key>UIPrerenderedIcon</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>com.fiore.trolldecrypt</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleSignature</key>
|
||||||
|
<string>????</string>
|
||||||
|
<key>CFBundleSupportedPlatforms</key>
|
||||||
|
<array>
|
||||||
|
<string>iPhoneOS</string>
|
||||||
|
</array>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>1.0</string>
|
||||||
|
<key>LSRequiresIPhoneOS</key>
|
||||||
|
<true/>
|
||||||
|
<key>UIDeviceFamily</key>
|
||||||
|
<array>
|
||||||
|
<integer>1</integer>
|
||||||
|
<integer>2</integer>
|
||||||
|
</array>
|
||||||
|
<key>UIRequiredDeviceCapabilities</key>
|
||||||
|
<array>
|
||||||
|
<string>armv7</string>
|
||||||
|
</array>
|
||||||
|
<key>UILaunchStoryboardName</key>
|
||||||
|
<string>LaunchScreen</string>
|
||||||
|
<key>UISupportedInterfaceOrientations</key>
|
||||||
|
<array>
|
||||||
|
<string>UIInterfaceOrientationPortrait</string>
|
||||||
|
</array>
|
||||||
|
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||||
|
<array>
|
||||||
|
<string>UIInterfaceOrientationPortrait</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
146
SSZipArchive/SSZipArchive.h
Normal file
146
SSZipArchive/SSZipArchive.h
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
//
|
||||||
|
// SSZipArchive.h
|
||||||
|
// SSZipArchive
|
||||||
|
//
|
||||||
|
// Created by Sam Soffes on 7/21/10.
|
||||||
|
// Copyright (c) Sam Soffes 2010-2015. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef _SSZIPARCHIVE_H
|
||||||
|
#define _SSZIPARCHIVE_H
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#include "SSZipCommon.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
extern NSString *const SSZipArchiveErrorDomain;
|
||||||
|
typedef NS_ENUM(NSInteger, SSZipArchiveErrorCode) {
|
||||||
|
SSZipArchiveErrorCodeFailedOpenZipFile = -1,
|
||||||
|
SSZipArchiveErrorCodeFailedOpenFileInZip = -2,
|
||||||
|
SSZipArchiveErrorCodeFileInfoNotLoadable = -3,
|
||||||
|
SSZipArchiveErrorCodeFileContentNotReadable = -4,
|
||||||
|
SSZipArchiveErrorCodeFailedToWriteFile = -5,
|
||||||
|
SSZipArchiveErrorCodeInvalidArguments = -6,
|
||||||
|
};
|
||||||
|
|
||||||
|
@protocol SSZipArchiveDelegate;
|
||||||
|
|
||||||
|
@interface SSZipArchive : NSObject
|
||||||
|
|
||||||
|
// Password check
|
||||||
|
+ (BOOL)isFilePasswordProtectedAtPath:(NSString *)path;
|
||||||
|
+ (BOOL)isPasswordValidForArchiveAtPath:(NSString *)path password:(NSString *)pw error:(NSError * _Nullable * _Nullable)error NS_SWIFT_NOTHROW;
|
||||||
|
|
||||||
|
// Unzip
|
||||||
|
+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination;
|
||||||
|
+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination delegate:(nullable id<SSZipArchiveDelegate>)delegate;
|
||||||
|
|
||||||
|
+ (BOOL)unzipFileAtPath:(NSString *)path
|
||||||
|
toDestination:(NSString *)destination
|
||||||
|
overwrite:(BOOL)overwrite
|
||||||
|
password:(nullable NSString *)password
|
||||||
|
error:(NSError * *)error;
|
||||||
|
|
||||||
|
+ (BOOL)unzipFileAtPath:(NSString *)path
|
||||||
|
toDestination:(NSString *)destination
|
||||||
|
overwrite:(BOOL)overwrite
|
||||||
|
password:(nullable NSString *)password
|
||||||
|
error:(NSError * *)error
|
||||||
|
delegate:(nullable id<SSZipArchiveDelegate>)delegate NS_REFINED_FOR_SWIFT;
|
||||||
|
|
||||||
|
+ (BOOL)unzipFileAtPath:(NSString *)path
|
||||||
|
toDestination:(NSString *)destination
|
||||||
|
preserveAttributes:(BOOL)preserveAttributes
|
||||||
|
overwrite:(BOOL)overwrite
|
||||||
|
password:(nullable NSString *)password
|
||||||
|
error:(NSError * *)error
|
||||||
|
delegate:(nullable id<SSZipArchiveDelegate>)delegate;
|
||||||
|
|
||||||
|
+ (BOOL)unzipFileAtPath:(NSString *)path
|
||||||
|
toDestination:(NSString *)destination
|
||||||
|
progressHandler:(void (^_Nullable)(NSString *entry, unz_file_info zipInfo, long entryNumber, long total))progressHandler
|
||||||
|
completionHandler:(void (^_Nullable)(NSString *path, BOOL succeeded, NSError * _Nullable error))completionHandler;
|
||||||
|
|
||||||
|
+ (BOOL)unzipFileAtPath:(NSString *)path
|
||||||
|
toDestination:(NSString *)destination
|
||||||
|
overwrite:(BOOL)overwrite
|
||||||
|
password:(nullable NSString *)password
|
||||||
|
progressHandler:(void (^_Nullable)(NSString *entry, unz_file_info zipInfo, long entryNumber, long total))progressHandler
|
||||||
|
completionHandler:(void (^_Nullable)(NSString *path, BOOL succeeded, NSError * _Nullable error))completionHandler;
|
||||||
|
|
||||||
|
+ (BOOL)unzipFileAtPath:(NSString *)path
|
||||||
|
toDestination:(NSString *)destination
|
||||||
|
preserveAttributes:(BOOL)preserveAttributes
|
||||||
|
overwrite:(BOOL)overwrite
|
||||||
|
nestedZipLevel:(NSInteger)nestedZipLevel
|
||||||
|
password:(nullable NSString *)password
|
||||||
|
error:(NSError **)error
|
||||||
|
delegate:(nullable id<SSZipArchiveDelegate>)delegate
|
||||||
|
progressHandler:(void (^_Nullable)(NSString *entry, unz_file_info zipInfo, long entryNumber, long total))progressHandler
|
||||||
|
completionHandler:(void (^_Nullable)(NSString *path, BOOL succeeded, NSError * _Nullable error))completionHandler;
|
||||||
|
|
||||||
|
// Zip
|
||||||
|
// default compression level is Z_DEFAULT_COMPRESSION (from "zlib.h")
|
||||||
|
|
||||||
|
// without password
|
||||||
|
+ (BOOL)createZipFileAtPath:(NSString *)path withFilesAtPaths:(NSArray<NSString *> *)paths;
|
||||||
|
+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath;
|
||||||
|
|
||||||
|
+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath keepParentDirectory:(BOOL)keepParentDirectory;
|
||||||
|
|
||||||
|
// with optional password, default encryption is AES
|
||||||
|
// don't use AES if you need compatibility with native macOS unzip and Archive Utility
|
||||||
|
+ (BOOL)createZipFileAtPath:(NSString *)path withFilesAtPaths:(NSArray<NSString *> *)paths withPassword:(nullable NSString *)password;
|
||||||
|
+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath withPassword:(nullable NSString *)password;
|
||||||
|
+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath keepParentDirectory:(BOOL)keepParentDirectory withPassword:(nullable NSString *)password;
|
||||||
|
+ (BOOL)createZipFileAtPath:(NSString *)path
|
||||||
|
withContentsOfDirectory:(NSString *)directoryPath
|
||||||
|
keepParentDirectory:(BOOL)keepParentDirectory
|
||||||
|
withPassword:(nullable NSString *)password
|
||||||
|
andProgressHandler:(void(^ _Nullable)(NSUInteger entryNumber, NSUInteger total))progressHandler;
|
||||||
|
+ (BOOL)createZipFileAtPath:(NSString *)path
|
||||||
|
withContentsOfDirectory:(NSString *)directoryPath
|
||||||
|
keepParentDirectory:(BOOL)keepParentDirectory
|
||||||
|
compressionLevel:(int)compressionLevel
|
||||||
|
password:(nullable NSString *)password
|
||||||
|
AES:(BOOL)aes
|
||||||
|
progressHandler:(void(^ _Nullable)(NSUInteger entryNumber, NSUInteger total))progressHandler;
|
||||||
|
|
||||||
|
- (instancetype)init NS_UNAVAILABLE;
|
||||||
|
- (instancetype)initWithPath:(NSString *)path NS_DESIGNATED_INITIALIZER;
|
||||||
|
- (BOOL)open;
|
||||||
|
|
||||||
|
/// write empty folder
|
||||||
|
- (BOOL)writeFolderAtPath:(NSString *)path withFolderName:(NSString *)folderName withPassword:(nullable NSString *)password;
|
||||||
|
/// write file
|
||||||
|
- (BOOL)writeFile:(NSString *)path withPassword:(nullable NSString *)password;
|
||||||
|
- (BOOL)writeFileAtPath:(NSString *)path withFileName:(nullable NSString *)fileName withPassword:(nullable NSString *)password;
|
||||||
|
- (BOOL)writeFileAtPath:(NSString *)path withFileName:(nullable NSString *)fileName compressionLevel:(int)compressionLevel password:(nullable NSString *)password AES:(BOOL)aes;
|
||||||
|
/// write data
|
||||||
|
- (BOOL)writeData:(NSData *)data filename:(nullable NSString *)filename withPassword:(nullable NSString *)password;
|
||||||
|
- (BOOL)writeData:(NSData *)data filename:(nullable NSString *)filename compressionLevel:(int)compressionLevel password:(nullable NSString *)password AES:(BOOL)aes;
|
||||||
|
|
||||||
|
- (BOOL)close;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@protocol SSZipArchiveDelegate <NSObject>
|
||||||
|
|
||||||
|
@optional
|
||||||
|
|
||||||
|
- (void)zipArchiveWillUnzipArchiveAtPath:(NSString *)path zipInfo:(unz_global_info)zipInfo;
|
||||||
|
- (void)zipArchiveDidUnzipArchiveAtPath:(NSString *)path zipInfo:(unz_global_info)zipInfo unzippedPath:(NSString *)unzippedPath;
|
||||||
|
|
||||||
|
- (BOOL)zipArchiveShouldUnzipFileAtIndex:(NSInteger)fileIndex totalFiles:(NSInteger)totalFiles archivePath:(NSString *)archivePath fileInfo:(unz_file_info)fileInfo;
|
||||||
|
- (void)zipArchiveWillUnzipFileAtIndex:(NSInteger)fileIndex totalFiles:(NSInteger)totalFiles archivePath:(NSString *)archivePath fileInfo:(unz_file_info)fileInfo;
|
||||||
|
- (void)zipArchiveDidUnzipFileAtIndex:(NSInteger)fileIndex totalFiles:(NSInteger)totalFiles archivePath:(NSString *)archivePath fileInfo:(unz_file_info)fileInfo;
|
||||||
|
- (void)zipArchiveDidUnzipFileAtIndex:(NSInteger)fileIndex totalFiles:(NSInteger)totalFiles archivePath:(NSString *)archivePath unzippedFilePath:(NSString *)unzippedFilePath;
|
||||||
|
|
||||||
|
- (void)zipArchiveProgressEvent:(unsigned long long)loaded total:(unsigned long long)total;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
|
|
||||||
|
#endif /* _SSZIPARCHIVE_H */
|
||||||
1069
SSZipArchive/SSZipArchive.m
Normal file
1069
SSZipArchive/SSZipArchive.m
Normal file
File diff suppressed because it is too large
Load Diff
66
SSZipArchive/SSZipCommon.h
Normal file
66
SSZipArchive/SSZipCommon.h
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
#ifndef SSZipCommon
|
||||||
|
#define SSZipCommon
|
||||||
|
|
||||||
|
/* unz_global_info structure contain global data about the ZIPfile
|
||||||
|
These data comes from the end of central dir */
|
||||||
|
typedef struct unz_global_info64_s
|
||||||
|
{
|
||||||
|
uint64_t number_entry; /* total number of entries in the central dir on this disk */
|
||||||
|
uint32_t number_disk_with_CD; /* number the the disk with central dir, used for spanning ZIP*/
|
||||||
|
uint16_t size_comment; /* size of the global comment of the zipfile */
|
||||||
|
} unz_global_info64;
|
||||||
|
|
||||||
|
typedef struct unz_global_info_s
|
||||||
|
{
|
||||||
|
uint32_t number_entry; /* total number of entries in the central dir on this disk */
|
||||||
|
uint32_t number_disk_with_CD; /* number the the disk with central dir, used for spanning ZIP*/
|
||||||
|
uint16_t size_comment; /* size of the global comment of the zipfile */
|
||||||
|
} unz_global_info;
|
||||||
|
|
||||||
|
/* unz_file_info contain information about a file in the zipfile */
|
||||||
|
/* https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT */
|
||||||
|
typedef struct unz_file_info64_s
|
||||||
|
{
|
||||||
|
uint16_t version; /* version made by 2 bytes */
|
||||||
|
uint16_t version_needed; /* version needed to extract 2 bytes */
|
||||||
|
uint16_t flag; /* general purpose bit flag 2 bytes */
|
||||||
|
uint16_t compression_method; /* compression method 2 bytes */
|
||||||
|
uint32_t dos_date; /* last mod file date in Dos fmt 4 bytes */
|
||||||
|
uint32_t crc; /* crc-32 4 bytes */
|
||||||
|
uint64_t compressed_size; /* compressed size 8 bytes */
|
||||||
|
uint64_t uncompressed_size; /* uncompressed size 8 bytes */
|
||||||
|
uint16_t size_filename; /* filename length 2 bytes */
|
||||||
|
uint16_t size_file_extra; /* extra field length 2 bytes */
|
||||||
|
uint16_t size_file_comment; /* file comment length 2 bytes */
|
||||||
|
|
||||||
|
uint32_t disk_num_start; /* disk number start 4 bytes */
|
||||||
|
uint16_t internal_fa; /* internal file attributes 2 bytes */
|
||||||
|
uint32_t external_fa; /* external file attributes 4 bytes */
|
||||||
|
|
||||||
|
uint64_t disk_offset;
|
||||||
|
|
||||||
|
uint16_t size_file_extra_internal;
|
||||||
|
} unz_file_info64;
|
||||||
|
|
||||||
|
typedef struct unz_file_info_s
|
||||||
|
{
|
||||||
|
uint16_t version; /* version made by 2 bytes */
|
||||||
|
uint16_t version_needed; /* version needed to extract 2 bytes */
|
||||||
|
uint16_t flag; /* general purpose bit flag 2 bytes */
|
||||||
|
uint16_t compression_method; /* compression method 2 bytes */
|
||||||
|
uint32_t dos_date; /* last mod file date in Dos fmt 4 bytes */
|
||||||
|
uint32_t crc; /* crc-32 4 bytes */
|
||||||
|
uint32_t compressed_size; /* compressed size 4 bytes */
|
||||||
|
uint32_t uncompressed_size; /* uncompressed size 4 bytes */
|
||||||
|
uint16_t size_filename; /* filename length 2 bytes */
|
||||||
|
uint16_t size_file_extra; /* extra field length 2 bytes */
|
||||||
|
uint16_t size_file_comment; /* file comment length 2 bytes */
|
||||||
|
|
||||||
|
uint16_t disk_num_start; /* disk number start 2 bytes */
|
||||||
|
uint16_t internal_fa; /* internal file attributes 2 bytes */
|
||||||
|
uint32_t external_fa; /* external file attributes 4 bytes */
|
||||||
|
|
||||||
|
uint64_t disk_offset;
|
||||||
|
} unz_file_info;
|
||||||
|
|
||||||
|
#endif
|
||||||
19
SSZipArchive/ZipArchive.h
Normal file
19
SSZipArchive/ZipArchive.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// ZipArchive.h
|
||||||
|
// ZipArchive
|
||||||
|
//
|
||||||
|
// Created by Serhii Mumriak on 12/1/15.
|
||||||
|
// Copyright © 2015 smumryak. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
//! Project version number for ZipArchive.
|
||||||
|
FOUNDATION_EXPORT double ZipArchiveVersionNumber;
|
||||||
|
|
||||||
|
//! Project version string for ZipArchive.
|
||||||
|
FOUNDATION_EXPORT const unsigned char ZipArchiveVersionString[];
|
||||||
|
|
||||||
|
// In this header, you should import all the public headers of your framework using statements like #import <ZipArchive/SSZipArchive.h>
|
||||||
|
|
||||||
|
#import "SSZipArchive.h"
|
||||||
270
SSZipArchive/minizip/aes/aes.h
Normal file
270
SSZipArchive/minizip/aes/aes.h
Normal file
@@ -0,0 +1,270 @@
|
|||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||||
|
|
||||||
|
The redistribution and use of this software (with or without changes)
|
||||||
|
is allowed without the payment of fees or royalties provided that:
|
||||||
|
|
||||||
|
source code distributions include the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer;
|
||||||
|
|
||||||
|
binary distributions include the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer in their documentation.
|
||||||
|
|
||||||
|
This software is provided 'as is' with no explicit or implied warranties
|
||||||
|
in respect of its operation, including, but not limited to, correctness
|
||||||
|
and fitness for purpose.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Issue Date: 20/12/2007
|
||||||
|
|
||||||
|
This file contains the definitions required to use AES in C. See aesopt.h
|
||||||
|
for optimisation details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _AES_H
|
||||||
|
#define _AES_H
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* This include is used to find 8 & 32 bit unsigned integer types */
|
||||||
|
#include "brg_types.h"
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define AES_128 /* if a fast 128 bit key scheduler is needed */
|
||||||
|
#define AES_192 /* if a fast 192 bit key scheduler is needed */
|
||||||
|
#define AES_256 /* if a fast 256 bit key scheduler is needed */
|
||||||
|
#define AES_VAR /* if variable key size scheduler is needed */
|
||||||
|
#define AES_MODES /* if support is needed for modes */
|
||||||
|
|
||||||
|
/* The following must also be set in assembler files if being used */
|
||||||
|
|
||||||
|
#define AES_ENCRYPT /* if support for encryption is needed */
|
||||||
|
#define AES_DECRYPT /* if support for decryption is needed */
|
||||||
|
|
||||||
|
#define AES_BLOCK_SIZE 16 /* the AES block size in bytes */
|
||||||
|
#define N_COLS 4 /* the number of columns in the state */
|
||||||
|
|
||||||
|
/* The key schedule length is 11, 13 or 15 16-byte blocks for 128, */
|
||||||
|
/* 192 or 256-bit keys respectively. That is 176, 208 or 240 bytes */
|
||||||
|
/* or 44, 52 or 60 32-bit words. */
|
||||||
|
|
||||||
|
#if defined( AES_VAR ) || defined( AES_256 )
|
||||||
|
#define KS_LENGTH 60
|
||||||
|
#elif defined( AES_192 )
|
||||||
|
#define KS_LENGTH 52
|
||||||
|
#else
|
||||||
|
#define KS_LENGTH 44
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define AES_RETURN INT_RETURN
|
||||||
|
|
||||||
|
/* the character array 'inf' in the following structures is used */
|
||||||
|
/* to hold AES context information. This AES code uses cx->inf.b[0] */
|
||||||
|
/* to hold the number of rounds multiplied by 16. The other three */
|
||||||
|
/* elements can be used by code that implements additional modes */
|
||||||
|
|
||||||
|
typedef union
|
||||||
|
{ uint32_t l;
|
||||||
|
uint8_t b[4];
|
||||||
|
} aes_inf;
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# pragma warning( disable : 4324 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && defined(_WIN64)
|
||||||
|
#define ALIGNED_(x) __declspec(align(x))
|
||||||
|
#elif defined(__GNUC__) && defined(__x86_64__)
|
||||||
|
#define ALIGNED_(x) __attribute__ ((aligned(x)))
|
||||||
|
#else
|
||||||
|
#define ALIGNED_(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct ALIGNED_(16)
|
||||||
|
{ uint32_t ks[KS_LENGTH];
|
||||||
|
aes_inf inf;
|
||||||
|
} aes_encrypt_ctx;
|
||||||
|
|
||||||
|
typedef struct ALIGNED_(16)
|
||||||
|
{ uint32_t ks[KS_LENGTH];
|
||||||
|
aes_inf inf;
|
||||||
|
} aes_decrypt_ctx;
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# pragma warning( default : 4324 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* This routine must be called before first use if non-static */
|
||||||
|
/* tables are being used */
|
||||||
|
|
||||||
|
AES_RETURN aes_init(void);
|
||||||
|
|
||||||
|
/* Key lengths in the range 16 <= key_len <= 32 are given in bytes, */
|
||||||
|
/* those in the range 128 <= key_len <= 256 are given in bits */
|
||||||
|
|
||||||
|
#if defined( AES_ENCRYPT )
|
||||||
|
|
||||||
|
#if defined( AES_128 ) || defined( AES_VAR)
|
||||||
|
AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( AES_192 ) || defined( AES_VAR)
|
||||||
|
AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( AES_256 ) || defined( AES_VAR)
|
||||||
|
AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( AES_VAR )
|
||||||
|
AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1]);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( AES_DECRYPT )
|
||||||
|
|
||||||
|
#if defined( AES_128 ) || defined( AES_VAR)
|
||||||
|
AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( AES_192 ) || defined( AES_VAR)
|
||||||
|
AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( AES_256 ) || defined( AES_VAR)
|
||||||
|
AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( AES_VAR )
|
||||||
|
AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1]);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( AES_MODES )
|
||||||
|
|
||||||
|
/* Multiple calls to the following subroutines for multiple block */
|
||||||
|
/* ECB, CBC, CFB, OFB and CTR mode encryption can be used to handle */
|
||||||
|
/* long messages incrementally provided that the context AND the iv */
|
||||||
|
/* are preserved between all such calls. For the ECB and CBC modes */
|
||||||
|
/* each individual call within a series of incremental calls must */
|
||||||
|
/* process only full blocks (i.e. len must be a multiple of 16) but */
|
||||||
|
/* the CFB, OFB and CTR mode calls can handle multiple incremental */
|
||||||
|
/* calls of any length. Each mode is reset when a new AES key is */
|
||||||
|
/* set but ECB needs no reset and CBC can be reset without setting */
|
||||||
|
/* a new key by setting a new IV value. To reset CFB, OFB and CTR */
|
||||||
|
/* without setting the key, aes_mode_reset() must be called and the */
|
||||||
|
/* IV must be set. NOTE: All these calls update the IV on exit so */
|
||||||
|
/* this has to be reset if a new operation with the same IV as the */
|
||||||
|
/* previous one is required (or decryption follows encryption with */
|
||||||
|
/* the same IV array). */
|
||||||
|
|
||||||
|
AES_RETURN aes_test_alignment_detection(unsigned int n);
|
||||||
|
|
||||||
|
AES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||||
|
int len, const aes_encrypt_ctx cx[1]);
|
||||||
|
|
||||||
|
AES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||||
|
int len, const aes_decrypt_ctx cx[1]);
|
||||||
|
|
||||||
|
AES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||||
|
int len, unsigned char *iv, const aes_encrypt_ctx cx[1]);
|
||||||
|
|
||||||
|
AES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||||
|
int len, unsigned char *iv, const aes_decrypt_ctx cx[1]);
|
||||||
|
|
||||||
|
AES_RETURN aes_mode_reset(aes_encrypt_ctx cx[1]);
|
||||||
|
|
||||||
|
AES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||||
|
int len, unsigned char *iv, aes_encrypt_ctx cx[1]);
|
||||||
|
|
||||||
|
AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||||
|
int len, unsigned char *iv, aes_encrypt_ctx cx[1]);
|
||||||
|
|
||||||
|
#define aes_ofb_encrypt aes_ofb_crypt
|
||||||
|
#define aes_ofb_decrypt aes_ofb_crypt
|
||||||
|
|
||||||
|
AES_RETURN aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||||
|
int len, unsigned char *iv, aes_encrypt_ctx cx[1]);
|
||||||
|
|
||||||
|
typedef void cbuf_inc(unsigned char *cbuf);
|
||||||
|
|
||||||
|
#define aes_ctr_encrypt aes_ctr_crypt
|
||||||
|
#define aes_ctr_decrypt aes_ctr_crypt
|
||||||
|
|
||||||
|
AES_RETURN aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||||
|
int len, unsigned char *cbuf, cbuf_inc ctr_inc, aes_encrypt_ctx cx[1]);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
# define ADD_AESNI_MODE_CALLS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0 && defined( ADD_AESNI_MODE_CALLS )
|
||||||
|
# define USE_AES_CONTEXT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ADD_AESNI_MODE_CALLS
|
||||||
|
# ifdef USE_AES_CONTEXT
|
||||||
|
|
||||||
|
AES_RETURN aes_CBC_encrypt(const unsigned char *in,
|
||||||
|
unsigned char *out,
|
||||||
|
unsigned char ivec[16],
|
||||||
|
unsigned long length,
|
||||||
|
const aes_encrypt_ctx cx[1]);
|
||||||
|
|
||||||
|
AES_RETURN aes_CBC_decrypt(const unsigned char *in,
|
||||||
|
unsigned char *out,
|
||||||
|
unsigned char ivec[16],
|
||||||
|
unsigned long length,
|
||||||
|
const aes_decrypt_ctx cx[1]);
|
||||||
|
|
||||||
|
AES_RETURN AES_CTR_encrypt(const unsigned char *in,
|
||||||
|
unsigned char *out,
|
||||||
|
const unsigned char ivec[8],
|
||||||
|
const unsigned char nonce[4],
|
||||||
|
unsigned long length,
|
||||||
|
const aes_encrypt_ctx cx[1]);
|
||||||
|
|
||||||
|
# else
|
||||||
|
|
||||||
|
void aes_CBC_encrypt(const unsigned char *in,
|
||||||
|
unsigned char *out,
|
||||||
|
unsigned char ivec[16],
|
||||||
|
unsigned long length,
|
||||||
|
unsigned char *key,
|
||||||
|
int number_of_rounds);
|
||||||
|
|
||||||
|
void aes_CBC_decrypt(const unsigned char *in,
|
||||||
|
unsigned char *out,
|
||||||
|
unsigned char ivec[16],
|
||||||
|
unsigned long length,
|
||||||
|
unsigned char *key,
|
||||||
|
int number_of_rounds);
|
||||||
|
|
||||||
|
void AES_CTR_encrypt(const unsigned char *in,
|
||||||
|
unsigned char *out,
|
||||||
|
const unsigned char ivec[8],
|
||||||
|
const unsigned char nonce[4],
|
||||||
|
unsigned long length,
|
||||||
|
const unsigned char *key,
|
||||||
|
int number_of_rounds);
|
||||||
|
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
687
SSZipArchive/minizip/aes/aes_ni.c
Normal file
687
SSZipArchive/minizip/aes/aes_ni.c
Normal file
@@ -0,0 +1,687 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||||
|
|
||||||
|
The redistribution and use of this software (with or without changes)
|
||||||
|
is allowed without the payment of fees or royalties provided that:
|
||||||
|
|
||||||
|
source code distributions include the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer;
|
||||||
|
|
||||||
|
binary distributions include the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer in their documentation.
|
||||||
|
|
||||||
|
This software is provided 'as is' with no explicit or implied warranties
|
||||||
|
in respect of its operation, including, but not limited to, correctness
|
||||||
|
and fitness for purpose.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Issue Date: 09/09/2014
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "aes_ni.h"
|
||||||
|
|
||||||
|
#if defined( USE_INTEL_AES_IF_PRESENT )
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
|
||||||
|
#include <intrin.h>
|
||||||
|
#pragma intrinsic(__cpuid)
|
||||||
|
#define INLINE __inline
|
||||||
|
|
||||||
|
INLINE int has_aes_ni(void)
|
||||||
|
{
|
||||||
|
static int test = -1;
|
||||||
|
if(test < 0)
|
||||||
|
{
|
||||||
|
int cpu_info[4];
|
||||||
|
__cpuid(cpu_info, 1);
|
||||||
|
test = cpu_info[2] & 0x02000000;
|
||||||
|
}
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined( __GNUC__ )
|
||||||
|
|
||||||
|
#include <cpuid.h>
|
||||||
|
|
||||||
|
#if !defined(__clang__)
|
||||||
|
#pragma GCC target ("ssse3")
|
||||||
|
#pragma GCC target ("sse4.1")
|
||||||
|
#pragma GCC target ("aes")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <x86intrin.h>
|
||||||
|
#define INLINE static __inline
|
||||||
|
|
||||||
|
INLINE int has_aes_ni()
|
||||||
|
{
|
||||||
|
static int test = -1;
|
||||||
|
if(test < 0)
|
||||||
|
{
|
||||||
|
unsigned int a, b, c, d;
|
||||||
|
if(!__get_cpuid(1, &a, &b, &c, &d))
|
||||||
|
test = 0;
|
||||||
|
else
|
||||||
|
test = (c & 0x2000000);
|
||||||
|
}
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error AES New Instructions require Microsoft, Intel, GNU C, or CLANG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
INLINE __m128i aes_128_assist(__m128i t1, __m128i t2)
|
||||||
|
{
|
||||||
|
__m128i t3;
|
||||||
|
t2 = _mm_shuffle_epi32(t2, 0xff);
|
||||||
|
t3 = _mm_slli_si128(t1, 0x4);
|
||||||
|
t1 = _mm_xor_si128(t1, t3);
|
||||||
|
t3 = _mm_slli_si128(t3, 0x4);
|
||||||
|
t1 = _mm_xor_si128(t1, t3);
|
||||||
|
t3 = _mm_slli_si128(t3, 0x4);
|
||||||
|
t1 = _mm_xor_si128(t1, t3);
|
||||||
|
t1 = _mm_xor_si128(t1, t2);
|
||||||
|
return t1;
|
||||||
|
}
|
||||||
|
|
||||||
|
AES_RETURN aes_ni(encrypt_key128)(const unsigned char *key, aes_encrypt_ctx cx[1])
|
||||||
|
{
|
||||||
|
__m128i t1, t2;
|
||||||
|
__m128i *ks = (__m128i*)cx->ks;
|
||||||
|
|
||||||
|
if(!has_aes_ni())
|
||||||
|
{
|
||||||
|
return aes_xi(encrypt_key128)(key, cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
t1 = _mm_loadu_si128((__m128i*)key);
|
||||||
|
|
||||||
|
ks[0] = t1;
|
||||||
|
|
||||||
|
t2 = _mm_aeskeygenassist_si128(t1, 0x1);
|
||||||
|
t1 = aes_128_assist(t1, t2);
|
||||||
|
ks[1] = t1;
|
||||||
|
|
||||||
|
t2 = _mm_aeskeygenassist_si128(t1, 0x2);
|
||||||
|
t1 = aes_128_assist(t1, t2);
|
||||||
|
ks[2] = t1;
|
||||||
|
|
||||||
|
t2 = _mm_aeskeygenassist_si128(t1, 0x4);
|
||||||
|
t1 = aes_128_assist(t1, t2);
|
||||||
|
ks[3] = t1;
|
||||||
|
|
||||||
|
t2 = _mm_aeskeygenassist_si128(t1, 0x8);
|
||||||
|
t1 = aes_128_assist(t1, t2);
|
||||||
|
ks[4] = t1;
|
||||||
|
|
||||||
|
t2 = _mm_aeskeygenassist_si128(t1, 0x10);
|
||||||
|
t1 = aes_128_assist(t1, t2);
|
||||||
|
ks[5] = t1;
|
||||||
|
|
||||||
|
t2 = _mm_aeskeygenassist_si128(t1, 0x20);
|
||||||
|
t1 = aes_128_assist(t1, t2);
|
||||||
|
ks[6] = t1;
|
||||||
|
|
||||||
|
t2 = _mm_aeskeygenassist_si128(t1, 0x40);
|
||||||
|
t1 = aes_128_assist(t1, t2);
|
||||||
|
ks[7] = t1;
|
||||||
|
|
||||||
|
t2 = _mm_aeskeygenassist_si128(t1, 0x80);
|
||||||
|
t1 = aes_128_assist(t1, t2);
|
||||||
|
ks[8] = t1;
|
||||||
|
|
||||||
|
t2 = _mm_aeskeygenassist_si128(t1, 0x1b);
|
||||||
|
t1 = aes_128_assist(t1, t2);
|
||||||
|
ks[9] = t1;
|
||||||
|
|
||||||
|
t2 = _mm_aeskeygenassist_si128(t1, 0x36);
|
||||||
|
t1 = aes_128_assist(t1, t2);
|
||||||
|
ks[10] = t1;
|
||||||
|
|
||||||
|
cx->inf.l = 0;
|
||||||
|
cx->inf.b[0] = 10 * 16;
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE void aes_192_assist(__m128i* t1, __m128i * t2, __m128i * t3)
|
||||||
|
{
|
||||||
|
__m128i t4;
|
||||||
|
*t2 = _mm_shuffle_epi32(*t2, 0x55);
|
||||||
|
t4 = _mm_slli_si128(*t1, 0x4);
|
||||||
|
*t1 = _mm_xor_si128(*t1, t4);
|
||||||
|
t4 = _mm_slli_si128(t4, 0x4);
|
||||||
|
*t1 = _mm_xor_si128(*t1, t4);
|
||||||
|
t4 = _mm_slli_si128(t4, 0x4);
|
||||||
|
*t1 = _mm_xor_si128(*t1, t4);
|
||||||
|
*t1 = _mm_xor_si128(*t1, *t2);
|
||||||
|
*t2 = _mm_shuffle_epi32(*t1, 0xff);
|
||||||
|
t4 = _mm_slli_si128(*t3, 0x4);
|
||||||
|
*t3 = _mm_xor_si128(*t3, t4);
|
||||||
|
*t3 = _mm_xor_si128(*t3, *t2);
|
||||||
|
}
|
||||||
|
|
||||||
|
AES_RETURN aes_ni(encrypt_key192)(const unsigned char *key, aes_encrypt_ctx cx[1])
|
||||||
|
{
|
||||||
|
__m128i t1, t2, t3;
|
||||||
|
__m128i *ks = (__m128i*)cx->ks;
|
||||||
|
|
||||||
|
if(!has_aes_ni())
|
||||||
|
{
|
||||||
|
return aes_xi(encrypt_key192)(key, cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
t1 = _mm_loadu_si128((__m128i*)key);
|
||||||
|
t3 = _mm_loadu_si128((__m128i*)(key + 16));
|
||||||
|
|
||||||
|
ks[0] = t1;
|
||||||
|
ks[1] = t3;
|
||||||
|
|
||||||
|
t2 = _mm_aeskeygenassist_si128(t3, 0x1);
|
||||||
|
aes_192_assist(&t1, &t2, &t3);
|
||||||
|
|
||||||
|
ks[1] = _mm_castpd_si128(_mm_shuffle_pd(_mm_castsi128_pd(ks[1]), _mm_castsi128_pd(t1), 0));
|
||||||
|
ks[2] = _mm_castpd_si128(_mm_shuffle_pd(_mm_castsi128_pd(t1), _mm_castsi128_pd(t3), 1));
|
||||||
|
|
||||||
|
t2 = _mm_aeskeygenassist_si128(t3, 0x2);
|
||||||
|
aes_192_assist(&t1, &t2, &t3);
|
||||||
|
ks[3] = t1;
|
||||||
|
ks[4] = t3;
|
||||||
|
|
||||||
|
t2 = _mm_aeskeygenassist_si128(t3, 0x4);
|
||||||
|
aes_192_assist(&t1, &t2, &t3);
|
||||||
|
ks[4] = _mm_castpd_si128(_mm_shuffle_pd(_mm_castsi128_pd(ks[4]), _mm_castsi128_pd(t1), 0));
|
||||||
|
ks[5] = _mm_castpd_si128(_mm_shuffle_pd(_mm_castsi128_pd(t1), _mm_castsi128_pd(t3), 1));
|
||||||
|
|
||||||
|
t2 = _mm_aeskeygenassist_si128(t3, 0x8);
|
||||||
|
aes_192_assist(&t1, &t2, &t3);
|
||||||
|
ks[6] = t1;
|
||||||
|
ks[7] = t3;
|
||||||
|
|
||||||
|
t2 = _mm_aeskeygenassist_si128(t3, 0x10);
|
||||||
|
aes_192_assist(&t1, &t2, &t3);
|
||||||
|
ks[7] = _mm_castpd_si128(_mm_shuffle_pd(_mm_castsi128_pd(ks[7]), _mm_castsi128_pd(t1), 0));
|
||||||
|
ks[8] = _mm_castpd_si128(_mm_shuffle_pd(_mm_castsi128_pd(t1), _mm_castsi128_pd(t3), 1));
|
||||||
|
|
||||||
|
t2 = _mm_aeskeygenassist_si128(t3, 0x20);
|
||||||
|
aes_192_assist(&t1, &t2, &t3);
|
||||||
|
ks[9] = t1;
|
||||||
|
ks[10] = t3;
|
||||||
|
|
||||||
|
t2 = _mm_aeskeygenassist_si128(t3, 0x40);
|
||||||
|
aes_192_assist(&t1, &t2, &t3);
|
||||||
|
ks[10] = _mm_castpd_si128(_mm_shuffle_pd(_mm_castsi128_pd(ks[10]), _mm_castsi128_pd(t1), 0));
|
||||||
|
ks[11] = _mm_castpd_si128(_mm_shuffle_pd(_mm_castsi128_pd(t1), _mm_castsi128_pd(t3), 1));
|
||||||
|
|
||||||
|
t2 = _mm_aeskeygenassist_si128(t3, 0x80);
|
||||||
|
aes_192_assist(&t1, &t2, &t3);
|
||||||
|
ks[12] = t1;
|
||||||
|
|
||||||
|
cx->inf.l = 0;
|
||||||
|
cx->inf.b[0] = 12 * 16;
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE void aes_256_assist1(__m128i* t1, __m128i * t2)
|
||||||
|
{
|
||||||
|
__m128i t4;
|
||||||
|
*t2 = _mm_shuffle_epi32(*t2, 0xff);
|
||||||
|
t4 = _mm_slli_si128(*t1, 0x4);
|
||||||
|
*t1 = _mm_xor_si128(*t1, t4);
|
||||||
|
t4 = _mm_slli_si128(t4, 0x4);
|
||||||
|
*t1 = _mm_xor_si128(*t1, t4);
|
||||||
|
t4 = _mm_slli_si128(t4, 0x4);
|
||||||
|
*t1 = _mm_xor_si128(*t1, t4);
|
||||||
|
*t1 = _mm_xor_si128(*t1, *t2);
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE void aes_256_assist2(__m128i* t1, __m128i * t3)
|
||||||
|
{
|
||||||
|
__m128i t2, t4;
|
||||||
|
t4 = _mm_aeskeygenassist_si128(*t1, 0x0);
|
||||||
|
t2 = _mm_shuffle_epi32(t4, 0xaa);
|
||||||
|
t4 = _mm_slli_si128(*t3, 0x4);
|
||||||
|
*t3 = _mm_xor_si128(*t3, t4);
|
||||||
|
t4 = _mm_slli_si128(t4, 0x4);
|
||||||
|
*t3 = _mm_xor_si128(*t3, t4);
|
||||||
|
t4 = _mm_slli_si128(t4, 0x4);
|
||||||
|
*t3 = _mm_xor_si128(*t3, t4);
|
||||||
|
*t3 = _mm_xor_si128(*t3, t2);
|
||||||
|
}
|
||||||
|
|
||||||
|
AES_RETURN aes_ni(encrypt_key256)(const unsigned char *key, aes_encrypt_ctx cx[1])
|
||||||
|
{
|
||||||
|
__m128i t1, t2, t3;
|
||||||
|
__m128i *ks = (__m128i*)cx->ks;
|
||||||
|
|
||||||
|
if(!has_aes_ni())
|
||||||
|
{
|
||||||
|
return aes_xi(encrypt_key256)(key, cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
t1 = _mm_loadu_si128((__m128i*)key);
|
||||||
|
t3 = _mm_loadu_si128((__m128i*)(key + 16));
|
||||||
|
|
||||||
|
ks[0] = t1;
|
||||||
|
ks[1] = t3;
|
||||||
|
|
||||||
|
t2 = _mm_aeskeygenassist_si128(t3, 0x01);
|
||||||
|
aes_256_assist1(&t1, &t2);
|
||||||
|
ks[2] = t1;
|
||||||
|
aes_256_assist2(&t1, &t3);
|
||||||
|
ks[3] = t3;
|
||||||
|
|
||||||
|
t2 = _mm_aeskeygenassist_si128(t3, 0x02);
|
||||||
|
aes_256_assist1(&t1, &t2);
|
||||||
|
ks[4] = t1;
|
||||||
|
aes_256_assist2(&t1, &t3);
|
||||||
|
ks[5] = t3;
|
||||||
|
|
||||||
|
t2 = _mm_aeskeygenassist_si128(t3, 0x04);
|
||||||
|
aes_256_assist1(&t1, &t2);
|
||||||
|
ks[6] = t1;
|
||||||
|
aes_256_assist2(&t1, &t3);
|
||||||
|
ks[7] = t3;
|
||||||
|
|
||||||
|
t2 = _mm_aeskeygenassist_si128(t3, 0x08);
|
||||||
|
aes_256_assist1(&t1, &t2);
|
||||||
|
ks[8] = t1;
|
||||||
|
aes_256_assist2(&t1, &t3);
|
||||||
|
ks[9] = t3;
|
||||||
|
|
||||||
|
t2 = _mm_aeskeygenassist_si128(t3, 0x10);
|
||||||
|
aes_256_assist1(&t1, &t2);
|
||||||
|
ks[10] = t1;
|
||||||
|
aes_256_assist2(&t1, &t3);
|
||||||
|
ks[11] = t3;
|
||||||
|
|
||||||
|
t2 = _mm_aeskeygenassist_si128(t3, 0x20);
|
||||||
|
aes_256_assist1(&t1, &t2);
|
||||||
|
ks[12] = t1;
|
||||||
|
aes_256_assist2(&t1, &t3);
|
||||||
|
ks[13] = t3;
|
||||||
|
|
||||||
|
t2 = _mm_aeskeygenassist_si128(t3, 0x40);
|
||||||
|
aes_256_assist1(&t1, &t2);
|
||||||
|
ks[14] = t1;
|
||||||
|
|
||||||
|
cx->inf.l = 0;
|
||||||
|
cx->inf.b[0] = 14 * 16;
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE void enc_to_dec(aes_decrypt_ctx cx[1])
|
||||||
|
{
|
||||||
|
__m128i *ks = (__m128i*)cx->ks;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
for( j = 1 ; j < (cx->inf.b[0] >> 4) ; ++j )
|
||||||
|
ks[j] = _mm_aesimc_si128(ks[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
AES_RETURN aes_ni(decrypt_key128)(const unsigned char *key, aes_decrypt_ctx cx[1])
|
||||||
|
{
|
||||||
|
if(!has_aes_ni())
|
||||||
|
{
|
||||||
|
return aes_xi(decrypt_key128)(key, cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(aes_ni(encrypt_key128)(key, (aes_encrypt_ctx*)cx) == EXIT_SUCCESS)
|
||||||
|
{
|
||||||
|
enc_to_dec(cx);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
AES_RETURN aes_ni(decrypt_key192)(const unsigned char *key, aes_decrypt_ctx cx[1])
|
||||||
|
{
|
||||||
|
if(!has_aes_ni())
|
||||||
|
{
|
||||||
|
return aes_xi(decrypt_key192)(key, cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(aes_ni(encrypt_key192)(key, (aes_encrypt_ctx*)cx) == EXIT_SUCCESS)
|
||||||
|
{
|
||||||
|
enc_to_dec(cx);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
AES_RETURN aes_ni(decrypt_key256)(const unsigned char *key, aes_decrypt_ctx cx[1])
|
||||||
|
{
|
||||||
|
if(!has_aes_ni())
|
||||||
|
{
|
||||||
|
return aes_xi(decrypt_key256)(key, cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(aes_ni(encrypt_key256)(key, (aes_encrypt_ctx*)cx) == EXIT_SUCCESS)
|
||||||
|
{
|
||||||
|
enc_to_dec(cx);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
AES_RETURN aes_ni(encrypt)(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1])
|
||||||
|
{
|
||||||
|
__m128i *key = (__m128i*)cx->ks, t;
|
||||||
|
|
||||||
|
if(cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
|
if(!has_aes_ni())
|
||||||
|
{
|
||||||
|
return aes_xi(encrypt)(in, out, cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
t = _mm_xor_si128(_mm_loadu_si128((__m128i*)in), *(__m128i*)key);
|
||||||
|
|
||||||
|
switch(cx->inf.b[0])
|
||||||
|
{
|
||||||
|
case 14 * 16:
|
||||||
|
t = _mm_aesenc_si128(t, *(__m128i*)++key);
|
||||||
|
t = _mm_aesenc_si128(t, *(__m128i*)++key);
|
||||||
|
case 12 * 16:
|
||||||
|
t = _mm_aesenc_si128(t, *(__m128i*)++key);
|
||||||
|
t = _mm_aesenc_si128(t, *(__m128i*)++key);
|
||||||
|
case 10 * 16:
|
||||||
|
t = _mm_aesenc_si128(t, *(__m128i*)++key);
|
||||||
|
t = _mm_aesenc_si128(t, *(__m128i*)++key);
|
||||||
|
t = _mm_aesenc_si128(t, *(__m128i*)++key);
|
||||||
|
t = _mm_aesenc_si128(t, *(__m128i*)++key);
|
||||||
|
t = _mm_aesenc_si128(t, *(__m128i*)++key);
|
||||||
|
t = _mm_aesenc_si128(t, *(__m128i*)++key);
|
||||||
|
t = _mm_aesenc_si128(t, *(__m128i*)++key);
|
||||||
|
t = _mm_aesenc_si128(t, *(__m128i*)++key);
|
||||||
|
t = _mm_aesenc_si128(t, *(__m128i*)++key);
|
||||||
|
t = _mm_aesenclast_si128(t, *(__m128i*)++key);
|
||||||
|
}
|
||||||
|
|
||||||
|
_mm_storeu_si128(&((__m128i*)out)[0], t);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
AES_RETURN aes_ni(decrypt)(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1])
|
||||||
|
{
|
||||||
|
__m128i *key = (__m128i*)cx->ks + (cx->inf.b[0] >> 4), t;
|
||||||
|
|
||||||
|
if(cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
|
if(!has_aes_ni())
|
||||||
|
{
|
||||||
|
return aes_xi(decrypt)(in, out, cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
t = _mm_xor_si128(_mm_loadu_si128((__m128i*)in), *(__m128i*)key);
|
||||||
|
|
||||||
|
switch(cx->inf.b[0])
|
||||||
|
{
|
||||||
|
case 14 * 16:
|
||||||
|
t = _mm_aesdec_si128(t, *(__m128i*)--key);
|
||||||
|
t = _mm_aesdec_si128(t, *(__m128i*)--key);
|
||||||
|
case 12 * 16:
|
||||||
|
t = _mm_aesdec_si128(t, *(__m128i*)--key);
|
||||||
|
t = _mm_aesdec_si128(t, *(__m128i*)--key);
|
||||||
|
case 10 * 16:
|
||||||
|
t = _mm_aesdec_si128(t, *(__m128i*)--key);
|
||||||
|
t = _mm_aesdec_si128(t, *(__m128i*)--key);
|
||||||
|
t = _mm_aesdec_si128(t, *(__m128i*)--key);
|
||||||
|
t = _mm_aesdec_si128(t, *(__m128i*)--key);
|
||||||
|
t = _mm_aesdec_si128(t, *(__m128i*)--key);
|
||||||
|
t = _mm_aesdec_si128(t, *(__m128i*)--key);
|
||||||
|
t = _mm_aesdec_si128(t, *(__m128i*)--key);
|
||||||
|
t = _mm_aesdec_si128(t, *(__m128i*)--key);
|
||||||
|
t = _mm_aesdec_si128(t, *(__m128i*)--key);
|
||||||
|
t = _mm_aesdeclast_si128(t, *(__m128i*)--key);
|
||||||
|
}
|
||||||
|
|
||||||
|
_mm_storeu_si128((__m128i*)out, t);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ADD_AESNI_MODE_CALLS
|
||||||
|
#ifdef USE_AES_CONTEXT
|
||||||
|
|
||||||
|
AES_RETURN aes_CBC_encrypt(const unsigned char *in,
|
||||||
|
unsigned char *out,
|
||||||
|
unsigned char ivec[16],
|
||||||
|
unsigned long length,
|
||||||
|
const aes_encrypt_ctx cx[1])
|
||||||
|
{
|
||||||
|
__m128i feedback, data, *key = (__m128i*)cx->ks;
|
||||||
|
int number_of_rounds = cx->inf.b[0] >> 4, j;
|
||||||
|
unsigned long i;
|
||||||
|
|
||||||
|
if(number_of_rounds != 10 && number_of_rounds != 12 && number_of_rounds != 14)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
|
if(!has_aes_ni())
|
||||||
|
{
|
||||||
|
return aes_cbc_encrypt(in, out, length, ivec, cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(length % 16)
|
||||||
|
length = length / 16 + 1;
|
||||||
|
else length /= 16;
|
||||||
|
feedback = _mm_loadu_si128((__m128i*)ivec);
|
||||||
|
for(i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
data = _mm_loadu_si128(&((__m128i*)in)[i]);
|
||||||
|
feedback = _mm_xor_si128(data, feedback);
|
||||||
|
feedback = _mm_xor_si128(feedback, ((__m128i*)key)[0]);
|
||||||
|
for(j = 1; j <number_of_rounds; j++)
|
||||||
|
feedback = _mm_aesenc_si128(feedback, ((__m128i*)key)[j]);
|
||||||
|
feedback = _mm_aesenclast_si128(feedback, ((__m128i*)key)[j]);
|
||||||
|
_mm_storeu_si128(&((__m128i*)out)[i], feedback);
|
||||||
|
}
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
AES_RETURN aes_CBC_decrypt(const unsigned char *in,
|
||||||
|
unsigned char *out,
|
||||||
|
unsigned char ivec[16],
|
||||||
|
unsigned long length,
|
||||||
|
const aes_decrypt_ctx cx[1])
|
||||||
|
{
|
||||||
|
__m128i data, feedback, last_in, *key = (__m128i*)cx->ks;
|
||||||
|
int number_of_rounds = cx->inf.b[0] >> 4, j;
|
||||||
|
unsigned long i;
|
||||||
|
|
||||||
|
if(number_of_rounds != 10 && number_of_rounds != 12 && number_of_rounds != 14)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
|
if(!has_aes_ni())
|
||||||
|
{
|
||||||
|
return aes_cbc_decrypt(in, out, length, ivec, cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(length % 16)
|
||||||
|
length = length / 16 + 1;
|
||||||
|
else length /= 16;
|
||||||
|
feedback = _mm_loadu_si128((__m128i*)ivec);
|
||||||
|
for(i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
last_in = _mm_loadu_si128(&((__m128i*)in)[i]);
|
||||||
|
data = _mm_xor_si128(last_in, ((__m128i*)key)[number_of_rounds]);
|
||||||
|
for(j = number_of_rounds - 1; j > 0; j--)
|
||||||
|
{
|
||||||
|
data = _mm_aesdec_si128(data, ((__m128i*)key)[j]);
|
||||||
|
}
|
||||||
|
data = _mm_aesdeclast_si128(data, ((__m128i*)key)[0]);
|
||||||
|
data = _mm_xor_si128(data, feedback);
|
||||||
|
_mm_storeu_si128(&((__m128i*)out)[i], data);
|
||||||
|
feedback = last_in;
|
||||||
|
}
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ctr_inc(unsigned char *ctr_blk)
|
||||||
|
{
|
||||||
|
uint32_t c;
|
||||||
|
|
||||||
|
c = *(uint32_t*)(ctr_blk + 8);
|
||||||
|
c++;
|
||||||
|
*(uint32_t*)(ctr_blk + 8) = c;
|
||||||
|
|
||||||
|
if(!c)
|
||||||
|
*(uint32_t*)(ctr_blk + 12) = *(uint32_t*)(ctr_blk + 12) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
AES_RETURN AES_CTR_encrypt(const unsigned char *in,
|
||||||
|
unsigned char *out,
|
||||||
|
const unsigned char ivec[8],
|
||||||
|
const unsigned char nonce[4],
|
||||||
|
unsigned long length,
|
||||||
|
const aes_encrypt_ctx cx[1])
|
||||||
|
{
|
||||||
|
__m128i ctr_block = { 0 }, *key = (__m128i*)cx->ks, tmp, ONE, BSWAP_EPI64;
|
||||||
|
int number_of_rounds = cx->inf.b[0] >> 4, j;
|
||||||
|
unsigned long i;
|
||||||
|
|
||||||
|
if(number_of_rounds != 10 && number_of_rounds != 12 && number_of_rounds != 14)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
|
if(!has_aes_ni())
|
||||||
|
{
|
||||||
|
unsigned char ctr_blk[16];
|
||||||
|
*(uint64_t*)ctr_blk = *(uint64_t*)ivec;
|
||||||
|
*(uint32_t*)(ctr_blk + 8) = *(uint32_t*)nonce;
|
||||||
|
return aes_ctr_crypt(in, out, length, (unsigned char*)ctr_blk, ctr_inc, cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(length % 16)
|
||||||
|
length = length / 16 + 1;
|
||||||
|
else length /= 16;
|
||||||
|
ONE = _mm_set_epi32(0, 1, 0, 0);
|
||||||
|
BSWAP_EPI64 = _mm_setr_epi8(7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8);
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
ctr_block = _mm_insert_epi64(ctr_block, *(long long*)ivec, 1);
|
||||||
|
#else
|
||||||
|
ctr_block = _mm_set_epi64(*(__m64*)ivec, *(__m64*)&ctr_block);
|
||||||
|
#endif
|
||||||
|
ctr_block = _mm_insert_epi32(ctr_block, *(long*)nonce, 1);
|
||||||
|
ctr_block = _mm_srli_si128(ctr_block, 4);
|
||||||
|
ctr_block = _mm_shuffle_epi8(ctr_block, BSWAP_EPI64);
|
||||||
|
ctr_block = _mm_add_epi64(ctr_block, ONE);
|
||||||
|
for(i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
tmp = _mm_shuffle_epi8(ctr_block, BSWAP_EPI64);
|
||||||
|
ctr_block = _mm_add_epi64(ctr_block, ONE);
|
||||||
|
tmp = _mm_xor_si128(tmp, ((__m128i*)key)[0]);
|
||||||
|
for(j = 1; j <number_of_rounds; j++)
|
||||||
|
{
|
||||||
|
tmp = _mm_aesenc_si128(tmp, ((__m128i*)key)[j]);
|
||||||
|
};
|
||||||
|
tmp = _mm_aesenclast_si128(tmp, ((__m128i*)key)[j]);
|
||||||
|
tmp = _mm_xor_si128(tmp, _mm_loadu_si128(&((__m128i*)in)[i]));
|
||||||
|
_mm_storeu_si128(&((__m128i*)out)[i], tmp);
|
||||||
|
}
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
void aes_CBC_encrypt(const unsigned char *in,
|
||||||
|
unsigned char *out,
|
||||||
|
unsigned char ivec[16],
|
||||||
|
unsigned long length,
|
||||||
|
unsigned char *key,
|
||||||
|
int number_of_rounds)
|
||||||
|
{
|
||||||
|
__m128i feedback, data;
|
||||||
|
unsigned long i;
|
||||||
|
int j;
|
||||||
|
if(length % 16)
|
||||||
|
length = length / 16 + 1;
|
||||||
|
else length /= 16;
|
||||||
|
feedback = _mm_loadu_si128((__m128i*)ivec);
|
||||||
|
for(i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
data = _mm_loadu_si128(&((__m128i*)in)[i]);
|
||||||
|
feedback = _mm_xor_si128(data, feedback);
|
||||||
|
feedback = _mm_xor_si128(feedback, ((__m128i*)key)[0]);
|
||||||
|
for(j = 1; j <number_of_rounds; j++)
|
||||||
|
feedback = _mm_aesenc_si128(feedback, ((__m128i*)key)[j]);
|
||||||
|
feedback = _mm_aesenclast_si128(feedback, ((__m128i*)key)[j]);
|
||||||
|
_mm_storeu_si128(&((__m128i*)out)[i], feedback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void aes_CBC_decrypt(const unsigned char *in,
|
||||||
|
unsigned char *out,
|
||||||
|
unsigned char ivec[16],
|
||||||
|
unsigned long length,
|
||||||
|
unsigned char *key,
|
||||||
|
int number_of_rounds)
|
||||||
|
{
|
||||||
|
__m128i data, feedback, last_in;
|
||||||
|
unsigned long i;
|
||||||
|
int j;
|
||||||
|
if(length % 16)
|
||||||
|
length = length / 16 + 1;
|
||||||
|
else length /= 16;
|
||||||
|
feedback = _mm_loadu_si128((__m128i*)ivec);
|
||||||
|
for(i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
last_in = _mm_loadu_si128(&((__m128i*)in)[i]);
|
||||||
|
data = _mm_xor_si128(last_in, ((__m128i*)key)[0]);
|
||||||
|
for(j = 1; j <number_of_rounds; j++)
|
||||||
|
{
|
||||||
|
data = _mm_aesdec_si128(data, ((__m128i*)key)[j]);
|
||||||
|
}
|
||||||
|
data = _mm_aesdeclast_si128(data, ((__m128i*)key)[j]);
|
||||||
|
data = _mm_xor_si128(data, feedback);
|
||||||
|
_mm_storeu_si128(&((__m128i*)out)[i], data);
|
||||||
|
feedback = last_in;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AES_CTR_encrypt(const unsigned char *in,
|
||||||
|
unsigned char *out,
|
||||||
|
const unsigned char ivec[8],
|
||||||
|
const unsigned char nonce[4],
|
||||||
|
unsigned long length,
|
||||||
|
const unsigned char *key,
|
||||||
|
int number_of_rounds)
|
||||||
|
{
|
||||||
|
__m128i ctr_block = { 0 }, tmp, ONE, BSWAP_EPI64;
|
||||||
|
unsigned long i;
|
||||||
|
int j;
|
||||||
|
if(length % 16)
|
||||||
|
length = length / 16 + 1;
|
||||||
|
else length /= 16;
|
||||||
|
ONE = _mm_set_epi32(0, 1, 0, 0);
|
||||||
|
BSWAP_EPI64 = _mm_setr_epi8(7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8);
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
ctr_block = _mm_insert_epi64(ctr_block, *(long long*)ivec, 1);
|
||||||
|
#else
|
||||||
|
ctr_block = _mm_set_epi64(*(__m64*)ivec, *(__m64*)&ctr_block);
|
||||||
|
#endif
|
||||||
|
ctr_block = _mm_insert_epi32(ctr_block, *(long*)nonce, 1);
|
||||||
|
ctr_block = _mm_srli_si128(ctr_block, 4);
|
||||||
|
ctr_block = _mm_shuffle_epi8(ctr_block, BSWAP_EPI64);
|
||||||
|
ctr_block = _mm_add_epi64(ctr_block, ONE);
|
||||||
|
for(i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
tmp = _mm_shuffle_epi8(ctr_block, BSWAP_EPI64);
|
||||||
|
ctr_block = _mm_add_epi64(ctr_block, ONE);
|
||||||
|
tmp = _mm_xor_si128(tmp, ((__m128i*)key)[0]);
|
||||||
|
for(j = 1; j <number_of_rounds; j++)
|
||||||
|
{
|
||||||
|
tmp = _mm_aesenc_si128(tmp, ((__m128i*)key)[j]);
|
||||||
|
};
|
||||||
|
tmp = _mm_aesenclast_si128(tmp, ((__m128i*)key)[j]);
|
||||||
|
tmp = _mm_xor_si128(tmp, _mm_loadu_si128(&((__m128i*)in)[i]));
|
||||||
|
_mm_storeu_si128(&((__m128i*)out)[i], tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
59
SSZipArchive/minizip/aes/aes_ni.h
Normal file
59
SSZipArchive/minizip/aes/aes_ni.h
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||||
|
|
||||||
|
The redistribution and use of this software (with or without changes)
|
||||||
|
is allowed without the payment of fees or royalties provided that:
|
||||||
|
|
||||||
|
source code distributions include the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer;
|
||||||
|
|
||||||
|
binary distributions include the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer in their documentation.
|
||||||
|
|
||||||
|
This software is provided 'as is' with no explicit or implied warranties
|
||||||
|
in respect of its operation, including, but not limited to, correctness
|
||||||
|
and fitness for purpose.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Issue Date: 13/11/2013
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AES_NI_H
|
||||||
|
#define AES_NI_H
|
||||||
|
|
||||||
|
#define USE_AES_CONTEXT
|
||||||
|
|
||||||
|
#include "aesopt.h"
|
||||||
|
|
||||||
|
#if defined( USE_INTEL_AES_IF_PRESENT )
|
||||||
|
|
||||||
|
/* map names in C code to make them internal ('name' -> 'aes_name_i') */
|
||||||
|
#define aes_xi(x) aes_ ## x ## _i
|
||||||
|
|
||||||
|
/* map names here to provide the external API ('name' -> 'aes_name') */
|
||||||
|
#define aes_ni(x) aes_ ## x
|
||||||
|
|
||||||
|
AES_RETURN aes_ni(encrypt_key128)(const unsigned char *key, aes_encrypt_ctx cx[1]);
|
||||||
|
AES_RETURN aes_ni(encrypt_key192)(const unsigned char *key, aes_encrypt_ctx cx[1]);
|
||||||
|
AES_RETURN aes_ni(encrypt_key256)(const unsigned char *key, aes_encrypt_ctx cx[1]);
|
||||||
|
|
||||||
|
AES_RETURN aes_ni(decrypt_key128)(const unsigned char *key, aes_decrypt_ctx cx[1]);
|
||||||
|
AES_RETURN aes_ni(decrypt_key192)(const unsigned char *key, aes_decrypt_ctx cx[1]);
|
||||||
|
AES_RETURN aes_ni(decrypt_key256)(const unsigned char *key, aes_decrypt_ctx cx[1]);
|
||||||
|
|
||||||
|
AES_RETURN aes_ni(encrypt)(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1]);
|
||||||
|
AES_RETURN aes_ni(decrypt)(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1]);
|
||||||
|
|
||||||
|
AES_RETURN aes_xi(encrypt_key128)(const unsigned char *key, aes_encrypt_ctx cx[1]);
|
||||||
|
AES_RETURN aes_xi(encrypt_key192)(const unsigned char *key, aes_encrypt_ctx cx[1]);
|
||||||
|
AES_RETURN aes_xi(encrypt_key256)(const unsigned char *key, aes_encrypt_ctx cx[1]);
|
||||||
|
|
||||||
|
AES_RETURN aes_xi(decrypt_key128)(const unsigned char *key, aes_decrypt_ctx cx[1]);
|
||||||
|
AES_RETURN aes_xi(decrypt_key192)(const unsigned char *key, aes_decrypt_ctx cx[1]);
|
||||||
|
AES_RETURN aes_xi(decrypt_key256)(const unsigned char *key, aes_decrypt_ctx cx[1]);
|
||||||
|
|
||||||
|
AES_RETURN aes_xi(encrypt)(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1]);
|
||||||
|
AES_RETURN aes_xi(decrypt)(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1]);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
301
SSZipArchive/minizip/aes/aescrypt.c
Normal file
301
SSZipArchive/minizip/aes/aescrypt.c
Normal file
@@ -0,0 +1,301 @@
|
|||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||||
|
|
||||||
|
The redistribution and use of this software (with or without changes)
|
||||||
|
is allowed without the payment of fees or royalties provided that:
|
||||||
|
|
||||||
|
source code distributions include the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer;
|
||||||
|
|
||||||
|
binary distributions include the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer in their documentation.
|
||||||
|
|
||||||
|
This software is provided 'as is' with no explicit or implied warranties
|
||||||
|
in respect of its operation, including, but not limited to, correctness
|
||||||
|
and fitness for purpose.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Issue Date: 20/12/2007
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "aesopt.h"
|
||||||
|
#include "aestab.h"
|
||||||
|
|
||||||
|
#if defined( USE_INTEL_AES_IF_PRESENT )
|
||||||
|
# include "aes_ni.h"
|
||||||
|
#else
|
||||||
|
/* map names here to provide the external API ('name' -> 'aes_name') */
|
||||||
|
# define aes_xi(x) aes_ ## x
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c])
|
||||||
|
#define so(y,x,c) word_out(y, c, s(x,c))
|
||||||
|
|
||||||
|
#if defined(ARRAYS)
|
||||||
|
#define locals(y,x) x[4],y[4]
|
||||||
|
#else
|
||||||
|
#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
|
||||||
|
s(y,2) = s(x,2); s(y,3) = s(x,3);
|
||||||
|
#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)
|
||||||
|
#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
|
||||||
|
#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)
|
||||||
|
|
||||||
|
#if ( FUNCS_IN_C & ENCRYPTION_IN_C )
|
||||||
|
|
||||||
|
/* Visual C++ .Net v7.1 provides the fastest encryption code when using
|
||||||
|
Pentium optimiation with small code but this is poor for decryption
|
||||||
|
so we need to control this with the following VC++ pragmas
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined( _MSC_VER ) && !defined( _WIN64 )
|
||||||
|
#pragma optimize( "s", on )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Given the column (c) of the output state variable, the following
|
||||||
|
macros give the input state variables which are needed in its
|
||||||
|
computation for each row (r) of the state. All the alternative
|
||||||
|
macros give the same end values but expand into different ways
|
||||||
|
of calculating these values. In particular the complex macro
|
||||||
|
used for dynamically variable block sizes is designed to expand
|
||||||
|
to a compile time constant whenever possible but will expand to
|
||||||
|
conditional clauses on some branches (I am grateful to Frank
|
||||||
|
Yellin for this construction)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define fwd_var(x,r,c)\
|
||||||
|
( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
|
||||||
|
: r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\
|
||||||
|
: r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
|
||||||
|
: ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))
|
||||||
|
|
||||||
|
#if defined(FT4_SET)
|
||||||
|
#undef dec_fmvars
|
||||||
|
#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))
|
||||||
|
#elif defined(FT1_SET)
|
||||||
|
#undef dec_fmvars
|
||||||
|
#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(f,n),fwd_var,rf1,c))
|
||||||
|
#else
|
||||||
|
#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ fwd_mcol(no_table(x,t_use(s,box),fwd_var,rf1,c)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(FL4_SET)
|
||||||
|
#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c))
|
||||||
|
#elif defined(FL1_SET)
|
||||||
|
#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(f,l),fwd_var,rf1,c))
|
||||||
|
#else
|
||||||
|
#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(s,box),fwd_var,rf1,c))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
AES_RETURN aes_xi(encrypt)(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1])
|
||||||
|
{ uint32_t locals(b0, b1);
|
||||||
|
const uint32_t *kp;
|
||||||
|
#if defined( dec_fmvars )
|
||||||
|
dec_fmvars; /* declare variables for fwd_mcol() if needed */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
|
kp = cx->ks;
|
||||||
|
state_in(b0, in, kp);
|
||||||
|
|
||||||
|
#if (ENC_UNROLL == FULL)
|
||||||
|
|
||||||
|
switch(cx->inf.b[0])
|
||||||
|
{
|
||||||
|
case 14 * 16:
|
||||||
|
round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
|
||||||
|
round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
|
||||||
|
kp += 2 * N_COLS;
|
||||||
|
case 12 * 16:
|
||||||
|
round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
|
||||||
|
round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
|
||||||
|
kp += 2 * N_COLS;
|
||||||
|
case 10 * 16:
|
||||||
|
round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
|
||||||
|
round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
|
||||||
|
round(fwd_rnd, b1, b0, kp + 3 * N_COLS);
|
||||||
|
round(fwd_rnd, b0, b1, kp + 4 * N_COLS);
|
||||||
|
round(fwd_rnd, b1, b0, kp + 5 * N_COLS);
|
||||||
|
round(fwd_rnd, b0, b1, kp + 6 * N_COLS);
|
||||||
|
round(fwd_rnd, b1, b0, kp + 7 * N_COLS);
|
||||||
|
round(fwd_rnd, b0, b1, kp + 8 * N_COLS);
|
||||||
|
round(fwd_rnd, b1, b0, kp + 9 * N_COLS);
|
||||||
|
round(fwd_lrnd, b0, b1, kp +10 * N_COLS);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#if (ENC_UNROLL == PARTIAL)
|
||||||
|
{ uint32_t rnd;
|
||||||
|
for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd)
|
||||||
|
{
|
||||||
|
kp += N_COLS;
|
||||||
|
round(fwd_rnd, b1, b0, kp);
|
||||||
|
kp += N_COLS;
|
||||||
|
round(fwd_rnd, b0, b1, kp);
|
||||||
|
}
|
||||||
|
kp += N_COLS;
|
||||||
|
round(fwd_rnd, b1, b0, kp);
|
||||||
|
#else
|
||||||
|
{ uint32_t rnd;
|
||||||
|
for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd)
|
||||||
|
{
|
||||||
|
kp += N_COLS;
|
||||||
|
round(fwd_rnd, b1, b0, kp);
|
||||||
|
l_copy(b0, b1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
kp += N_COLS;
|
||||||
|
round(fwd_lrnd, b0, b1, kp);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
state_out(out, b0);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ( FUNCS_IN_C & DECRYPTION_IN_C)
|
||||||
|
|
||||||
|
/* Visual C++ .Net v7.1 provides the fastest encryption code when using
|
||||||
|
Pentium optimiation with small code but this is poor for decryption
|
||||||
|
so we need to control this with the following VC++ pragmas
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined( _MSC_VER ) && !defined( _WIN64 )
|
||||||
|
#pragma optimize( "t", on )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Given the column (c) of the output state variable, the following
|
||||||
|
macros give the input state variables which are needed in its
|
||||||
|
computation for each row (r) of the state. All the alternative
|
||||||
|
macros give the same end values but expand into different ways
|
||||||
|
of calculating these values. In particular the complex macro
|
||||||
|
used for dynamically variable block sizes is designed to expand
|
||||||
|
to a compile time constant whenever possible but will expand to
|
||||||
|
conditional clauses on some branches (I am grateful to Frank
|
||||||
|
Yellin for this construction)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define inv_var(x,r,c)\
|
||||||
|
( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
|
||||||
|
: r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\
|
||||||
|
: r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
|
||||||
|
: ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0)))
|
||||||
|
|
||||||
|
#if defined(IT4_SET)
|
||||||
|
#undef dec_imvars
|
||||||
|
#define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c))
|
||||||
|
#elif defined(IT1_SET)
|
||||||
|
#undef dec_imvars
|
||||||
|
#define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(i,n),inv_var,rf1,c))
|
||||||
|
#else
|
||||||
|
#define inv_rnd(y,x,k,c) (s(y,c) = inv_mcol((k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(IL4_SET)
|
||||||
|
#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c))
|
||||||
|
#elif defined(IL1_SET)
|
||||||
|
#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(i,l),inv_var,rf1,c))
|
||||||
|
#else
|
||||||
|
#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* This code can work with the decryption key schedule in the */
|
||||||
|
/* order that is used for encrytpion (where the 1st decryption */
|
||||||
|
/* round key is at the high end ot the schedule) or with a key */
|
||||||
|
/* schedule that has been reversed to put the 1st decryption */
|
||||||
|
/* round key at the low end of the schedule in memory (when */
|
||||||
|
/* AES_REV_DKS is defined) */
|
||||||
|
|
||||||
|
#ifdef AES_REV_DKS
|
||||||
|
#define key_ofs 0
|
||||||
|
#define rnd_key(n) (kp + n * N_COLS)
|
||||||
|
#else
|
||||||
|
#define key_ofs 1
|
||||||
|
#define rnd_key(n) (kp - n * N_COLS)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
AES_RETURN aes_xi(decrypt)(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1])
|
||||||
|
{ uint32_t locals(b0, b1);
|
||||||
|
#if defined( dec_imvars )
|
||||||
|
dec_imvars; /* declare variables for inv_mcol() if needed */
|
||||||
|
#endif
|
||||||
|
const uint32_t *kp;
|
||||||
|
|
||||||
|
if(cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
|
kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0);
|
||||||
|
state_in(b0, in, kp);
|
||||||
|
|
||||||
|
#if (DEC_UNROLL == FULL)
|
||||||
|
|
||||||
|
kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2));
|
||||||
|
switch(cx->inf.b[0])
|
||||||
|
{
|
||||||
|
case 14 * 16:
|
||||||
|
round(inv_rnd, b1, b0, rnd_key(-13));
|
||||||
|
round(inv_rnd, b0, b1, rnd_key(-12));
|
||||||
|
case 12 * 16:
|
||||||
|
round(inv_rnd, b1, b0, rnd_key(-11));
|
||||||
|
round(inv_rnd, b0, b1, rnd_key(-10));
|
||||||
|
case 10 * 16:
|
||||||
|
round(inv_rnd, b1, b0, rnd_key(-9));
|
||||||
|
round(inv_rnd, b0, b1, rnd_key(-8));
|
||||||
|
round(inv_rnd, b1, b0, rnd_key(-7));
|
||||||
|
round(inv_rnd, b0, b1, rnd_key(-6));
|
||||||
|
round(inv_rnd, b1, b0, rnd_key(-5));
|
||||||
|
round(inv_rnd, b0, b1, rnd_key(-4));
|
||||||
|
round(inv_rnd, b1, b0, rnd_key(-3));
|
||||||
|
round(inv_rnd, b0, b1, rnd_key(-2));
|
||||||
|
round(inv_rnd, b1, b0, rnd_key(-1));
|
||||||
|
round(inv_lrnd, b0, b1, rnd_key( 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#if (DEC_UNROLL == PARTIAL)
|
||||||
|
{ uint32_t rnd;
|
||||||
|
for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd)
|
||||||
|
{
|
||||||
|
kp = rnd_key(1);
|
||||||
|
round(inv_rnd, b1, b0, kp);
|
||||||
|
kp = rnd_key(1);
|
||||||
|
round(inv_rnd, b0, b1, kp);
|
||||||
|
}
|
||||||
|
kp = rnd_key(1);
|
||||||
|
round(inv_rnd, b1, b0, kp);
|
||||||
|
#else
|
||||||
|
{ uint32_t rnd;
|
||||||
|
for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd)
|
||||||
|
{
|
||||||
|
kp = rnd_key(1);
|
||||||
|
round(inv_rnd, b1, b0, kp);
|
||||||
|
l_copy(b0, b1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
kp = rnd_key(1);
|
||||||
|
round(inv_lrnd, b0, b1, kp);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
state_out(out, b0);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
554
SSZipArchive/minizip/aes/aeskey.c
Normal file
554
SSZipArchive/minizip/aes/aeskey.c
Normal file
@@ -0,0 +1,554 @@
|
|||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||||
|
|
||||||
|
The redistribution and use of this software (with or without changes)
|
||||||
|
is allowed without the payment of fees or royalties provided that:
|
||||||
|
|
||||||
|
source code distributions include the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer;
|
||||||
|
|
||||||
|
binary distributions include the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer in their documentation.
|
||||||
|
|
||||||
|
This software is provided 'as is' with no explicit or implied warranties
|
||||||
|
in respect of its operation, including, but not limited to, correctness
|
||||||
|
and fitness for purpose.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Issue Date: 20/12/2007
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "aesopt.h"
|
||||||
|
#include "aestab.h"
|
||||||
|
|
||||||
|
#if defined( USE_INTEL_AES_IF_PRESENT )
|
||||||
|
# include "aes_ni.h"
|
||||||
|
#else
|
||||||
|
/* map names here to provide the external API ('name' -> 'aes_name') */
|
||||||
|
# define aes_xi(x) aes_ ## x
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||||
|
# include "aes_via_ace.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Initialise the key schedule from the user supplied key. The key
|
||||||
|
length can be specified in bytes, with legal values of 16, 24
|
||||||
|
and 32, or in bits, with legal values of 128, 192 and 256. These
|
||||||
|
values correspond with Nk values of 4, 6 and 8 respectively.
|
||||||
|
|
||||||
|
The following macros implement a single cycle in the key
|
||||||
|
schedule generation process. The number of cycles needed
|
||||||
|
for each cx->n_col and nk value is:
|
||||||
|
|
||||||
|
nk = 4 5 6 7 8
|
||||||
|
------------------------------
|
||||||
|
cx->n_col = 4 10 9 8 7 7
|
||||||
|
cx->n_col = 5 14 11 10 9 9
|
||||||
|
cx->n_col = 6 19 15 12 11 11
|
||||||
|
cx->n_col = 7 21 19 16 13 14
|
||||||
|
cx->n_col = 8 29 23 19 17 14
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined( REDUCE_CODE_SIZE )
|
||||||
|
# define ls_box ls_sub
|
||||||
|
uint32_t ls_sub(const uint32_t t, const uint32_t n);
|
||||||
|
# define inv_mcol im_sub
|
||||||
|
uint32_t im_sub(const uint32_t x);
|
||||||
|
# ifdef ENC_KS_UNROLL
|
||||||
|
# undef ENC_KS_UNROLL
|
||||||
|
# endif
|
||||||
|
# ifdef DEC_KS_UNROLL
|
||||||
|
# undef DEC_KS_UNROLL
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (FUNCS_IN_C & ENC_KEYING_IN_C)
|
||||||
|
|
||||||
|
#if defined(AES_128) || defined( AES_VAR )
|
||||||
|
|
||||||
|
#define ke4(k,i) \
|
||||||
|
{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
|
||||||
|
k[4*(i)+5] = ss[1] ^= ss[0]; \
|
||||||
|
k[4*(i)+6] = ss[2] ^= ss[1]; \
|
||||||
|
k[4*(i)+7] = ss[3] ^= ss[2]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
AES_RETURN aes_xi(encrypt_key128)(const unsigned char *key, aes_encrypt_ctx cx[1])
|
||||||
|
{ uint32_t ss[4];
|
||||||
|
|
||||||
|
cx->ks[0] = ss[0] = word_in(key, 0);
|
||||||
|
cx->ks[1] = ss[1] = word_in(key, 1);
|
||||||
|
cx->ks[2] = ss[2] = word_in(key, 2);
|
||||||
|
cx->ks[3] = ss[3] = word_in(key, 3);
|
||||||
|
|
||||||
|
#ifdef ENC_KS_UNROLL
|
||||||
|
ke4(cx->ks, 0); ke4(cx->ks, 1);
|
||||||
|
ke4(cx->ks, 2); ke4(cx->ks, 3);
|
||||||
|
ke4(cx->ks, 4); ke4(cx->ks, 5);
|
||||||
|
ke4(cx->ks, 6); ke4(cx->ks, 7);
|
||||||
|
ke4(cx->ks, 8);
|
||||||
|
#else
|
||||||
|
{ uint32_t i;
|
||||||
|
for(i = 0; i < 9; ++i)
|
||||||
|
ke4(cx->ks, i);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
ke4(cx->ks, 9);
|
||||||
|
cx->inf.l = 0;
|
||||||
|
cx->inf.b[0] = 10 * 16;
|
||||||
|
|
||||||
|
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||||
|
if(VIA_ACE_AVAILABLE)
|
||||||
|
cx->inf.b[1] = 0xff;
|
||||||
|
#endif
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(AES_192) || defined( AES_VAR )
|
||||||
|
|
||||||
|
#define kef6(k,i) \
|
||||||
|
{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
|
||||||
|
k[6*(i)+ 7] = ss[1] ^= ss[0]; \
|
||||||
|
k[6*(i)+ 8] = ss[2] ^= ss[1]; \
|
||||||
|
k[6*(i)+ 9] = ss[3] ^= ss[2]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ke6(k,i) \
|
||||||
|
{ kef6(k,i); \
|
||||||
|
k[6*(i)+10] = ss[4] ^= ss[3]; \
|
||||||
|
k[6*(i)+11] = ss[5] ^= ss[4]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
AES_RETURN aes_xi(encrypt_key192)(const unsigned char *key, aes_encrypt_ctx cx[1])
|
||||||
|
{ uint32_t ss[6];
|
||||||
|
|
||||||
|
cx->ks[0] = ss[0] = word_in(key, 0);
|
||||||
|
cx->ks[1] = ss[1] = word_in(key, 1);
|
||||||
|
cx->ks[2] = ss[2] = word_in(key, 2);
|
||||||
|
cx->ks[3] = ss[3] = word_in(key, 3);
|
||||||
|
cx->ks[4] = ss[4] = word_in(key, 4);
|
||||||
|
cx->ks[5] = ss[5] = word_in(key, 5);
|
||||||
|
|
||||||
|
#ifdef ENC_KS_UNROLL
|
||||||
|
ke6(cx->ks, 0); ke6(cx->ks, 1);
|
||||||
|
ke6(cx->ks, 2); ke6(cx->ks, 3);
|
||||||
|
ke6(cx->ks, 4); ke6(cx->ks, 5);
|
||||||
|
ke6(cx->ks, 6);
|
||||||
|
#else
|
||||||
|
{ uint32_t i;
|
||||||
|
for(i = 0; i < 7; ++i)
|
||||||
|
ke6(cx->ks, i);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
kef6(cx->ks, 7);
|
||||||
|
cx->inf.l = 0;
|
||||||
|
cx->inf.b[0] = 12 * 16;
|
||||||
|
|
||||||
|
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||||
|
if(VIA_ACE_AVAILABLE)
|
||||||
|
cx->inf.b[1] = 0xff;
|
||||||
|
#endif
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(AES_256) || defined( AES_VAR )
|
||||||
|
|
||||||
|
#define kef8(k,i) \
|
||||||
|
{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
|
||||||
|
k[8*(i)+ 9] = ss[1] ^= ss[0]; \
|
||||||
|
k[8*(i)+10] = ss[2] ^= ss[1]; \
|
||||||
|
k[8*(i)+11] = ss[3] ^= ss[2]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ke8(k,i) \
|
||||||
|
{ kef8(k,i); \
|
||||||
|
k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); \
|
||||||
|
k[8*(i)+13] = ss[5] ^= ss[4]; \
|
||||||
|
k[8*(i)+14] = ss[6] ^= ss[5]; \
|
||||||
|
k[8*(i)+15] = ss[7] ^= ss[6]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
AES_RETURN aes_xi(encrypt_key256)(const unsigned char *key, aes_encrypt_ctx cx[1])
|
||||||
|
{ uint32_t ss[8];
|
||||||
|
|
||||||
|
cx->ks[0] = ss[0] = word_in(key, 0);
|
||||||
|
cx->ks[1] = ss[1] = word_in(key, 1);
|
||||||
|
cx->ks[2] = ss[2] = word_in(key, 2);
|
||||||
|
cx->ks[3] = ss[3] = word_in(key, 3);
|
||||||
|
cx->ks[4] = ss[4] = word_in(key, 4);
|
||||||
|
cx->ks[5] = ss[5] = word_in(key, 5);
|
||||||
|
cx->ks[6] = ss[6] = word_in(key, 6);
|
||||||
|
cx->ks[7] = ss[7] = word_in(key, 7);
|
||||||
|
|
||||||
|
#ifdef ENC_KS_UNROLL
|
||||||
|
ke8(cx->ks, 0); ke8(cx->ks, 1);
|
||||||
|
ke8(cx->ks, 2); ke8(cx->ks, 3);
|
||||||
|
ke8(cx->ks, 4); ke8(cx->ks, 5);
|
||||||
|
#else
|
||||||
|
{ uint32_t i;
|
||||||
|
for(i = 0; i < 6; ++i)
|
||||||
|
ke8(cx->ks, i);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
kef8(cx->ks, 6);
|
||||||
|
cx->inf.l = 0;
|
||||||
|
cx->inf.b[0] = 14 * 16;
|
||||||
|
|
||||||
|
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||||
|
if(VIA_ACE_AVAILABLE)
|
||||||
|
cx->inf.b[1] = 0xff;
|
||||||
|
#endif
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (FUNCS_IN_C & DEC_KEYING_IN_C)
|
||||||
|
|
||||||
|
/* this is used to store the decryption round keys */
|
||||||
|
/* in forward or reverse order */
|
||||||
|
|
||||||
|
#ifdef AES_REV_DKS
|
||||||
|
#define v(n,i) ((n) - (i) + 2 * ((i) & 3))
|
||||||
|
#else
|
||||||
|
#define v(n,i) (i)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if DEC_ROUND == NO_TABLES
|
||||||
|
#define ff(x) (x)
|
||||||
|
#else
|
||||||
|
#define ff(x) inv_mcol(x)
|
||||||
|
#if defined( dec_imvars )
|
||||||
|
#define d_vars dec_imvars
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(AES_128) || defined( AES_VAR )
|
||||||
|
|
||||||
|
#define k4e(k,i) \
|
||||||
|
{ k[v(40,(4*(i))+4)] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
|
||||||
|
k[v(40,(4*(i))+5)] = ss[1] ^= ss[0]; \
|
||||||
|
k[v(40,(4*(i))+6)] = ss[2] ^= ss[1]; \
|
||||||
|
k[v(40,(4*(i))+7)] = ss[3] ^= ss[2]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
|
||||||
|
#define kdf4(k,i) \
|
||||||
|
{ ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; \
|
||||||
|
ss[1] = ss[1] ^ ss[3]; \
|
||||||
|
ss[2] = ss[2] ^ ss[3]; \
|
||||||
|
ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
|
||||||
|
ss[i % 4] ^= ss[4]; \
|
||||||
|
ss[4] ^= k[v(40,(4*(i)))]; k[v(40,(4*(i))+4)] = ff(ss[4]); \
|
||||||
|
ss[4] ^= k[v(40,(4*(i))+1)]; k[v(40,(4*(i))+5)] = ff(ss[4]); \
|
||||||
|
ss[4] ^= k[v(40,(4*(i))+2)]; k[v(40,(4*(i))+6)] = ff(ss[4]); \
|
||||||
|
ss[4] ^= k[v(40,(4*(i))+3)]; k[v(40,(4*(i))+7)] = ff(ss[4]); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define kd4(k,i) \
|
||||||
|
{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
|
||||||
|
ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \
|
||||||
|
k[v(40,(4*(i))+4)] = ss[4] ^= k[v(40,(4*(i)))]; \
|
||||||
|
k[v(40,(4*(i))+5)] = ss[4] ^= k[v(40,(4*(i))+1)]; \
|
||||||
|
k[v(40,(4*(i))+6)] = ss[4] ^= k[v(40,(4*(i))+2)]; \
|
||||||
|
k[v(40,(4*(i))+7)] = ss[4] ^= k[v(40,(4*(i))+3)]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define kdl4(k,i) \
|
||||||
|
{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \
|
||||||
|
k[v(40,(4*(i))+4)] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; \
|
||||||
|
k[v(40,(4*(i))+5)] = ss[1] ^ ss[3]; \
|
||||||
|
k[v(40,(4*(i))+6)] = ss[0]; \
|
||||||
|
k[v(40,(4*(i))+7)] = ss[1]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define kdf4(k,i) \
|
||||||
|
{ ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[v(40,(4*(i))+ 4)] = ff(ss[0]); \
|
||||||
|
ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ff(ss[1]); \
|
||||||
|
ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ff(ss[2]); \
|
||||||
|
ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ff(ss[3]); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define kd4(k,i) \
|
||||||
|
{ ss[4] = ls_box(ss[3],3) ^ t_use(r,c)[i]; \
|
||||||
|
ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[v(40,(4*(i))+ 4)] = ss[4] ^= k[v(40,(4*(i)))]; \
|
||||||
|
ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ss[4] ^= k[v(40,(4*(i))+ 1)]; \
|
||||||
|
ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ss[4] ^= k[v(40,(4*(i))+ 2)]; \
|
||||||
|
ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ss[4] ^= k[v(40,(4*(i))+ 3)]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define kdl4(k,i) \
|
||||||
|
{ ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[v(40,(4*(i))+ 4)] = ss[0]; \
|
||||||
|
ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ss[1]; \
|
||||||
|
ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ss[2]; \
|
||||||
|
ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ss[3]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
AES_RETURN aes_xi(decrypt_key128)(const unsigned char *key, aes_decrypt_ctx cx[1])
|
||||||
|
{ uint32_t ss[5];
|
||||||
|
#if defined( d_vars )
|
||||||
|
d_vars;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
cx->ks[v(40,(0))] = ss[0] = word_in(key, 0);
|
||||||
|
cx->ks[v(40,(1))] = ss[1] = word_in(key, 1);
|
||||||
|
cx->ks[v(40,(2))] = ss[2] = word_in(key, 2);
|
||||||
|
cx->ks[v(40,(3))] = ss[3] = word_in(key, 3);
|
||||||
|
|
||||||
|
#ifdef DEC_KS_UNROLL
|
||||||
|
kdf4(cx->ks, 0); kd4(cx->ks, 1);
|
||||||
|
kd4(cx->ks, 2); kd4(cx->ks, 3);
|
||||||
|
kd4(cx->ks, 4); kd4(cx->ks, 5);
|
||||||
|
kd4(cx->ks, 6); kd4(cx->ks, 7);
|
||||||
|
kd4(cx->ks, 8); kdl4(cx->ks, 9);
|
||||||
|
#else
|
||||||
|
{ uint32_t i;
|
||||||
|
for(i = 0; i < 10; ++i)
|
||||||
|
k4e(cx->ks, i);
|
||||||
|
#if !(DEC_ROUND == NO_TABLES)
|
||||||
|
for(i = N_COLS; i < 10 * N_COLS; ++i)
|
||||||
|
cx->ks[i] = inv_mcol(cx->ks[i]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
cx->inf.l = 0;
|
||||||
|
cx->inf.b[0] = 10 * 16;
|
||||||
|
|
||||||
|
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||||
|
if(VIA_ACE_AVAILABLE)
|
||||||
|
cx->inf.b[1] = 0xff;
|
||||||
|
#endif
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(AES_192) || defined( AES_VAR )
|
||||||
|
|
||||||
|
#define k6ef(k,i) \
|
||||||
|
{ k[v(48,(6*(i))+ 6)] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
|
||||||
|
k[v(48,(6*(i))+ 7)] = ss[1] ^= ss[0]; \
|
||||||
|
k[v(48,(6*(i))+ 8)] = ss[2] ^= ss[1]; \
|
||||||
|
k[v(48,(6*(i))+ 9)] = ss[3] ^= ss[2]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define k6e(k,i) \
|
||||||
|
{ k6ef(k,i); \
|
||||||
|
k[v(48,(6*(i))+10)] = ss[4] ^= ss[3]; \
|
||||||
|
k[v(48,(6*(i))+11)] = ss[5] ^= ss[4]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define kdf6(k,i) \
|
||||||
|
{ ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ff(ss[0]); \
|
||||||
|
ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ff(ss[1]); \
|
||||||
|
ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ff(ss[2]); \
|
||||||
|
ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ff(ss[3]); \
|
||||||
|
ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ff(ss[4]); \
|
||||||
|
ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ff(ss[5]); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define kd6(k,i) \
|
||||||
|
{ ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \
|
||||||
|
ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[v(48,(6*(i))+ 6)] = ss[6] ^= k[v(48,(6*(i)))]; \
|
||||||
|
ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[6] ^= k[v(48,(6*(i))+ 1)]; \
|
||||||
|
ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[6] ^= k[v(48,(6*(i))+ 2)]; \
|
||||||
|
ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[6] ^= k[v(48,(6*(i))+ 3)]; \
|
||||||
|
ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ss[6] ^= k[v(48,(6*(i))+ 4)]; \
|
||||||
|
ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ss[6] ^= k[v(48,(6*(i))+ 5)]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define kdl6(k,i) \
|
||||||
|
{ ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ss[0]; \
|
||||||
|
ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[1]; \
|
||||||
|
ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[2]; \
|
||||||
|
ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[3]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
AES_RETURN aes_xi(decrypt_key192)(const unsigned char *key, aes_decrypt_ctx cx[1])
|
||||||
|
{ uint32_t ss[7];
|
||||||
|
#if defined( d_vars )
|
||||||
|
d_vars;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
cx->ks[v(48,(0))] = ss[0] = word_in(key, 0);
|
||||||
|
cx->ks[v(48,(1))] = ss[1] = word_in(key, 1);
|
||||||
|
cx->ks[v(48,(2))] = ss[2] = word_in(key, 2);
|
||||||
|
cx->ks[v(48,(3))] = ss[3] = word_in(key, 3);
|
||||||
|
|
||||||
|
#ifdef DEC_KS_UNROLL
|
||||||
|
cx->ks[v(48,(4))] = ff(ss[4] = word_in(key, 4));
|
||||||
|
cx->ks[v(48,(5))] = ff(ss[5] = word_in(key, 5));
|
||||||
|
kdf6(cx->ks, 0); kd6(cx->ks, 1);
|
||||||
|
kd6(cx->ks, 2); kd6(cx->ks, 3);
|
||||||
|
kd6(cx->ks, 4); kd6(cx->ks, 5);
|
||||||
|
kd6(cx->ks, 6); kdl6(cx->ks, 7);
|
||||||
|
#else
|
||||||
|
cx->ks[v(48,(4))] = ss[4] = word_in(key, 4);
|
||||||
|
cx->ks[v(48,(5))] = ss[5] = word_in(key, 5);
|
||||||
|
{ uint32_t i;
|
||||||
|
|
||||||
|
for(i = 0; i < 7; ++i)
|
||||||
|
k6e(cx->ks, i);
|
||||||
|
k6ef(cx->ks, 7);
|
||||||
|
#if !(DEC_ROUND == NO_TABLES)
|
||||||
|
for(i = N_COLS; i < 12 * N_COLS; ++i)
|
||||||
|
cx->ks[i] = inv_mcol(cx->ks[i]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
cx->inf.l = 0;
|
||||||
|
cx->inf.b[0] = 12 * 16;
|
||||||
|
|
||||||
|
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||||
|
if(VIA_ACE_AVAILABLE)
|
||||||
|
cx->inf.b[1] = 0xff;
|
||||||
|
#endif
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(AES_256) || defined( AES_VAR )
|
||||||
|
|
||||||
|
#define k8ef(k,i) \
|
||||||
|
{ k[v(56,(8*(i))+ 8)] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
|
||||||
|
k[v(56,(8*(i))+ 9)] = ss[1] ^= ss[0]; \
|
||||||
|
k[v(56,(8*(i))+10)] = ss[2] ^= ss[1]; \
|
||||||
|
k[v(56,(8*(i))+11)] = ss[3] ^= ss[2]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define k8e(k,i) \
|
||||||
|
{ k8ef(k,i); \
|
||||||
|
k[v(56,(8*(i))+12)] = ss[4] ^= ls_box(ss[3],0); \
|
||||||
|
k[v(56,(8*(i))+13)] = ss[5] ^= ss[4]; \
|
||||||
|
k[v(56,(8*(i))+14)] = ss[6] ^= ss[5]; \
|
||||||
|
k[v(56,(8*(i))+15)] = ss[7] ^= ss[6]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define kdf8(k,i) \
|
||||||
|
{ ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ff(ss[0]); \
|
||||||
|
ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ff(ss[1]); \
|
||||||
|
ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ff(ss[2]); \
|
||||||
|
ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ff(ss[3]); \
|
||||||
|
ss[4] ^= ls_box(ss[3],0); k[v(56,(8*(i))+12)] = ff(ss[4]); \
|
||||||
|
ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ff(ss[5]); \
|
||||||
|
ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ff(ss[6]); \
|
||||||
|
ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ff(ss[7]); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define kd8(k,i) \
|
||||||
|
{ ss[8] = ls_box(ss[7],3) ^ t_use(r,c)[i]; \
|
||||||
|
ss[0] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+ 8)] = ss[8] ^= k[v(56,(8*(i)))]; \
|
||||||
|
ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[8] ^= k[v(56,(8*(i))+ 1)]; \
|
||||||
|
ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[8] ^= k[v(56,(8*(i))+ 2)]; \
|
||||||
|
ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[8] ^= k[v(56,(8*(i))+ 3)]; \
|
||||||
|
ss[8] = ls_box(ss[3],0); \
|
||||||
|
ss[4] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+12)] = ss[8] ^= k[v(56,(8*(i))+ 4)]; \
|
||||||
|
ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ss[8] ^= k[v(56,(8*(i))+ 5)]; \
|
||||||
|
ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ss[8] ^= k[v(56,(8*(i))+ 6)]; \
|
||||||
|
ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ss[8] ^= k[v(56,(8*(i))+ 7)]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define kdl8(k,i) \
|
||||||
|
{ ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ss[0]; \
|
||||||
|
ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[1]; \
|
||||||
|
ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[2]; \
|
||||||
|
ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[3]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
AES_RETURN aes_xi(decrypt_key256)(const unsigned char *key, aes_decrypt_ctx cx[1])
|
||||||
|
{ uint32_t ss[9];
|
||||||
|
#if defined( d_vars )
|
||||||
|
d_vars;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
cx->ks[v(56,(0))] = ss[0] = word_in(key, 0);
|
||||||
|
cx->ks[v(56,(1))] = ss[1] = word_in(key, 1);
|
||||||
|
cx->ks[v(56,(2))] = ss[2] = word_in(key, 2);
|
||||||
|
cx->ks[v(56,(3))] = ss[3] = word_in(key, 3);
|
||||||
|
|
||||||
|
#ifdef DEC_KS_UNROLL
|
||||||
|
cx->ks[v(56,(4))] = ff(ss[4] = word_in(key, 4));
|
||||||
|
cx->ks[v(56,(5))] = ff(ss[5] = word_in(key, 5));
|
||||||
|
cx->ks[v(56,(6))] = ff(ss[6] = word_in(key, 6));
|
||||||
|
cx->ks[v(56,(7))] = ff(ss[7] = word_in(key, 7));
|
||||||
|
kdf8(cx->ks, 0); kd8(cx->ks, 1);
|
||||||
|
kd8(cx->ks, 2); kd8(cx->ks, 3);
|
||||||
|
kd8(cx->ks, 4); kd8(cx->ks, 5);
|
||||||
|
kdl8(cx->ks, 6);
|
||||||
|
#else
|
||||||
|
cx->ks[v(56,(4))] = ss[4] = word_in(key, 4);
|
||||||
|
cx->ks[v(56,(5))] = ss[5] = word_in(key, 5);
|
||||||
|
cx->ks[v(56,(6))] = ss[6] = word_in(key, 6);
|
||||||
|
cx->ks[v(56,(7))] = ss[7] = word_in(key, 7);
|
||||||
|
{ uint32_t i;
|
||||||
|
|
||||||
|
for(i = 0; i < 6; ++i)
|
||||||
|
k8e(cx->ks, i);
|
||||||
|
k8ef(cx->ks, 6);
|
||||||
|
#if !(DEC_ROUND == NO_TABLES)
|
||||||
|
for(i = N_COLS; i < 14 * N_COLS; ++i)
|
||||||
|
cx->ks[i] = inv_mcol(cx->ks[i]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
cx->inf.l = 0;
|
||||||
|
cx->inf.b[0] = 14 * 16;
|
||||||
|
|
||||||
|
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||||
|
if(VIA_ACE_AVAILABLE)
|
||||||
|
cx->inf.b[1] = 0xff;
|
||||||
|
#endif
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( AES_VAR )
|
||||||
|
|
||||||
|
AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1])
|
||||||
|
{
|
||||||
|
switch(key_len)
|
||||||
|
{
|
||||||
|
case 16: case 128: return aes_encrypt_key128(key, cx);
|
||||||
|
case 24: case 192: return aes_encrypt_key192(key, cx);
|
||||||
|
case 32: case 256: return aes_encrypt_key256(key, cx);
|
||||||
|
default: return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1])
|
||||||
|
{
|
||||||
|
switch(key_len)
|
||||||
|
{
|
||||||
|
case 16: case 128: return aes_decrypt_key128(key, cx);
|
||||||
|
case 24: case 192: return aes_decrypt_key192(key, cx);
|
||||||
|
case 32: case 256: return aes_decrypt_key256(key, cx);
|
||||||
|
default: return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
776
SSZipArchive/minizip/aes/aesopt.h
Normal file
776
SSZipArchive/minizip/aes/aesopt.h
Normal file
@@ -0,0 +1,776 @@
|
|||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||||
|
|
||||||
|
The redistribution and use of this software (with or without changes)
|
||||||
|
is allowed without the payment of fees or royalties provided that:
|
||||||
|
|
||||||
|
source code distributions include the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer;
|
||||||
|
|
||||||
|
binary distributions include the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer in their documentation.
|
||||||
|
|
||||||
|
This software is provided 'as is' with no explicit or implied warranties
|
||||||
|
in respect of its operation, including, but not limited to, correctness
|
||||||
|
and fitness for purpose.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Issue Date: 20/12/2007
|
||||||
|
|
||||||
|
This file contains the compilation options for AES (Rijndael) and code
|
||||||
|
that is common across encryption, key scheduling and table generation.
|
||||||
|
|
||||||
|
OPERATION
|
||||||
|
|
||||||
|
These source code files implement the AES algorithm Rijndael designed by
|
||||||
|
Joan Daemen and Vincent Rijmen. This version is designed for the standard
|
||||||
|
block size of 16 bytes and for key sizes of 128, 192 and 256 bits (16, 24
|
||||||
|
and 32 bytes).
|
||||||
|
|
||||||
|
This version is designed for flexibility and speed using operations on
|
||||||
|
32-bit words rather than operations on bytes. It can be compiled with
|
||||||
|
either big or little endian internal byte order but is faster when the
|
||||||
|
native byte order for the processor is used.
|
||||||
|
|
||||||
|
THE CIPHER INTERFACE
|
||||||
|
|
||||||
|
The cipher interface is implemented as an array of bytes in which lower
|
||||||
|
AES bit sequence indexes map to higher numeric significance within bytes.
|
||||||
|
|
||||||
|
uint8_t (an unsigned 8-bit type)
|
||||||
|
uint32_t (an unsigned 32-bit type)
|
||||||
|
struct aes_encrypt_ctx (structure for the cipher encryption context)
|
||||||
|
struct aes_decrypt_ctx (structure for the cipher decryption context)
|
||||||
|
AES_RETURN the function return type
|
||||||
|
|
||||||
|
C subroutine calls:
|
||||||
|
|
||||||
|
AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]);
|
||||||
|
AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]);
|
||||||
|
AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]);
|
||||||
|
AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out,
|
||||||
|
const aes_encrypt_ctx cx[1]);
|
||||||
|
|
||||||
|
AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]);
|
||||||
|
AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]);
|
||||||
|
AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]);
|
||||||
|
AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out,
|
||||||
|
const aes_decrypt_ctx cx[1]);
|
||||||
|
|
||||||
|
IMPORTANT NOTE: If you are using this C interface with dynamic tables make sure that
|
||||||
|
you call aes_init() before AES is used so that the tables are initialised.
|
||||||
|
|
||||||
|
C++ aes class subroutines:
|
||||||
|
|
||||||
|
Class AESencrypt for encryption
|
||||||
|
|
||||||
|
Construtors:
|
||||||
|
AESencrypt(void)
|
||||||
|
AESencrypt(const unsigned char *key) - 128 bit key
|
||||||
|
Members:
|
||||||
|
AES_RETURN key128(const unsigned char *key)
|
||||||
|
AES_RETURN key192(const unsigned char *key)
|
||||||
|
AES_RETURN key256(const unsigned char *key)
|
||||||
|
AES_RETURN encrypt(const unsigned char *in, unsigned char *out) const
|
||||||
|
|
||||||
|
Class AESdecrypt for encryption
|
||||||
|
Construtors:
|
||||||
|
AESdecrypt(void)
|
||||||
|
AESdecrypt(const unsigned char *key) - 128 bit key
|
||||||
|
Members:
|
||||||
|
AES_RETURN key128(const unsigned char *key)
|
||||||
|
AES_RETURN key192(const unsigned char *key)
|
||||||
|
AES_RETURN key256(const unsigned char *key)
|
||||||
|
AES_RETURN decrypt(const unsigned char *in, unsigned char *out) const
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined( _AESOPT_H )
|
||||||
|
#define _AESOPT_H
|
||||||
|
|
||||||
|
#if defined( __cplusplus )
|
||||||
|
#include "aescpp.h"
|
||||||
|
#else
|
||||||
|
#include "aes.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* PLATFORM SPECIFIC INCLUDES */
|
||||||
|
|
||||||
|
#include "brg_endian.h"
|
||||||
|
|
||||||
|
/* CONFIGURATION - THE USE OF DEFINES
|
||||||
|
|
||||||
|
Later in this section there are a number of defines that control the
|
||||||
|
operation of the code. In each section, the purpose of each define is
|
||||||
|
explained so that the relevant form can be included or excluded by
|
||||||
|
setting either 1's or 0's respectively on the branches of the related
|
||||||
|
#if clauses. The following local defines should not be changed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define ENCRYPTION_IN_C 1
|
||||||
|
#define DECRYPTION_IN_C 2
|
||||||
|
#define ENC_KEYING_IN_C 4
|
||||||
|
#define DEC_KEYING_IN_C 8
|
||||||
|
|
||||||
|
#define NO_TABLES 0
|
||||||
|
#define ONE_TABLE 1
|
||||||
|
#define FOUR_TABLES 4
|
||||||
|
#define NONE 0
|
||||||
|
#define PARTIAL 1
|
||||||
|
#define FULL 2
|
||||||
|
|
||||||
|
/* --- START OF USER CONFIGURED OPTIONS --- */
|
||||||
|
|
||||||
|
/* 1. BYTE ORDER WITHIN 32 BIT WORDS
|
||||||
|
|
||||||
|
The fundamental data processing units in Rijndael are 8-bit bytes. The
|
||||||
|
input, output and key input are all enumerated arrays of bytes in which
|
||||||
|
bytes are numbered starting at zero and increasing to one less than the
|
||||||
|
number of bytes in the array in question. This enumeration is only used
|
||||||
|
for naming bytes and does not imply any adjacency or order relationship
|
||||||
|
from one byte to another. When these inputs and outputs are considered
|
||||||
|
as bit sequences, bits 8*n to 8*n+7 of the bit sequence are mapped to
|
||||||
|
byte[n] with bit 8n+i in the sequence mapped to bit 7-i within the byte.
|
||||||
|
In this implementation bits are numbered from 0 to 7 starting at the
|
||||||
|
numerically least significant end of each byte (bit n represents 2^n).
|
||||||
|
|
||||||
|
However, Rijndael can be implemented more efficiently using 32-bit
|
||||||
|
words by packing bytes into words so that bytes 4*n to 4*n+3 are placed
|
||||||
|
into word[n]. While in principle these bytes can be assembled into words
|
||||||
|
in any positions, this implementation only supports the two formats in
|
||||||
|
which bytes in adjacent positions within words also have adjacent byte
|
||||||
|
numbers. This order is called big-endian if the lowest numbered bytes
|
||||||
|
in words have the highest numeric significance and little-endian if the
|
||||||
|
opposite applies.
|
||||||
|
|
||||||
|
This code can work in either order irrespective of the order used by the
|
||||||
|
machine on which it runs. Normally the internal byte order will be set
|
||||||
|
to the order of the processor on which the code is to be run but this
|
||||||
|
define can be used to reverse this in special situations
|
||||||
|
|
||||||
|
WARNING: Assembler code versions rely on PLATFORM_BYTE_ORDER being set.
|
||||||
|
This define will hence be redefined later (in section 4) if necessary
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
# define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER
|
||||||
|
#elif 0
|
||||||
|
# define ALGORITHM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||||
|
#elif 0
|
||||||
|
# define ALGORITHM_BYTE_ORDER IS_BIG_ENDIAN
|
||||||
|
#else
|
||||||
|
# error The algorithm byte order is not defined
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 2. Intel AES AND VIA ACE SUPPORT */
|
||||||
|
|
||||||
|
#if defined( __GNUC__ ) && defined( __i386__ ) \
|
||||||
|
|| defined( _WIN32 ) && defined( _M_IX86 ) && !(defined( _WIN64 ) \
|
||||||
|
|| defined( _WIN32_WCE ) || defined( _MSC_VER ) && ( _MSC_VER <= 800 ))
|
||||||
|
# define VIA_ACE_POSSIBLE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined( _WIN64 ) && defined( _MSC_VER )) \
|
||||||
|
|| (defined( __GNUC__ ) && defined( __x86_64__ )) && !(defined( __APPLE__ ))\
|
||||||
|
&& !(defined( INTEL_AES_POSSIBLE ))
|
||||||
|
# define INTEL_AES_POSSIBLE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Define this option if support for the Intel AESNI is required
|
||||||
|
If USE_INTEL_AES_IF_PRESENT is defined then AESNI will be used
|
||||||
|
if it is detected (both present and enabled).
|
||||||
|
|
||||||
|
AESNI uses a decryption key schedule with the first decryption
|
||||||
|
round key at the high end of the key scedule with the following
|
||||||
|
round keys at lower positions in memory. So AES_REV_DKS must NOT
|
||||||
|
be defined when AESNI will be used. ALthough it is unlikely that
|
||||||
|
assembler code will be used with an AESNI build, if it is then
|
||||||
|
AES_REV_DKS must NOT be defined when the assembler files are
|
||||||
|
built
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if 1 && defined( INTEL_AES_POSSIBLE ) && !defined( USE_INTEL_AES_IF_PRESENT )
|
||||||
|
# define USE_INTEL_AES_IF_PRESENT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Define this option if support for the VIA ACE is required. This uses
|
||||||
|
inline assembler instructions and is only implemented for the Microsoft,
|
||||||
|
Intel and GCC compilers. If VIA ACE is known to be present, then defining
|
||||||
|
ASSUME_VIA_ACE_PRESENT will remove the ordinary encryption/decryption
|
||||||
|
code. If USE_VIA_ACE_IF_PRESENT is defined then VIA ACE will be used if
|
||||||
|
it is detected (both present and enabled) but the normal AES code will
|
||||||
|
also be present.
|
||||||
|
|
||||||
|
When VIA ACE is to be used, all AES encryption contexts MUST be 16 byte
|
||||||
|
aligned; other input/output buffers do not need to be 16 byte aligned
|
||||||
|
but there are very large performance gains if this can be arranged.
|
||||||
|
VIA ACE also requires the decryption key schedule to be in reverse
|
||||||
|
order (which later checks below ensure).
|
||||||
|
|
||||||
|
AES_REV_DKS must be set for assembler code used with a VIA ACE build
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if 0 && defined( VIA_ACE_POSSIBLE ) && !defined( USE_VIA_ACE_IF_PRESENT )
|
||||||
|
# define USE_VIA_ACE_IF_PRESENT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0 && defined( VIA_ACE_POSSIBLE ) && !defined( ASSUME_VIA_ACE_PRESENT )
|
||||||
|
# define ASSUME_VIA_ACE_PRESENT
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/* 3. ASSEMBLER SUPPORT
|
||||||
|
|
||||||
|
This define (which can be on the command line) enables the use of the
|
||||||
|
assembler code routines for encryption, decryption and key scheduling
|
||||||
|
as follows:
|
||||||
|
|
||||||
|
ASM_X86_V1C uses the assembler (aes_x86_v1.asm) with large tables for
|
||||||
|
encryption and decryption and but with key scheduling in C
|
||||||
|
ASM_X86_V2 uses assembler (aes_x86_v2.asm) with compressed tables for
|
||||||
|
encryption, decryption and key scheduling
|
||||||
|
ASM_X86_V2C uses assembler (aes_x86_v2.asm) with compressed tables for
|
||||||
|
encryption and decryption and but with key scheduling in C
|
||||||
|
ASM_AMD64_C uses assembler (aes_amd64.asm) with compressed tables for
|
||||||
|
encryption and decryption and but with key scheduling in C
|
||||||
|
|
||||||
|
Change one 'if 0' below to 'if 1' to select the version or define
|
||||||
|
as a compilation option.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if 0 && !defined( ASM_X86_V1C )
|
||||||
|
# define ASM_X86_V1C
|
||||||
|
#elif 0 && !defined( ASM_X86_V2 )
|
||||||
|
# define ASM_X86_V2
|
||||||
|
#elif 0 && !defined( ASM_X86_V2C )
|
||||||
|
# define ASM_X86_V2C
|
||||||
|
#elif 0 && !defined( ASM_AMD64_C )
|
||||||
|
# define ASM_AMD64_C
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( __i386 ) || defined( _M_IX86 )
|
||||||
|
# define A32_
|
||||||
|
#elif defined( __x86_64__ ) || defined( _M_X64 )
|
||||||
|
# define A64_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined ( ASM_X86_V1C ) || defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )) \
|
||||||
|
&& !defined( A32_ ) || defined( ASM_AMD64_C ) && !defined( A64_ )
|
||||||
|
# error Assembler code is only available for x86 and AMD64 systems
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 4. FAST INPUT/OUTPUT OPERATIONS.
|
||||||
|
|
||||||
|
On some machines it is possible to improve speed by transferring the
|
||||||
|
bytes in the input and output arrays to and from the internal 32-bit
|
||||||
|
variables by addressing these arrays as if they are arrays of 32-bit
|
||||||
|
words. On some machines this will always be possible but there may
|
||||||
|
be a large performance penalty if the byte arrays are not aligned on
|
||||||
|
the normal word boundaries. On other machines this technique will
|
||||||
|
lead to memory access errors when such 32-bit word accesses are not
|
||||||
|
properly aligned. The option SAFE_IO avoids such problems but will
|
||||||
|
often be slower on those machines that support misaligned access
|
||||||
|
(especially so if care is taken to align the input and output byte
|
||||||
|
arrays on 32-bit word boundaries). If SAFE_IO is not defined it is
|
||||||
|
assumed that access to byte arrays as if they are arrays of 32-bit
|
||||||
|
words will not cause problems when such accesses are misaligned.
|
||||||
|
*/
|
||||||
|
#if 1 && !defined( _MSC_VER )
|
||||||
|
# define SAFE_IO
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 5. LOOP UNROLLING
|
||||||
|
|
||||||
|
The code for encryption and decrytpion cycles through a number of rounds
|
||||||
|
that can be implemented either in a loop or by expanding the code into a
|
||||||
|
long sequence of instructions, the latter producing a larger program but
|
||||||
|
one that will often be much faster. The latter is called loop unrolling.
|
||||||
|
There are also potential speed advantages in expanding two iterations in
|
||||||
|
a loop with half the number of iterations, which is called partial loop
|
||||||
|
unrolling. The following options allow partial or full loop unrolling
|
||||||
|
to be set independently for encryption and decryption
|
||||||
|
*/
|
||||||
|
#if 1
|
||||||
|
# define ENC_UNROLL FULL
|
||||||
|
#elif 0
|
||||||
|
# define ENC_UNROLL PARTIAL
|
||||||
|
#else
|
||||||
|
# define ENC_UNROLL NONE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
# define DEC_UNROLL FULL
|
||||||
|
#elif 0
|
||||||
|
# define DEC_UNROLL PARTIAL
|
||||||
|
#else
|
||||||
|
# define DEC_UNROLL NONE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
# define ENC_KS_UNROLL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
# define DEC_KS_UNROLL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 6. FAST FINITE FIELD OPERATIONS
|
||||||
|
|
||||||
|
If this section is included, tables are used to provide faster finite
|
||||||
|
field arithmetic (this has no effect if STATIC_TABLES is defined).
|
||||||
|
*/
|
||||||
|
#if 1
|
||||||
|
# define FF_TABLES
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 7. INTERNAL STATE VARIABLE FORMAT
|
||||||
|
|
||||||
|
The internal state of Rijndael is stored in a number of local 32-bit
|
||||||
|
word varaibles which can be defined either as an array or as individual
|
||||||
|
names variables. Include this section if you want to store these local
|
||||||
|
varaibles in arrays. Otherwise individual local variables will be used.
|
||||||
|
*/
|
||||||
|
#if 1
|
||||||
|
# define ARRAYS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 8. FIXED OR DYNAMIC TABLES
|
||||||
|
|
||||||
|
When this section is included the tables used by the code are compiled
|
||||||
|
statically into the binary file. Otherwise the subroutine aes_init()
|
||||||
|
must be called to compute them before the code is first used.
|
||||||
|
*/
|
||||||
|
#if 1 && !(defined( _MSC_VER ) && ( _MSC_VER <= 800 ))
|
||||||
|
# define STATIC_TABLES
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 9. MASKING OR CASTING FROM LONGER VALUES TO BYTES
|
||||||
|
|
||||||
|
In some systems it is better to mask longer values to extract bytes
|
||||||
|
rather than using a cast. This option allows this choice.
|
||||||
|
*/
|
||||||
|
#if 0
|
||||||
|
# define to_byte(x) ((uint8_t)(x))
|
||||||
|
#else
|
||||||
|
# define to_byte(x) ((x) & 0xff)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 10. TABLE ALIGNMENT
|
||||||
|
|
||||||
|
On some sytsems speed will be improved by aligning the AES large lookup
|
||||||
|
tables on particular boundaries. This define should be set to a power of
|
||||||
|
two giving the desired alignment. It can be left undefined if alignment
|
||||||
|
is not needed. This option is specific to the Microsft VC++ compiler -
|
||||||
|
it seems to sometimes cause trouble for the VC++ version 6 compiler.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if 1 && defined( _MSC_VER ) && ( _MSC_VER >= 1300 )
|
||||||
|
# define TABLE_ALIGN 32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 11. REDUCE CODE AND TABLE SIZE
|
||||||
|
|
||||||
|
This replaces some expanded macros with function calls if AES_ASM_V2 or
|
||||||
|
AES_ASM_V2C are defined
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if 1 && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C ))
|
||||||
|
# define REDUCE_CODE_SIZE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 12. TABLE OPTIONS
|
||||||
|
|
||||||
|
This cipher proceeds by repeating in a number of cycles known as 'rounds'
|
||||||
|
which are implemented by a round function which can optionally be speeded
|
||||||
|
up using tables. The basic tables are each 256 32-bit words, with either
|
||||||
|
one or four tables being required for each round function depending on
|
||||||
|
how much speed is required. The encryption and decryption round functions
|
||||||
|
are different and the last encryption and decrytpion round functions are
|
||||||
|
different again making four different round functions in all.
|
||||||
|
|
||||||
|
This means that:
|
||||||
|
1. Normal encryption and decryption rounds can each use either 0, 1
|
||||||
|
or 4 tables and table spaces of 0, 1024 or 4096 bytes each.
|
||||||
|
2. The last encryption and decryption rounds can also use either 0, 1
|
||||||
|
or 4 tables and table spaces of 0, 1024 or 4096 bytes each.
|
||||||
|
|
||||||
|
Include or exclude the appropriate definitions below to set the number
|
||||||
|
of tables used by this implementation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if 1 /* set tables for the normal encryption round */
|
||||||
|
# define ENC_ROUND FOUR_TABLES
|
||||||
|
#elif 0
|
||||||
|
# define ENC_ROUND ONE_TABLE
|
||||||
|
#else
|
||||||
|
# define ENC_ROUND NO_TABLES
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 1 /* set tables for the last encryption round */
|
||||||
|
# define LAST_ENC_ROUND FOUR_TABLES
|
||||||
|
#elif 0
|
||||||
|
# define LAST_ENC_ROUND ONE_TABLE
|
||||||
|
#else
|
||||||
|
# define LAST_ENC_ROUND NO_TABLES
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 1 /* set tables for the normal decryption round */
|
||||||
|
# define DEC_ROUND FOUR_TABLES
|
||||||
|
#elif 0
|
||||||
|
# define DEC_ROUND ONE_TABLE
|
||||||
|
#else
|
||||||
|
# define DEC_ROUND NO_TABLES
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 1 /* set tables for the last decryption round */
|
||||||
|
# define LAST_DEC_ROUND FOUR_TABLES
|
||||||
|
#elif 0
|
||||||
|
# define LAST_DEC_ROUND ONE_TABLE
|
||||||
|
#else
|
||||||
|
# define LAST_DEC_ROUND NO_TABLES
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The decryption key schedule can be speeded up with tables in the same
|
||||||
|
way that the round functions can. Include or exclude the following
|
||||||
|
defines to set this requirement.
|
||||||
|
*/
|
||||||
|
#if 1
|
||||||
|
# define KEY_SCHED FOUR_TABLES
|
||||||
|
#elif 0
|
||||||
|
# define KEY_SCHED ONE_TABLE
|
||||||
|
#else
|
||||||
|
# define KEY_SCHED NO_TABLES
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ---- END OF USER CONFIGURED OPTIONS ---- */
|
||||||
|
|
||||||
|
/* VIA ACE support is only available for VC++ and GCC */
|
||||||
|
|
||||||
|
#if !defined( _MSC_VER ) && !defined( __GNUC__ )
|
||||||
|
# if defined( ASSUME_VIA_ACE_PRESENT )
|
||||||
|
# undef ASSUME_VIA_ACE_PRESENT
|
||||||
|
# endif
|
||||||
|
# if defined( USE_VIA_ACE_IF_PRESENT )
|
||||||
|
# undef USE_VIA_ACE_IF_PRESENT
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( ASSUME_VIA_ACE_PRESENT ) && !defined( USE_VIA_ACE_IF_PRESENT )
|
||||||
|
# define USE_VIA_ACE_IF_PRESENT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* define to reverse decryption key schedule */
|
||||||
|
#if 1 || defined( USE_VIA_ACE_IF_PRESENT ) && !defined ( AES_REV_DKS )
|
||||||
|
# define AES_REV_DKS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Intel AESNI uses a decryption key schedule in the encryption order */
|
||||||
|
#if defined( USE_INTEL_AES_IF_PRESENT ) && defined ( AES_REV_DKS )
|
||||||
|
# undef AES_REV_DKS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Assembler support requires the use of platform byte order */
|
||||||
|
|
||||||
|
#if ( defined( ASM_X86_V1C ) || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C ) ) \
|
||||||
|
&& (ALGORITHM_BYTE_ORDER != PLATFORM_BYTE_ORDER)
|
||||||
|
# undef ALGORITHM_BYTE_ORDER
|
||||||
|
# define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* In this implementation the columns of the state array are each held in
|
||||||
|
32-bit words. The state array can be held in various ways: in an array
|
||||||
|
of words, in a number of individual word variables or in a number of
|
||||||
|
processor registers. The following define maps a variable name x and
|
||||||
|
a column number c to the way the state array variable is to be held.
|
||||||
|
The first define below maps the state into an array x[c] whereas the
|
||||||
|
second form maps the state into a number of individual variables x0,
|
||||||
|
x1, etc. Another form could map individual state colums to machine
|
||||||
|
register names.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined( ARRAYS )
|
||||||
|
# define s(x,c) x[c]
|
||||||
|
#else
|
||||||
|
# define s(x,c) x##c
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* This implementation provides subroutines for encryption, decryption
|
||||||
|
and for setting the three key lengths (separately) for encryption
|
||||||
|
and decryption. Since not all functions are needed, masks are set
|
||||||
|
up here to determine which will be implemented in C
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined( AES_ENCRYPT )
|
||||||
|
# define EFUNCS_IN_C 0
|
||||||
|
#elif defined( ASSUME_VIA_ACE_PRESENT ) || defined( ASM_X86_V1C ) \
|
||||||
|
|| defined( ASM_X86_V2C ) || defined( ASM_AMD64_C )
|
||||||
|
# define EFUNCS_IN_C ENC_KEYING_IN_C
|
||||||
|
#elif !defined( ASM_X86_V2 )
|
||||||
|
# define EFUNCS_IN_C ( ENCRYPTION_IN_C | ENC_KEYING_IN_C )
|
||||||
|
#else
|
||||||
|
# define EFUNCS_IN_C 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined( AES_DECRYPT )
|
||||||
|
# define DFUNCS_IN_C 0
|
||||||
|
#elif defined( ASSUME_VIA_ACE_PRESENT ) || defined( ASM_X86_V1C ) \
|
||||||
|
|| defined( ASM_X86_V2C ) || defined( ASM_AMD64_C )
|
||||||
|
# define DFUNCS_IN_C DEC_KEYING_IN_C
|
||||||
|
#elif !defined( ASM_X86_V2 )
|
||||||
|
# define DFUNCS_IN_C ( DECRYPTION_IN_C | DEC_KEYING_IN_C )
|
||||||
|
#else
|
||||||
|
# define DFUNCS_IN_C 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define FUNCS_IN_C ( EFUNCS_IN_C | DFUNCS_IN_C )
|
||||||
|
|
||||||
|
/* END OF CONFIGURATION OPTIONS */
|
||||||
|
|
||||||
|
#define RC_LENGTH (5 * (AES_BLOCK_SIZE / 4 - 2))
|
||||||
|
|
||||||
|
/* Disable or report errors on some combinations of options */
|
||||||
|
|
||||||
|
#if ENC_ROUND == NO_TABLES && LAST_ENC_ROUND != NO_TABLES
|
||||||
|
# undef LAST_ENC_ROUND
|
||||||
|
# define LAST_ENC_ROUND NO_TABLES
|
||||||
|
#elif ENC_ROUND == ONE_TABLE && LAST_ENC_ROUND == FOUR_TABLES
|
||||||
|
# undef LAST_ENC_ROUND
|
||||||
|
# define LAST_ENC_ROUND ONE_TABLE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ENC_ROUND == NO_TABLES && ENC_UNROLL != NONE
|
||||||
|
# undef ENC_UNROLL
|
||||||
|
# define ENC_UNROLL NONE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if DEC_ROUND == NO_TABLES && LAST_DEC_ROUND != NO_TABLES
|
||||||
|
# undef LAST_DEC_ROUND
|
||||||
|
# define LAST_DEC_ROUND NO_TABLES
|
||||||
|
#elif DEC_ROUND == ONE_TABLE && LAST_DEC_ROUND == FOUR_TABLES
|
||||||
|
# undef LAST_DEC_ROUND
|
||||||
|
# define LAST_DEC_ROUND ONE_TABLE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if DEC_ROUND == NO_TABLES && DEC_UNROLL != NONE
|
||||||
|
# undef DEC_UNROLL
|
||||||
|
# define DEC_UNROLL NONE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( bswap32 )
|
||||||
|
# define aes_sw32 bswap32
|
||||||
|
#elif defined( bswap_32 )
|
||||||
|
# define aes_sw32 bswap_32
|
||||||
|
#else
|
||||||
|
# define brot(x,n) (((uint32_t)(x) << n) | ((uint32_t)(x) >> (32 - n)))
|
||||||
|
# define aes_sw32(x) ((brot((x),8) & 0x00ff00ff) | (brot((x),24) & 0xff00ff00))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* upr(x,n): rotates bytes within words by n positions, moving bytes to
|
||||||
|
higher index positions with wrap around into low positions
|
||||||
|
ups(x,n): moves bytes by n positions to higher index positions in
|
||||||
|
words but without wrap around
|
||||||
|
bval(x,n): extracts a byte from a word
|
||||||
|
|
||||||
|
WARNING: The definitions given here are intended only for use with
|
||||||
|
unsigned variables and with shift counts that are compile
|
||||||
|
time constants
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if ( ALGORITHM_BYTE_ORDER == IS_LITTLE_ENDIAN )
|
||||||
|
# define upr(x,n) (((uint32_t)(x) << (8 * (n))) | ((uint32_t)(x) >> (32 - 8 * (n))))
|
||||||
|
# define ups(x,n) ((uint32_t) (x) << (8 * (n)))
|
||||||
|
# define bval(x,n) to_byte((x) >> (8 * (n)))
|
||||||
|
# define bytes2word(b0, b1, b2, b3) \
|
||||||
|
(((uint32_t)(b3) << 24) | ((uint32_t)(b2) << 16) | ((uint32_t)(b1) << 8) | (b0))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ( ALGORITHM_BYTE_ORDER == IS_BIG_ENDIAN )
|
||||||
|
# define upr(x,n) (((uint32_t)(x) >> (8 * (n))) | ((uint32_t)(x) << (32 - 8 * (n))))
|
||||||
|
# define ups(x,n) ((uint32_t) (x) >> (8 * (n)))
|
||||||
|
# define bval(x,n) to_byte((x) >> (24 - 8 * (n)))
|
||||||
|
# define bytes2word(b0, b1, b2, b3) \
|
||||||
|
(((uint32_t)(b0) << 24) | ((uint32_t)(b1) << 16) | ((uint32_t)(b2) << 8) | (b3))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( SAFE_IO )
|
||||||
|
# define word_in(x,c) bytes2word(((const uint8_t*)(x)+4*c)[0], ((const uint8_t*)(x)+4*c)[1], \
|
||||||
|
((const uint8_t*)(x)+4*c)[2], ((const uint8_t*)(x)+4*c)[3])
|
||||||
|
# define word_out(x,c,v) { ((uint8_t*)(x)+4*c)[0] = bval(v,0); ((uint8_t*)(x)+4*c)[1] = bval(v,1); \
|
||||||
|
((uint8_t*)(x)+4*c)[2] = bval(v,2); ((uint8_t*)(x)+4*c)[3] = bval(v,3); }
|
||||||
|
#elif ( ALGORITHM_BYTE_ORDER == PLATFORM_BYTE_ORDER )
|
||||||
|
# define word_in(x,c) (*((uint32_t*)(x)+(c)))
|
||||||
|
# define word_out(x,c,v) (*((uint32_t*)(x)+(c)) = (v))
|
||||||
|
#else
|
||||||
|
# define word_in(x,c) aes_sw32(*((uint32_t*)(x)+(c)))
|
||||||
|
# define word_out(x,c,v) (*((uint32_t*)(x)+(c)) = aes_sw32(v))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* the finite field modular polynomial and elements */
|
||||||
|
|
||||||
|
#define WPOLY 0x011b
|
||||||
|
#define BPOLY 0x1b
|
||||||
|
|
||||||
|
/* multiply four bytes in GF(2^8) by 'x' {02} in parallel */
|
||||||
|
|
||||||
|
#define gf_c1 0x80808080
|
||||||
|
#define gf_c2 0x7f7f7f7f
|
||||||
|
#define gf_mulx(x) ((((x) & gf_c2) << 1) ^ ((((x) & gf_c1) >> 7) * BPOLY))
|
||||||
|
|
||||||
|
/* The following defines provide alternative definitions of gf_mulx that might
|
||||||
|
give improved performance if a fast 32-bit multiply is not available. Note
|
||||||
|
that a temporary variable u needs to be defined where gf_mulx is used.
|
||||||
|
|
||||||
|
#define gf_mulx(x) (u = (x) & gf_c1, u |= (u >> 1), ((x) & gf_c2) << 1) ^ ((u >> 3) | (u >> 6))
|
||||||
|
#define gf_c4 (0x01010101 * BPOLY)
|
||||||
|
#define gf_mulx(x) (u = (x) & gf_c1, ((x) & gf_c2) << 1) ^ ((u - (u >> 7)) & gf_c4)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Work out which tables are needed for the different options */
|
||||||
|
|
||||||
|
#if defined( ASM_X86_V1C )
|
||||||
|
# if defined( ENC_ROUND )
|
||||||
|
# undef ENC_ROUND
|
||||||
|
# endif
|
||||||
|
# define ENC_ROUND FOUR_TABLES
|
||||||
|
# if defined( LAST_ENC_ROUND )
|
||||||
|
# undef LAST_ENC_ROUND
|
||||||
|
# endif
|
||||||
|
# define LAST_ENC_ROUND FOUR_TABLES
|
||||||
|
# if defined( DEC_ROUND )
|
||||||
|
# undef DEC_ROUND
|
||||||
|
# endif
|
||||||
|
# define DEC_ROUND FOUR_TABLES
|
||||||
|
# if defined( LAST_DEC_ROUND )
|
||||||
|
# undef LAST_DEC_ROUND
|
||||||
|
# endif
|
||||||
|
# define LAST_DEC_ROUND FOUR_TABLES
|
||||||
|
# if defined( KEY_SCHED )
|
||||||
|
# undef KEY_SCHED
|
||||||
|
# define KEY_SCHED FOUR_TABLES
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ( FUNCS_IN_C & ENCRYPTION_IN_C ) || defined( ASM_X86_V1C )
|
||||||
|
# if ENC_ROUND == ONE_TABLE
|
||||||
|
# define FT1_SET
|
||||||
|
# elif ENC_ROUND == FOUR_TABLES
|
||||||
|
# define FT4_SET
|
||||||
|
# else
|
||||||
|
# define SBX_SET
|
||||||
|
# endif
|
||||||
|
# if LAST_ENC_ROUND == ONE_TABLE
|
||||||
|
# define FL1_SET
|
||||||
|
# elif LAST_ENC_ROUND == FOUR_TABLES
|
||||||
|
# define FL4_SET
|
||||||
|
# elif !defined( SBX_SET )
|
||||||
|
# define SBX_SET
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ( FUNCS_IN_C & DECRYPTION_IN_C ) || defined( ASM_X86_V1C )
|
||||||
|
# if DEC_ROUND == ONE_TABLE
|
||||||
|
# define IT1_SET
|
||||||
|
# elif DEC_ROUND == FOUR_TABLES
|
||||||
|
# define IT4_SET
|
||||||
|
# else
|
||||||
|
# define ISB_SET
|
||||||
|
# endif
|
||||||
|
# if LAST_DEC_ROUND == ONE_TABLE
|
||||||
|
# define IL1_SET
|
||||||
|
# elif LAST_DEC_ROUND == FOUR_TABLES
|
||||||
|
# define IL4_SET
|
||||||
|
# elif !defined(ISB_SET)
|
||||||
|
# define ISB_SET
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !(defined( REDUCE_CODE_SIZE ) && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )))
|
||||||
|
# if ((FUNCS_IN_C & ENC_KEYING_IN_C) || (FUNCS_IN_C & DEC_KEYING_IN_C))
|
||||||
|
# if KEY_SCHED == ONE_TABLE
|
||||||
|
# if !defined( FL1_SET ) && !defined( FL4_SET )
|
||||||
|
# define LS1_SET
|
||||||
|
# endif
|
||||||
|
# elif KEY_SCHED == FOUR_TABLES
|
||||||
|
# if !defined( FL4_SET )
|
||||||
|
# define LS4_SET
|
||||||
|
# endif
|
||||||
|
# elif !defined( SBX_SET )
|
||||||
|
# define SBX_SET
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# if (FUNCS_IN_C & DEC_KEYING_IN_C)
|
||||||
|
# if KEY_SCHED == ONE_TABLE
|
||||||
|
# define IM1_SET
|
||||||
|
# elif KEY_SCHED == FOUR_TABLES
|
||||||
|
# define IM4_SET
|
||||||
|
# elif !defined( SBX_SET )
|
||||||
|
# define SBX_SET
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* generic definitions of Rijndael macros that use tables */
|
||||||
|
|
||||||
|
#define no_table(x,box,vf,rf,c) bytes2word( \
|
||||||
|
box[bval(vf(x,0,c),rf(0,c))], \
|
||||||
|
box[bval(vf(x,1,c),rf(1,c))], \
|
||||||
|
box[bval(vf(x,2,c),rf(2,c))], \
|
||||||
|
box[bval(vf(x,3,c),rf(3,c))])
|
||||||
|
|
||||||
|
#define one_table(x,op,tab,vf,rf,c) \
|
||||||
|
( tab[bval(vf(x,0,c),rf(0,c))] \
|
||||||
|
^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \
|
||||||
|
^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \
|
||||||
|
^ op(tab[bval(vf(x,3,c),rf(3,c))],3))
|
||||||
|
|
||||||
|
#define four_tables(x,tab,vf,rf,c) \
|
||||||
|
( tab[0][bval(vf(x,0,c),rf(0,c))] \
|
||||||
|
^ tab[1][bval(vf(x,1,c),rf(1,c))] \
|
||||||
|
^ tab[2][bval(vf(x,2,c),rf(2,c))] \
|
||||||
|
^ tab[3][bval(vf(x,3,c),rf(3,c))])
|
||||||
|
|
||||||
|
#define vf1(x,r,c) (x)
|
||||||
|
#define rf1(r,c) (r)
|
||||||
|
#define rf2(r,c) ((8+r-c)&3)
|
||||||
|
|
||||||
|
/* perform forward and inverse column mix operation on four bytes in long word x in */
|
||||||
|
/* parallel. NOTE: x must be a simple variable, NOT an expression in these macros. */
|
||||||
|
|
||||||
|
#if !(defined( REDUCE_CODE_SIZE ) && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )))
|
||||||
|
|
||||||
|
#if defined( FM4_SET ) /* not currently used */
|
||||||
|
# define fwd_mcol(x) four_tables(x,t_use(f,m),vf1,rf1,0)
|
||||||
|
#elif defined( FM1_SET ) /* not currently used */
|
||||||
|
# define fwd_mcol(x) one_table(x,upr,t_use(f,m),vf1,rf1,0)
|
||||||
|
#else
|
||||||
|
# define dec_fmvars uint32_t g2
|
||||||
|
# define fwd_mcol(x) (g2 = gf_mulx(x), g2 ^ upr((x) ^ g2, 3) ^ upr((x), 2) ^ upr((x), 1))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( IM4_SET )
|
||||||
|
# define inv_mcol(x) four_tables(x,t_use(i,m),vf1,rf1,0)
|
||||||
|
#elif defined( IM1_SET )
|
||||||
|
# define inv_mcol(x) one_table(x,upr,t_use(i,m),vf1,rf1,0)
|
||||||
|
#else
|
||||||
|
# define dec_imvars uint32_t g2, g4, g9
|
||||||
|
# define inv_mcol(x) (g2 = gf_mulx(x), g4 = gf_mulx(g2), g9 = (x) ^ gf_mulx(g4), g4 ^= g9, \
|
||||||
|
(x) ^ g2 ^ g4 ^ upr(g2 ^ g9, 3) ^ upr(g4, 2) ^ upr(g9, 1))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( FL4_SET )
|
||||||
|
# define ls_box(x,c) four_tables(x,t_use(f,l),vf1,rf2,c)
|
||||||
|
#elif defined( LS4_SET )
|
||||||
|
# define ls_box(x,c) four_tables(x,t_use(l,s),vf1,rf2,c)
|
||||||
|
#elif defined( FL1_SET )
|
||||||
|
# define ls_box(x,c) one_table(x,upr,t_use(f,l),vf1,rf2,c)
|
||||||
|
#elif defined( LS1_SET )
|
||||||
|
# define ls_box(x,c) one_table(x,upr,t_use(l,s),vf1,rf2,c)
|
||||||
|
#else
|
||||||
|
# define ls_box(x,c) no_table(x,t_use(s,box),vf1,rf2,c)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( ASM_X86_V1C ) && defined( AES_DECRYPT ) && !defined( ISB_SET )
|
||||||
|
# define ISB_SET
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
418
SSZipArchive/minizip/aes/aestab.c
Normal file
418
SSZipArchive/minizip/aes/aestab.c
Normal file
@@ -0,0 +1,418 @@
|
|||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||||
|
|
||||||
|
The redistribution and use of this software (with or without changes)
|
||||||
|
is allowed without the payment of fees or royalties provided that:
|
||||||
|
|
||||||
|
source code distributions include the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer;
|
||||||
|
|
||||||
|
binary distributions include the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer in their documentation.
|
||||||
|
|
||||||
|
This software is provided 'as is' with no explicit or implied warranties
|
||||||
|
in respect of its operation, including, but not limited to, correctness
|
||||||
|
and fitness for purpose.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Issue Date: 20/12/2007
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DO_TABLES
|
||||||
|
|
||||||
|
#include "aes.h"
|
||||||
|
#include "aesopt.h"
|
||||||
|
|
||||||
|
#if defined(STATIC_TABLES)
|
||||||
|
|
||||||
|
#define sb_data(w) {\
|
||||||
|
w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\
|
||||||
|
w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\
|
||||||
|
w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\
|
||||||
|
w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\
|
||||||
|
w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\
|
||||||
|
w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\
|
||||||
|
w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\
|
||||||
|
w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\
|
||||||
|
w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\
|
||||||
|
w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\
|
||||||
|
w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\
|
||||||
|
w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\
|
||||||
|
w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\
|
||||||
|
w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\
|
||||||
|
w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\
|
||||||
|
w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\
|
||||||
|
w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\
|
||||||
|
w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\
|
||||||
|
w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\
|
||||||
|
w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\
|
||||||
|
w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\
|
||||||
|
w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\
|
||||||
|
w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\
|
||||||
|
w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\
|
||||||
|
w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\
|
||||||
|
w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\
|
||||||
|
w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\
|
||||||
|
w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\
|
||||||
|
w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\
|
||||||
|
w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\
|
||||||
|
w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\
|
||||||
|
w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16) }
|
||||||
|
|
||||||
|
#define isb_data(w) {\
|
||||||
|
w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38),\
|
||||||
|
w(0xbf), w(0x40), w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb),\
|
||||||
|
w(0x7c), w(0xe3), w(0x39), w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87),\
|
||||||
|
w(0x34), w(0x8e), w(0x43), w(0x44), w(0xc4), w(0xde), w(0xe9), w(0xcb),\
|
||||||
|
w(0x54), w(0x7b), w(0x94), w(0x32), w(0xa6), w(0xc2), w(0x23), w(0x3d),\
|
||||||
|
w(0xee), w(0x4c), w(0x95), w(0x0b), w(0x42), w(0xfa), w(0xc3), w(0x4e),\
|
||||||
|
w(0x08), w(0x2e), w(0xa1), w(0x66), w(0x28), w(0xd9), w(0x24), w(0xb2),\
|
||||||
|
w(0x76), w(0x5b), w(0xa2), w(0x49), w(0x6d), w(0x8b), w(0xd1), w(0x25),\
|
||||||
|
w(0x72), w(0xf8), w(0xf6), w(0x64), w(0x86), w(0x68), w(0x98), w(0x16),\
|
||||||
|
w(0xd4), w(0xa4), w(0x5c), w(0xcc), w(0x5d), w(0x65), w(0xb6), w(0x92),\
|
||||||
|
w(0x6c), w(0x70), w(0x48), w(0x50), w(0xfd), w(0xed), w(0xb9), w(0xda),\
|
||||||
|
w(0x5e), w(0x15), w(0x46), w(0x57), w(0xa7), w(0x8d), w(0x9d), w(0x84),\
|
||||||
|
w(0x90), w(0xd8), w(0xab), w(0x00), w(0x8c), w(0xbc), w(0xd3), w(0x0a),\
|
||||||
|
w(0xf7), w(0xe4), w(0x58), w(0x05), w(0xb8), w(0xb3), w(0x45), w(0x06),\
|
||||||
|
w(0xd0), w(0x2c), w(0x1e), w(0x8f), w(0xca), w(0x3f), w(0x0f), w(0x02),\
|
||||||
|
w(0xc1), w(0xaf), w(0xbd), w(0x03), w(0x01), w(0x13), w(0x8a), w(0x6b),\
|
||||||
|
w(0x3a), w(0x91), w(0x11), w(0x41), w(0x4f), w(0x67), w(0xdc), w(0xea),\
|
||||||
|
w(0x97), w(0xf2), w(0xcf), w(0xce), w(0xf0), w(0xb4), w(0xe6), w(0x73),\
|
||||||
|
w(0x96), w(0xac), w(0x74), w(0x22), w(0xe7), w(0xad), w(0x35), w(0x85),\
|
||||||
|
w(0xe2), w(0xf9), w(0x37), w(0xe8), w(0x1c), w(0x75), w(0xdf), w(0x6e),\
|
||||||
|
w(0x47), w(0xf1), w(0x1a), w(0x71), w(0x1d), w(0x29), w(0xc5), w(0x89),\
|
||||||
|
w(0x6f), w(0xb7), w(0x62), w(0x0e), w(0xaa), w(0x18), w(0xbe), w(0x1b),\
|
||||||
|
w(0xfc), w(0x56), w(0x3e), w(0x4b), w(0xc6), w(0xd2), w(0x79), w(0x20),\
|
||||||
|
w(0x9a), w(0xdb), w(0xc0), w(0xfe), w(0x78), w(0xcd), w(0x5a), w(0xf4),\
|
||||||
|
w(0x1f), w(0xdd), w(0xa8), w(0x33), w(0x88), w(0x07), w(0xc7), w(0x31),\
|
||||||
|
w(0xb1), w(0x12), w(0x10), w(0x59), w(0x27), w(0x80), w(0xec), w(0x5f),\
|
||||||
|
w(0x60), w(0x51), w(0x7f), w(0xa9), w(0x19), w(0xb5), w(0x4a), w(0x0d),\
|
||||||
|
w(0x2d), w(0xe5), w(0x7a), w(0x9f), w(0x93), w(0xc9), w(0x9c), w(0xef),\
|
||||||
|
w(0xa0), w(0xe0), w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0),\
|
||||||
|
w(0xc8), w(0xeb), w(0xbb), w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61),\
|
||||||
|
w(0x17), w(0x2b), w(0x04), w(0x7e), w(0xba), w(0x77), w(0xd6), w(0x26),\
|
||||||
|
w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d) }
|
||||||
|
|
||||||
|
#define mm_data(w) {\
|
||||||
|
w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07),\
|
||||||
|
w(0x08), w(0x09), w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f),\
|
||||||
|
w(0x10), w(0x11), w(0x12), w(0x13), w(0x14), w(0x15), w(0x16), w(0x17),\
|
||||||
|
w(0x18), w(0x19), w(0x1a), w(0x1b), w(0x1c), w(0x1d), w(0x1e), w(0x1f),\
|
||||||
|
w(0x20), w(0x21), w(0x22), w(0x23), w(0x24), w(0x25), w(0x26), w(0x27),\
|
||||||
|
w(0x28), w(0x29), w(0x2a), w(0x2b), w(0x2c), w(0x2d), w(0x2e), w(0x2f),\
|
||||||
|
w(0x30), w(0x31), w(0x32), w(0x33), w(0x34), w(0x35), w(0x36), w(0x37),\
|
||||||
|
w(0x38), w(0x39), w(0x3a), w(0x3b), w(0x3c), w(0x3d), w(0x3e), w(0x3f),\
|
||||||
|
w(0x40), w(0x41), w(0x42), w(0x43), w(0x44), w(0x45), w(0x46), w(0x47),\
|
||||||
|
w(0x48), w(0x49), w(0x4a), w(0x4b), w(0x4c), w(0x4d), w(0x4e), w(0x4f),\
|
||||||
|
w(0x50), w(0x51), w(0x52), w(0x53), w(0x54), w(0x55), w(0x56), w(0x57),\
|
||||||
|
w(0x58), w(0x59), w(0x5a), w(0x5b), w(0x5c), w(0x5d), w(0x5e), w(0x5f),\
|
||||||
|
w(0x60), w(0x61), w(0x62), w(0x63), w(0x64), w(0x65), w(0x66), w(0x67),\
|
||||||
|
w(0x68), w(0x69), w(0x6a), w(0x6b), w(0x6c), w(0x6d), w(0x6e), w(0x6f),\
|
||||||
|
w(0x70), w(0x71), w(0x72), w(0x73), w(0x74), w(0x75), w(0x76), w(0x77),\
|
||||||
|
w(0x78), w(0x79), w(0x7a), w(0x7b), w(0x7c), w(0x7d), w(0x7e), w(0x7f),\
|
||||||
|
w(0x80), w(0x81), w(0x82), w(0x83), w(0x84), w(0x85), w(0x86), w(0x87),\
|
||||||
|
w(0x88), w(0x89), w(0x8a), w(0x8b), w(0x8c), w(0x8d), w(0x8e), w(0x8f),\
|
||||||
|
w(0x90), w(0x91), w(0x92), w(0x93), w(0x94), w(0x95), w(0x96), w(0x97),\
|
||||||
|
w(0x98), w(0x99), w(0x9a), w(0x9b), w(0x9c), w(0x9d), w(0x9e), w(0x9f),\
|
||||||
|
w(0xa0), w(0xa1), w(0xa2), w(0xa3), w(0xa4), w(0xa5), w(0xa6), w(0xa7),\
|
||||||
|
w(0xa8), w(0xa9), w(0xaa), w(0xab), w(0xac), w(0xad), w(0xae), w(0xaf),\
|
||||||
|
w(0xb0), w(0xb1), w(0xb2), w(0xb3), w(0xb4), w(0xb5), w(0xb6), w(0xb7),\
|
||||||
|
w(0xb8), w(0xb9), w(0xba), w(0xbb), w(0xbc), w(0xbd), w(0xbe), w(0xbf),\
|
||||||
|
w(0xc0), w(0xc1), w(0xc2), w(0xc3), w(0xc4), w(0xc5), w(0xc6), w(0xc7),\
|
||||||
|
w(0xc8), w(0xc9), w(0xca), w(0xcb), w(0xcc), w(0xcd), w(0xce), w(0xcf),\
|
||||||
|
w(0xd0), w(0xd1), w(0xd2), w(0xd3), w(0xd4), w(0xd5), w(0xd6), w(0xd7),\
|
||||||
|
w(0xd8), w(0xd9), w(0xda), w(0xdb), w(0xdc), w(0xdd), w(0xde), w(0xdf),\
|
||||||
|
w(0xe0), w(0xe1), w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7),\
|
||||||
|
w(0xe8), w(0xe9), w(0xea), w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef),\
|
||||||
|
w(0xf0), w(0xf1), w(0xf2), w(0xf3), w(0xf4), w(0xf5), w(0xf6), w(0xf7),\
|
||||||
|
w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff) }
|
||||||
|
|
||||||
|
#define rc_data(w) {\
|
||||||
|
w(0x01), w(0x02), w(0x04), w(0x08), w(0x10),w(0x20), w(0x40), w(0x80),\
|
||||||
|
w(0x1b), w(0x36) }
|
||||||
|
|
||||||
|
#define h0(x) (x)
|
||||||
|
|
||||||
|
#define w0(p) bytes2word(p, 0, 0, 0)
|
||||||
|
#define w1(p) bytes2word(0, p, 0, 0)
|
||||||
|
#define w2(p) bytes2word(0, 0, p, 0)
|
||||||
|
#define w3(p) bytes2word(0, 0, 0, p)
|
||||||
|
|
||||||
|
#define u0(p) bytes2word(f2(p), p, p, f3(p))
|
||||||
|
#define u1(p) bytes2word(f3(p), f2(p), p, p)
|
||||||
|
#define u2(p) bytes2word(p, f3(p), f2(p), p)
|
||||||
|
#define u3(p) bytes2word(p, p, f3(p), f2(p))
|
||||||
|
|
||||||
|
#define v0(p) bytes2word(fe(p), f9(p), fd(p), fb(p))
|
||||||
|
#define v1(p) bytes2word(fb(p), fe(p), f9(p), fd(p))
|
||||||
|
#define v2(p) bytes2word(fd(p), fb(p), fe(p), f9(p))
|
||||||
|
#define v3(p) bytes2word(f9(p), fd(p), fb(p), fe(p))
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(STATIC_TABLES) || !defined(FF_TABLES)
|
||||||
|
|
||||||
|
#define f2(x) ((x<<1) ^ (((x>>7) & 1) * WPOLY))
|
||||||
|
#define f4(x) ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY))
|
||||||
|
#define f8(x) ((x<<3) ^ (((x>>5) & 1) * WPOLY) ^ (((x>>5) & 2) * WPOLY) \
|
||||||
|
^ (((x>>5) & 4) * WPOLY))
|
||||||
|
#define f3(x) (f2(x) ^ x)
|
||||||
|
#define f9(x) (f8(x) ^ x)
|
||||||
|
#define fb(x) (f8(x) ^ f2(x) ^ x)
|
||||||
|
#define fd(x) (f8(x) ^ f4(x) ^ x)
|
||||||
|
#define fe(x) (f8(x) ^ f4(x) ^ f2(x))
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define f2(x) ((x) ? pow[log[x] + 0x19] : 0)
|
||||||
|
#define f3(x) ((x) ? pow[log[x] + 0x01] : 0)
|
||||||
|
#define f9(x) ((x) ? pow[log[x] + 0xc7] : 0)
|
||||||
|
#define fb(x) ((x) ? pow[log[x] + 0x68] : 0)
|
||||||
|
#define fd(x) ((x) ? pow[log[x] + 0xee] : 0)
|
||||||
|
#define fe(x) ((x) ? pow[log[x] + 0xdf] : 0)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "aestab.h"
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(STATIC_TABLES)
|
||||||
|
|
||||||
|
/* implemented in case of wrong call for fixed tables */
|
||||||
|
|
||||||
|
AES_RETURN aes_init(void)
|
||||||
|
{
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* Generate the tables for the dynamic table option */
|
||||||
|
|
||||||
|
#if defined(FF_TABLES)
|
||||||
|
|
||||||
|
#define gf_inv(x) ((x) ? pow[ 255 - log[x]] : 0)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* It will generally be sensible to use tables to compute finite
|
||||||
|
field multiplies and inverses but where memory is scarse this
|
||||||
|
code might sometimes be better. But it only has effect during
|
||||||
|
initialisation so its pretty unimportant in overall terms.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* return 2 ^ (n - 1) where n is the bit number of the highest bit
|
||||||
|
set in x with x in the range 1 < x < 0x00000200. This form is
|
||||||
|
used so that locals within fi can be bytes rather than words
|
||||||
|
*/
|
||||||
|
|
||||||
|
static uint8_t hibit(const uint32_t x)
|
||||||
|
{ uint8_t r = (uint8_t)((x >> 1) | (x >> 2));
|
||||||
|
|
||||||
|
r |= (r >> 2);
|
||||||
|
r |= (r >> 4);
|
||||||
|
return (r + 1) >> 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return the inverse of the finite field element x */
|
||||||
|
|
||||||
|
static uint8_t gf_inv(const uint8_t x)
|
||||||
|
{ uint8_t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
|
||||||
|
|
||||||
|
if(x < 2)
|
||||||
|
return x;
|
||||||
|
|
||||||
|
for( ; ; )
|
||||||
|
{
|
||||||
|
if(n1)
|
||||||
|
while(n2 >= n1) /* divide polynomial p2 by p1 */
|
||||||
|
{
|
||||||
|
n2 /= n1; /* shift smaller polynomial left */
|
||||||
|
p2 ^= (p1 * n2) & 0xff; /* and remove from larger one */
|
||||||
|
v2 ^= v1 * n2; /* shift accumulated value and */
|
||||||
|
n2 = hibit(p2); /* add into result */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return v1;
|
||||||
|
|
||||||
|
if(n2) /* repeat with values swapped */
|
||||||
|
while(n1 >= n2)
|
||||||
|
{
|
||||||
|
n1 /= n2;
|
||||||
|
p1 ^= p2 * n1;
|
||||||
|
v1 ^= v2 * n1;
|
||||||
|
n1 = hibit(p1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return v2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The forward and inverse affine transformations used in the S-box */
|
||||||
|
uint8_t fwd_affine(const uint8_t x)
|
||||||
|
{ uint32_t w = x;
|
||||||
|
w ^= (w << 1) ^ (w << 2) ^ (w << 3) ^ (w << 4);
|
||||||
|
return 0x63 ^ ((w ^ (w >> 8)) & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t inv_affine(const uint8_t x)
|
||||||
|
{ uint32_t w = x;
|
||||||
|
w = (w << 1) ^ (w << 3) ^ (w << 6);
|
||||||
|
return 0x05 ^ ((w ^ (w >> 8)) & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int init = 0;
|
||||||
|
|
||||||
|
AES_RETURN aes_init(void)
|
||||||
|
{ uint32_t i, w;
|
||||||
|
|
||||||
|
#if defined(FF_TABLES)
|
||||||
|
|
||||||
|
uint8_t pow[512], log[256];
|
||||||
|
|
||||||
|
if(init)
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
/* log and power tables for GF(2^8) finite field with
|
||||||
|
WPOLY as modular polynomial - the simplest primitive
|
||||||
|
root is 0x03, used here to generate the tables
|
||||||
|
*/
|
||||||
|
|
||||||
|
i = 0; w = 1;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
pow[i] = (uint8_t)w;
|
||||||
|
pow[i + 255] = (uint8_t)w;
|
||||||
|
log[w] = (uint8_t)i++;
|
||||||
|
w ^= (w << 1) ^ (w & 0x80 ? WPOLY : 0);
|
||||||
|
}
|
||||||
|
while (w != 1);
|
||||||
|
|
||||||
|
#else
|
||||||
|
if(init)
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for(i = 0, w = 1; i < RC_LENGTH; ++i)
|
||||||
|
{
|
||||||
|
t_set(r,c)[i] = bytes2word(w, 0, 0, 0);
|
||||||
|
w = f2(w);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < 256; ++i)
|
||||||
|
{ uint8_t b;
|
||||||
|
|
||||||
|
b = fwd_affine(gf_inv((uint8_t)i));
|
||||||
|
w = bytes2word(f2(b), b, b, f3(b));
|
||||||
|
|
||||||
|
#if defined( SBX_SET )
|
||||||
|
t_set(s,box)[i] = b;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( FT1_SET ) /* tables for a normal encryption round */
|
||||||
|
t_set(f,n)[i] = w;
|
||||||
|
#endif
|
||||||
|
#if defined( FT4_SET )
|
||||||
|
t_set(f,n)[0][i] = w;
|
||||||
|
t_set(f,n)[1][i] = upr(w,1);
|
||||||
|
t_set(f,n)[2][i] = upr(w,2);
|
||||||
|
t_set(f,n)[3][i] = upr(w,3);
|
||||||
|
#endif
|
||||||
|
w = bytes2word(b, 0, 0, 0);
|
||||||
|
|
||||||
|
#if defined( FL1_SET ) /* tables for last encryption round (may also */
|
||||||
|
t_set(f,l)[i] = w; /* be used in the key schedule) */
|
||||||
|
#endif
|
||||||
|
#if defined( FL4_SET )
|
||||||
|
t_set(f,l)[0][i] = w;
|
||||||
|
t_set(f,l)[1][i] = upr(w,1);
|
||||||
|
t_set(f,l)[2][i] = upr(w,2);
|
||||||
|
t_set(f,l)[3][i] = upr(w,3);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( LS1_SET ) /* table for key schedule if t_set(f,l) above is*/
|
||||||
|
t_set(l,s)[i] = w; /* not of the required form */
|
||||||
|
#endif
|
||||||
|
#if defined( LS4_SET )
|
||||||
|
t_set(l,s)[0][i] = w;
|
||||||
|
t_set(l,s)[1][i] = upr(w,1);
|
||||||
|
t_set(l,s)[2][i] = upr(w,2);
|
||||||
|
t_set(l,s)[3][i] = upr(w,3);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
b = gf_inv(inv_affine((uint8_t)i));
|
||||||
|
w = bytes2word(fe(b), f9(b), fd(b), fb(b));
|
||||||
|
|
||||||
|
#if defined( IM1_SET ) /* tables for the inverse mix column operation */
|
||||||
|
t_set(i,m)[b] = w;
|
||||||
|
#endif
|
||||||
|
#if defined( IM4_SET )
|
||||||
|
t_set(i,m)[0][b] = w;
|
||||||
|
t_set(i,m)[1][b] = upr(w,1);
|
||||||
|
t_set(i,m)[2][b] = upr(w,2);
|
||||||
|
t_set(i,m)[3][b] = upr(w,3);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( ISB_SET )
|
||||||
|
t_set(i,box)[i] = b;
|
||||||
|
#endif
|
||||||
|
#if defined( IT1_SET ) /* tables for a normal decryption round */
|
||||||
|
t_set(i,n)[i] = w;
|
||||||
|
#endif
|
||||||
|
#if defined( IT4_SET )
|
||||||
|
t_set(i,n)[0][i] = w;
|
||||||
|
t_set(i,n)[1][i] = upr(w,1);
|
||||||
|
t_set(i,n)[2][i] = upr(w,2);
|
||||||
|
t_set(i,n)[3][i] = upr(w,3);
|
||||||
|
#endif
|
||||||
|
w = bytes2word(b, 0, 0, 0);
|
||||||
|
#if defined( IL1_SET ) /* tables for last decryption round */
|
||||||
|
t_set(i,l)[i] = w;
|
||||||
|
#endif
|
||||||
|
#if defined( IL4_SET )
|
||||||
|
t_set(i,l)[0][i] = w;
|
||||||
|
t_set(i,l)[1][i] = upr(w,1);
|
||||||
|
t_set(i,l)[2][i] = upr(w,2);
|
||||||
|
t_set(i,l)[3][i] = upr(w,3);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
init = 1;
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Automatic code initialisation (suggested by by Henrik S. Gaßmann)
|
||||||
|
based on code provided by Joe Lowe and placed in the public domain at:
|
||||||
|
http://stackoverflow.com/questions/1113409/attribute-constructor-equivalent-in-vc
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
|
#pragma section(".CRT$XCU", read)
|
||||||
|
|
||||||
|
__declspec(allocate(".CRT$XCU")) void (__cdecl *aes_startup)(void) = aes_init;
|
||||||
|
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
|
||||||
|
static void aes_startup(void) __attribute__((constructor));
|
||||||
|
|
||||||
|
static void aes_startup(void)
|
||||||
|
{
|
||||||
|
aes_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#pragma message( "dynamic tables must be initialised manually on your system" )
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
173
SSZipArchive/minizip/aes/aestab.h
Normal file
173
SSZipArchive/minizip/aes/aestab.h
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||||
|
|
||||||
|
The redistribution and use of this software (with or without changes)
|
||||||
|
is allowed without the payment of fees or royalties provided that:
|
||||||
|
|
||||||
|
source code distributions include the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer;
|
||||||
|
|
||||||
|
binary distributions include the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer in their documentation.
|
||||||
|
|
||||||
|
This software is provided 'as is' with no explicit or implied warranties
|
||||||
|
in respect of its operation, including, but not limited to, correctness
|
||||||
|
and fitness for purpose.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Issue Date: 20/12/2007
|
||||||
|
|
||||||
|
This file contains the code for declaring the tables needed to implement
|
||||||
|
AES. The file aesopt.h is assumed to be included before this header file.
|
||||||
|
If there are no global variables, the definitions here can be used to put
|
||||||
|
the AES tables in a structure so that a pointer can then be added to the
|
||||||
|
AES context to pass them to the AES routines that need them. If this
|
||||||
|
facility is used, the calling program has to ensure that this pointer is
|
||||||
|
managed appropriately. In particular, the value of the t_dec(in,it) item
|
||||||
|
in the table structure must be set to zero in order to ensure that the
|
||||||
|
tables are initialised. In practice the three code sequences in aeskey.c
|
||||||
|
that control the calls to aes_init() and the aes_init() routine itself will
|
||||||
|
have to be changed for a specific implementation. If global variables are
|
||||||
|
available it will generally be preferable to use them with the precomputed
|
||||||
|
STATIC_TABLES option that uses static global tables.
|
||||||
|
|
||||||
|
The following defines can be used to control the way the tables
|
||||||
|
are defined, initialised and used in embedded environments that
|
||||||
|
require special features for these purposes
|
||||||
|
|
||||||
|
the 't_dec' construction is used to declare fixed table arrays
|
||||||
|
the 't_set' construction is used to set fixed table values
|
||||||
|
the 't_use' construction is used to access fixed table values
|
||||||
|
|
||||||
|
256 byte tables:
|
||||||
|
|
||||||
|
t_xxx(s,box) => forward S box
|
||||||
|
t_xxx(i,box) => inverse S box
|
||||||
|
|
||||||
|
256 32-bit word OR 4 x 256 32-bit word tables:
|
||||||
|
|
||||||
|
t_xxx(f,n) => forward normal round
|
||||||
|
t_xxx(f,l) => forward last round
|
||||||
|
t_xxx(i,n) => inverse normal round
|
||||||
|
t_xxx(i,l) => inverse last round
|
||||||
|
t_xxx(l,s) => key schedule table
|
||||||
|
t_xxx(i,m) => key schedule table
|
||||||
|
|
||||||
|
Other variables and tables:
|
||||||
|
|
||||||
|
t_xxx(r,c) => the rcon table
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined( _AESTAB_H )
|
||||||
|
#define _AESTAB_H
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define t_dec(m,n) t_##m##n
|
||||||
|
#define t_set(m,n) t_##m##n
|
||||||
|
#define t_use(m,n) t_##m##n
|
||||||
|
|
||||||
|
#if defined(STATIC_TABLES)
|
||||||
|
# if !defined( __GNUC__ ) && (defined( __MSDOS__ ) || defined( __WIN16__ ))
|
||||||
|
/* make tables far data to avoid using too much DGROUP space (PG) */
|
||||||
|
# define CONST const far
|
||||||
|
# else
|
||||||
|
# define CONST const
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define CONST
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(DO_TABLES)
|
||||||
|
# define EXTERN
|
||||||
|
#else
|
||||||
|
# define EXTERN extern
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && defined(TABLE_ALIGN)
|
||||||
|
#define ALIGN __declspec(align(TABLE_ALIGN))
|
||||||
|
#else
|
||||||
|
#define ALIGN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( __WATCOMC__ ) && ( __WATCOMC__ >= 1100 )
|
||||||
|
# define XP_DIR __cdecl
|
||||||
|
#else
|
||||||
|
# define XP_DIR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(DO_TABLES) && defined(STATIC_TABLES)
|
||||||
|
#define d_1(t,n,b,e) EXTERN ALIGN CONST XP_DIR t n[256] = b(e)
|
||||||
|
#define d_4(t,n,b,e,f,g,h) EXTERN ALIGN CONST XP_DIR t n[4][256] = { b(e), b(f), b(g), b(h) }
|
||||||
|
EXTERN ALIGN CONST uint32_t t_dec(r,c)[RC_LENGTH] = rc_data(w0);
|
||||||
|
#else
|
||||||
|
#define d_1(t,n,b,e) EXTERN ALIGN CONST XP_DIR t n[256]
|
||||||
|
#define d_4(t,n,b,e,f,g,h) EXTERN ALIGN CONST XP_DIR t n[4][256]
|
||||||
|
EXTERN ALIGN CONST uint32_t t_dec(r,c)[RC_LENGTH];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( SBX_SET )
|
||||||
|
d_1(uint8_t, t_dec(s,box), sb_data, h0);
|
||||||
|
#endif
|
||||||
|
#if defined( ISB_SET )
|
||||||
|
d_1(uint8_t, t_dec(i,box), isb_data, h0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( FT1_SET )
|
||||||
|
d_1(uint32_t, t_dec(f,n), sb_data, u0);
|
||||||
|
#endif
|
||||||
|
#if defined( FT4_SET )
|
||||||
|
d_4(uint32_t, t_dec(f,n), sb_data, u0, u1, u2, u3);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( FL1_SET )
|
||||||
|
d_1(uint32_t, t_dec(f,l), sb_data, w0);
|
||||||
|
#endif
|
||||||
|
#if defined( FL4_SET )
|
||||||
|
d_4(uint32_t, t_dec(f,l), sb_data, w0, w1, w2, w3);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( IT1_SET )
|
||||||
|
d_1(uint32_t, t_dec(i,n), isb_data, v0);
|
||||||
|
#endif
|
||||||
|
#if defined( IT4_SET )
|
||||||
|
d_4(uint32_t, t_dec(i,n), isb_data, v0, v1, v2, v3);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( IL1_SET )
|
||||||
|
d_1(uint32_t, t_dec(i,l), isb_data, w0);
|
||||||
|
#endif
|
||||||
|
#if defined( IL4_SET )
|
||||||
|
d_4(uint32_t, t_dec(i,l), isb_data, w0, w1, w2, w3);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( LS1_SET )
|
||||||
|
#if defined( FL1_SET )
|
||||||
|
#undef LS1_SET
|
||||||
|
#else
|
||||||
|
d_1(uint32_t, t_dec(l,s), sb_data, w0);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( LS4_SET )
|
||||||
|
#if defined( FL4_SET )
|
||||||
|
#undef LS4_SET
|
||||||
|
#else
|
||||||
|
d_4(uint32_t, t_dec(l,s), sb_data, w0, w1, w2, w3);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( IM1_SET )
|
||||||
|
d_1(uint32_t, t_dec(i,m), mm_data, v0);
|
||||||
|
#endif
|
||||||
|
#if defined( IM4_SET )
|
||||||
|
d_4(uint32_t, t_dec(i,m), mm_data, v0, v1, v2, v3);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
127
SSZipArchive/minizip/aes/brg_endian.h
Normal file
127
SSZipArchive/minizip/aes/brg_endian.h
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||||
|
|
||||||
|
The redistribution and use of this software (with or without changes)
|
||||||
|
is allowed without the payment of fees or royalties provided that:
|
||||||
|
|
||||||
|
source code distributions include the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer;
|
||||||
|
|
||||||
|
binary distributions include the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer in their documentation.
|
||||||
|
|
||||||
|
This software is provided 'as is' with no explicit or implied warranties
|
||||||
|
in respect of its operation, including, but not limited to, correctness
|
||||||
|
and fitness for purpose.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Issue Date: 20/12/2007
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _BRG_ENDIAN_H
|
||||||
|
#define _BRG_ENDIAN_H
|
||||||
|
|
||||||
|
#define IS_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */
|
||||||
|
#define IS_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */
|
||||||
|
|
||||||
|
/* Include files where endian defines and byteswap functions may reside */
|
||||||
|
#if defined( __sun )
|
||||||
|
# include <sys/isa_defs.h>
|
||||||
|
#elif defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ )
|
||||||
|
# include <sys/endian.h>
|
||||||
|
#elif defined( BSD ) && ( BSD >= 199103 ) || defined( __APPLE__ ) || \
|
||||||
|
defined( __CYGWIN32__ ) || defined( __DJGPP__ ) || defined( __osf__ ) || \
|
||||||
|
defined(__pnacl__)
|
||||||
|
# include <machine/endian.h>
|
||||||
|
#elif defined( __linux__ ) || defined( __GNUC__ ) || defined( __GNU_LIBRARY__ )
|
||||||
|
# if !defined( __MINGW32__ ) && !defined( _AIX )
|
||||||
|
# include <endian.h>
|
||||||
|
# if !defined( __BEOS__ )
|
||||||
|
# include <byteswap.h>
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Now attempt to set the define for platform byte order using any */
|
||||||
|
/* of the four forms SYMBOL, _SYMBOL, __SYMBOL & __SYMBOL__, which */
|
||||||
|
/* seem to encompass most endian symbol definitions */
|
||||||
|
|
||||||
|
#if defined( BIG_ENDIAN ) && defined( LITTLE_ENDIAN )
|
||||||
|
# if defined( BYTE_ORDER ) && BYTE_ORDER == BIG_ENDIAN
|
||||||
|
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||||
|
# elif defined( BYTE_ORDER ) && BYTE_ORDER == LITTLE_ENDIAN
|
||||||
|
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||||
|
# endif
|
||||||
|
#elif defined( BIG_ENDIAN )
|
||||||
|
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||||
|
#elif defined( LITTLE_ENDIAN )
|
||||||
|
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( _BIG_ENDIAN ) && defined( _LITTLE_ENDIAN )
|
||||||
|
# if defined( _BYTE_ORDER ) && _BYTE_ORDER == _BIG_ENDIAN
|
||||||
|
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||||
|
# elif defined( _BYTE_ORDER ) && _BYTE_ORDER == _LITTLE_ENDIAN
|
||||||
|
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||||
|
# endif
|
||||||
|
#elif defined( _BIG_ENDIAN )
|
||||||
|
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||||
|
#elif defined( _LITTLE_ENDIAN )
|
||||||
|
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( __BIG_ENDIAN ) && defined( __LITTLE_ENDIAN )
|
||||||
|
# if defined( __BYTE_ORDER ) && __BYTE_ORDER == __BIG_ENDIAN
|
||||||
|
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||||
|
# elif defined( __BYTE_ORDER ) && __BYTE_ORDER == __LITTLE_ENDIAN
|
||||||
|
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||||
|
# endif
|
||||||
|
#elif defined( __BIG_ENDIAN )
|
||||||
|
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||||
|
#elif defined( __LITTLE_ENDIAN )
|
||||||
|
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( __BIG_ENDIAN__ ) && defined( __LITTLE_ENDIAN__ )
|
||||||
|
# if defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __BIG_ENDIAN__
|
||||||
|
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||||
|
# elif defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __LITTLE_ENDIAN__
|
||||||
|
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||||
|
# endif
|
||||||
|
#elif defined( __BIG_ENDIAN__ )
|
||||||
|
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||||
|
#elif defined( __LITTLE_ENDIAN__ )
|
||||||
|
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* if the platform byte order could not be determined, then try to */
|
||||||
|
/* set this define using common machine defines */
|
||||||
|
#if !defined(PLATFORM_BYTE_ORDER)
|
||||||
|
|
||||||
|
#if defined( __alpha__ ) || defined( __alpha ) || defined( i386 ) || \
|
||||||
|
defined( __i386__ ) || defined( _M_I86 ) || defined( _M_IX86 ) || \
|
||||||
|
defined( __OS2__ ) || defined( sun386 ) || defined( __TURBOC__ ) || \
|
||||||
|
defined( vax ) || defined( vms ) || defined( VMS ) || \
|
||||||
|
defined( __VMS ) || defined( _M_X64 )
|
||||||
|
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||||
|
|
||||||
|
#elif defined( AMIGA ) || defined( applec ) || defined( __AS400__ ) || \
|
||||||
|
defined( _CRAY ) || defined( __hppa ) || defined( __hp9000 ) || \
|
||||||
|
defined( ibm370 ) || defined( mc68000 ) || defined( m68k ) || \
|
||||||
|
defined( __MRC__ ) || defined( __MVS__ ) || defined( __MWERKS__ ) || \
|
||||||
|
defined( sparc ) || defined( __sparc) || defined( SYMANTEC_C ) || \
|
||||||
|
defined( __VOS__ ) || defined( __TIGCC__ ) || defined( __TANDEM ) || \
|
||||||
|
defined( THINK_C ) || defined( __VMCMS__ ) || defined( _AIX )
|
||||||
|
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||||
|
|
||||||
|
#elif 0 /* **** EDIT HERE IF NECESSARY **** */
|
||||||
|
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||||
|
#elif 0 /* **** EDIT HERE IF NECESSARY **** */
|
||||||
|
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||||
|
#else
|
||||||
|
# error Please edit lines 126 or 128 in brg_endian.h to set the platform byte order
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
191
SSZipArchive/minizip/aes/brg_types.h
Normal file
191
SSZipArchive/minizip/aes/brg_types.h
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||||
|
|
||||||
|
The redistribution and use of this software (with or without changes)
|
||||||
|
is allowed without the payment of fees or royalties provided that:
|
||||||
|
|
||||||
|
source code distributions include the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer;
|
||||||
|
|
||||||
|
binary distributions include the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer in their documentation.
|
||||||
|
|
||||||
|
This software is provided 'as is' with no explicit or implied warranties
|
||||||
|
in respect of its operation, including, but not limited to, correctness
|
||||||
|
and fitness for purpose.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Issue Date: 20/12/2007
|
||||||
|
|
||||||
|
The unsigned integer types defined here are of the form uint_<nn>t where
|
||||||
|
<nn> is the length of the type; for example, the unsigned 32-bit type is
|
||||||
|
'uint32_t'. These are NOT the same as the 'C99 integer types' that are
|
||||||
|
defined in the inttypes.h and stdint.h headers since attempts to use these
|
||||||
|
types have shown that support for them is still highly variable. However,
|
||||||
|
since the latter are of the form uint<nn>_t, a regular expression search
|
||||||
|
and replace (in VC++ search on 'uint_{:z}t' and replace with 'uint\1_t')
|
||||||
|
can be used to convert the types used here to the C99 standard types.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _BRG_TYPES_H
|
||||||
|
#define _BRG_TYPES_H
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#if defined( _MSC_VER ) && ( _MSC_VER >= 1300 )
|
||||||
|
# include <stddef.h>
|
||||||
|
# define ptrint_t intptr_t
|
||||||
|
#elif defined( __ECOS__ )
|
||||||
|
# define intptr_t unsigned int
|
||||||
|
# define ptrint_t intptr_t
|
||||||
|
#elif defined( __GNUC__ ) && ( __GNUC__ >= 3 )
|
||||||
|
# define ptrint_t intptr_t
|
||||||
|
#else
|
||||||
|
# define ptrint_t int
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BRG_UI32
|
||||||
|
# define BRG_UI32
|
||||||
|
# if UINT_MAX == 4294967295u
|
||||||
|
# define li_32(h) 0x##h##u
|
||||||
|
# elif ULONG_MAX == 4294967295u
|
||||||
|
# define li_32(h) 0x##h##ul
|
||||||
|
# elif defined( _CRAY )
|
||||||
|
# error This code needs 32-bit data types, which Cray machines do not provide
|
||||||
|
# else
|
||||||
|
# error Please define uint32_t as a 32-bit unsigned integer type in brg_types.h
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BRG_UI64
|
||||||
|
# if defined( __BORLANDC__ ) && !defined( __MSDOS__ )
|
||||||
|
# define BRG_UI64
|
||||||
|
# define li_64(h) 0x##h##ui64
|
||||||
|
# elif defined( _MSC_VER ) && ( _MSC_VER < 1300 ) /* 1300 == VC++ 7.0 */
|
||||||
|
# define BRG_UI64
|
||||||
|
# define li_64(h) 0x##h##ui64
|
||||||
|
# elif defined( __sun ) && defined( ULONG_MAX ) && ULONG_MAX == 0xfffffffful
|
||||||
|
# define BRG_UI64
|
||||||
|
# define li_64(h) 0x##h##ull
|
||||||
|
# elif defined( __MVS__ )
|
||||||
|
# define BRG_UI64
|
||||||
|
# define li_64(h) 0x##h##ull
|
||||||
|
# elif defined( UINT_MAX ) && UINT_MAX > 4294967295u
|
||||||
|
# if UINT_MAX == 18446744073709551615u
|
||||||
|
# define BRG_UI64
|
||||||
|
# define li_64(h) 0x##h##u
|
||||||
|
# endif
|
||||||
|
# elif defined( ULONG_MAX ) && ULONG_MAX > 4294967295u
|
||||||
|
# if ULONG_MAX == 18446744073709551615ul
|
||||||
|
# define BRG_UI64
|
||||||
|
# define li_64(h) 0x##h##ul
|
||||||
|
# endif
|
||||||
|
# elif defined( ULLONG_MAX ) && ULLONG_MAX > 4294967295u
|
||||||
|
# if ULLONG_MAX == 18446744073709551615ull
|
||||||
|
# define BRG_UI64
|
||||||
|
# define li_64(h) 0x##h##ull
|
||||||
|
# endif
|
||||||
|
# elif defined( ULONG_LONG_MAX ) && ULONG_LONG_MAX > 4294967295u
|
||||||
|
# if ULONG_LONG_MAX == 18446744073709551615ull
|
||||||
|
# define BRG_UI64
|
||||||
|
# define li_64(h) 0x##h##ull
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined( BRG_UI64 )
|
||||||
|
# if defined( NEED_UINT_64T )
|
||||||
|
# error Please define uint64_t as an unsigned 64 bit type in brg_types.h
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RETURN_VALUES
|
||||||
|
# define RETURN_VALUES
|
||||||
|
# if defined( DLL_EXPORT )
|
||||||
|
# if defined( _MSC_VER ) || defined ( __INTEL_COMPILER )
|
||||||
|
# define VOID_RETURN __declspec( dllexport ) void __stdcall
|
||||||
|
# define INT_RETURN __declspec( dllexport ) int __stdcall
|
||||||
|
# elif defined( __GNUC__ )
|
||||||
|
# define VOID_RETURN __declspec( __dllexport__ ) void
|
||||||
|
# define INT_RETURN __declspec( __dllexport__ ) int
|
||||||
|
# else
|
||||||
|
# error Use of the DLL is only available on the Microsoft, Intel and GCC compilers
|
||||||
|
# endif
|
||||||
|
# elif defined( DLL_IMPORT )
|
||||||
|
# if defined( _MSC_VER ) || defined ( __INTEL_COMPILER )
|
||||||
|
# define VOID_RETURN __declspec( dllimport ) void __stdcall
|
||||||
|
# define INT_RETURN __declspec( dllimport ) int __stdcall
|
||||||
|
# elif defined( __GNUC__ )
|
||||||
|
# define VOID_RETURN __declspec( __dllimport__ ) void
|
||||||
|
# define INT_RETURN __declspec( __dllimport__ ) int
|
||||||
|
# else
|
||||||
|
# error Use of the DLL is only available on the Microsoft, Intel and GCC compilers
|
||||||
|
# endif
|
||||||
|
# elif defined( __WATCOMC__ )
|
||||||
|
# define VOID_RETURN void __cdecl
|
||||||
|
# define INT_RETURN int __cdecl
|
||||||
|
# else
|
||||||
|
# define VOID_RETURN void
|
||||||
|
# define INT_RETURN int
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* These defines are used to detect and set the memory alignment of pointers.
|
||||||
|
Note that offsets are in bytes.
|
||||||
|
|
||||||
|
ALIGN_OFFSET(x,n) return the positive or zero offset of
|
||||||
|
the memory addressed by the pointer 'x'
|
||||||
|
from an address that is aligned on an
|
||||||
|
'n' byte boundary ('n' is a power of 2)
|
||||||
|
|
||||||
|
ALIGN_FLOOR(x,n) return a pointer that points to memory
|
||||||
|
that is aligned on an 'n' byte boundary
|
||||||
|
and is not higher than the memory address
|
||||||
|
pointed to by 'x' ('n' is a power of 2)
|
||||||
|
|
||||||
|
ALIGN_CEIL(x,n) return a pointer that points to memory
|
||||||
|
that is aligned on an 'n' byte boundary
|
||||||
|
and is not lower than the memory address
|
||||||
|
pointed to by 'x' ('n' is a power of 2)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define ALIGN_OFFSET(x,n) (((ptrint_t)(x)) & ((n) - 1))
|
||||||
|
#define ALIGN_FLOOR(x,n) ((uint8_t*)(x) - ( ((ptrint_t)(x)) & ((n) - 1)))
|
||||||
|
#define ALIGN_CEIL(x,n) ((uint8_t*)(x) + (-((ptrint_t)(x)) & ((n) - 1)))
|
||||||
|
|
||||||
|
/* These defines are used to declare buffers in a way that allows
|
||||||
|
faster operations on longer variables to be used. In all these
|
||||||
|
defines 'size' must be a power of 2 and >= 8. NOTE that the
|
||||||
|
buffer size is in bytes but the type length is in bits
|
||||||
|
|
||||||
|
UNIT_TYPEDEF(x,size) declares a variable 'x' of length
|
||||||
|
'size' bits
|
||||||
|
|
||||||
|
BUFR_TYPEDEF(x,size,bsize) declares a buffer 'x' of length 'bsize'
|
||||||
|
bytes defined as an array of variables
|
||||||
|
each of 'size' bits (bsize must be a
|
||||||
|
multiple of size / 8)
|
||||||
|
|
||||||
|
UNIT_CAST(x,size) casts a variable to a type of
|
||||||
|
length 'size' bits
|
||||||
|
|
||||||
|
UPTR_CAST(x,size) casts a pointer to a pointer to a
|
||||||
|
varaiable of length 'size' bits
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define UI_TYPE(size) uint##size##_t
|
||||||
|
#define UNIT_TYPEDEF(x,size) typedef UI_TYPE(size) x
|
||||||
|
#define BUFR_TYPEDEF(x,size,bsize) typedef UI_TYPE(size) x[bsize / (size >> 3)]
|
||||||
|
#define UNIT_CAST(x,size) ((UI_TYPE(size) )(x))
|
||||||
|
#define UPTR_CAST(x,size) ((UI_TYPE(size)*)(x))
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
145
SSZipArchive/minizip/aes/fileenc.c
Normal file
145
SSZipArchive/minizip/aes/fileenc.c
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Copyright (c) 2002, Dr Brian Gladman < >, Worcester, UK.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
LICENSE TERMS
|
||||||
|
|
||||||
|
The free distribution and use of this software in both source and binary
|
||||||
|
form is allowed (with or without changes) provided that:
|
||||||
|
|
||||||
|
1. distributions of this source code include the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer;
|
||||||
|
|
||||||
|
2. distributions in binary form include the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other associated materials;
|
||||||
|
|
||||||
|
3. the copyright holder's name is not used to endorse products
|
||||||
|
built using this software without specific written permission.
|
||||||
|
|
||||||
|
ALTERNATIVELY, provided that this notice is retained in full, this product
|
||||||
|
may be distributed under the terms of the GNU General Public License (GPL),
|
||||||
|
in which case the provisions of the GPL apply INSTEAD OF those given above.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
|
||||||
|
This software is provided 'as is' with no explicit or implied warranties
|
||||||
|
in respect of its properties, including, but not limited to, correctness
|
||||||
|
and/or fitness for purpose.
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
Issue Date: 24/01/2003
|
||||||
|
|
||||||
|
This file implements password based file encryption and authentication
|
||||||
|
using AES in CTR mode, HMAC-SHA1 authentication and RFC2898 password
|
||||||
|
based key derivation.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "fileenc.h"
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* subroutine for data encryption/decryption */
|
||||||
|
/* this could be speeded up a lot by aligning */
|
||||||
|
/* buffers and using 32 bit operations */
|
||||||
|
|
||||||
|
static void encr_data(unsigned char data[], unsigned long d_len, fcrypt_ctx cx[1])
|
||||||
|
{
|
||||||
|
unsigned int i = 0, pos = cx->encr_pos;
|
||||||
|
|
||||||
|
while (i < d_len)
|
||||||
|
{
|
||||||
|
if (pos == AES_BLOCK_SIZE)
|
||||||
|
{
|
||||||
|
unsigned int j = 0;
|
||||||
|
/* increment encryption nonce */
|
||||||
|
while (j < 8 && !++cx->nonce[j])
|
||||||
|
++j;
|
||||||
|
/* encrypt the nonce to form next xor buffer */
|
||||||
|
aes_encrypt(cx->nonce, cx->encr_bfr, cx->encr_ctx);
|
||||||
|
pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
data[i++] ^= cx->encr_bfr[pos++];
|
||||||
|
}
|
||||||
|
|
||||||
|
cx->encr_pos = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fcrypt_init(
|
||||||
|
int mode, /* the mode to be used (input) */
|
||||||
|
const unsigned char pwd[], /* the user specified password (input) */
|
||||||
|
unsigned int pwd_len, /* the length of the password (input) */
|
||||||
|
const unsigned char salt[], /* the salt (input) */
|
||||||
|
#ifdef PASSWORD_VERIFIER
|
||||||
|
unsigned char pwd_ver[PWD_VER_LENGTH], /* 2 byte password verifier (output) */
|
||||||
|
#endif
|
||||||
|
fcrypt_ctx cx[1]) /* the file encryption context (output) */
|
||||||
|
{ unsigned char kbuf[2 * MAX_KEY_LENGTH + PWD_VER_LENGTH];
|
||||||
|
|
||||||
|
if (pwd_len > MAX_PWD_LENGTH)
|
||||||
|
return PASSWORD_TOO_LONG;
|
||||||
|
|
||||||
|
if (mode < 1 || mode > 3)
|
||||||
|
return BAD_MODE;
|
||||||
|
|
||||||
|
cx->mode = mode;
|
||||||
|
cx->pwd_len = pwd_len;
|
||||||
|
|
||||||
|
/* derive the encryption and authentication keys and the password verifier */
|
||||||
|
derive_key(pwd, pwd_len, salt, SALT_LENGTH(mode), KEYING_ITERATIONS,
|
||||||
|
kbuf, 2 * KEY_LENGTH(mode) + PWD_VER_LENGTH);
|
||||||
|
|
||||||
|
/* initialise the encryption nonce and buffer pos */
|
||||||
|
cx->encr_pos = AES_BLOCK_SIZE;
|
||||||
|
/* if we need a random component in the encryption */
|
||||||
|
/* nonce, this is where it would have to be set */
|
||||||
|
memset(cx->nonce, 0, AES_BLOCK_SIZE * sizeof(unsigned char));
|
||||||
|
|
||||||
|
/* initialise for encryption using key 1 */
|
||||||
|
aes_encrypt_key(kbuf, KEY_LENGTH(mode), cx->encr_ctx);
|
||||||
|
|
||||||
|
/* initialise for authentication using key 2 */
|
||||||
|
hmac_sha_begin(HMAC_SHA1, cx->auth_ctx);
|
||||||
|
hmac_sha_key(kbuf + KEY_LENGTH(mode), KEY_LENGTH(mode), cx->auth_ctx);
|
||||||
|
|
||||||
|
#ifdef PASSWORD_VERIFIER
|
||||||
|
memcpy(pwd_ver, kbuf + 2 * KEY_LENGTH(mode), PWD_VER_LENGTH);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return GOOD_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* perform 'in place' encryption and authentication */
|
||||||
|
|
||||||
|
void fcrypt_encrypt(unsigned char data[], unsigned int data_len, fcrypt_ctx cx[1])
|
||||||
|
{
|
||||||
|
encr_data(data, data_len, cx);
|
||||||
|
hmac_sha_data(data, data_len, cx->auth_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* perform 'in place' authentication and decryption */
|
||||||
|
|
||||||
|
void fcrypt_decrypt(unsigned char data[], unsigned int data_len, fcrypt_ctx cx[1])
|
||||||
|
{
|
||||||
|
hmac_sha_data(data, data_len, cx->auth_ctx);
|
||||||
|
encr_data(data, data_len, cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* close encryption/decryption and return the MAC value */
|
||||||
|
|
||||||
|
int fcrypt_end(unsigned char mac[], fcrypt_ctx cx[1])
|
||||||
|
{
|
||||||
|
hmac_sha_end(mac, MAC_LENGTH(cx->mode), cx->auth_ctx);
|
||||||
|
return MAC_LENGTH(cx->mode); /* return MAC length in bytes */
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
121
SSZipArchive/minizip/aes/fileenc.h
Normal file
121
SSZipArchive/minizip/aes/fileenc.h
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Copyright (c) 2002, Dr Brian Gladman < >, Worcester, UK.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
LICENSE TERMS
|
||||||
|
|
||||||
|
The free distribution and use of this software in both source and binary
|
||||||
|
form is allowed (with or without changes) provided that:
|
||||||
|
|
||||||
|
1. distributions of this source code include the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer;
|
||||||
|
|
||||||
|
2. distributions in binary form include the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other associated materials;
|
||||||
|
|
||||||
|
3. the copyright holder's name is not used to endorse products
|
||||||
|
built using this software without specific written permission.
|
||||||
|
|
||||||
|
ALTERNATIVELY, provided that this notice is retained in full, this product
|
||||||
|
may be distributed under the terms of the GNU General Public License (GPL),
|
||||||
|
in which case the provisions of the GPL apply INSTEAD OF those given above.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
|
||||||
|
This software is provided 'as is' with no explicit or implied warranties
|
||||||
|
in respect of its properties, including, but not limited to, correctness
|
||||||
|
and/or fitness for purpose.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Issue Date: 24/01/2003
|
||||||
|
|
||||||
|
This file contains the header file for fileenc.c, which implements password
|
||||||
|
based file encryption and authentication using AES in CTR mode, HMAC-SHA1
|
||||||
|
authentication and RFC2898 password based key derivation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _FENC_H
|
||||||
|
#define _FENC_H
|
||||||
|
|
||||||
|
#include "aes.h"
|
||||||
|
#include "hmac.h"
|
||||||
|
#include "pwd2key.h"
|
||||||
|
|
||||||
|
#define PASSWORD_VERIFIER
|
||||||
|
|
||||||
|
#define MAX_KEY_LENGTH 32
|
||||||
|
#define MAX_PWD_LENGTH 128
|
||||||
|
#define MAX_SALT_LENGTH 16
|
||||||
|
#define KEYING_ITERATIONS 1000
|
||||||
|
|
||||||
|
#ifdef PASSWORD_VERIFIER
|
||||||
|
#define PWD_VER_LENGTH 2
|
||||||
|
#else
|
||||||
|
#define PWD_VER_LENGTH 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define GOOD_RETURN 0
|
||||||
|
#define PASSWORD_TOO_LONG -100
|
||||||
|
#define BAD_MODE -101
|
||||||
|
|
||||||
|
/*
|
||||||
|
Field lengths (in bytes) versus File Encryption Mode (0 < mode < 4)
|
||||||
|
|
||||||
|
Mode Key Salt MAC Overhead
|
||||||
|
1 16 8 10 18
|
||||||
|
2 24 12 10 22
|
||||||
|
3 32 16 10 26
|
||||||
|
|
||||||
|
The following macros assume that the mode value is correct.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define KEY_LENGTH(mode) (8 * (mode & 3) + 8)
|
||||||
|
#define SALT_LENGTH(mode) (4 * (mode & 3) + 4)
|
||||||
|
#define MAC_LENGTH(mode) (10)
|
||||||
|
|
||||||
|
/* the context for file encryption */
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{ unsigned char nonce[AES_BLOCK_SIZE]; /* the CTR nonce */
|
||||||
|
unsigned char encr_bfr[AES_BLOCK_SIZE]; /* encrypt buffer */
|
||||||
|
aes_encrypt_ctx encr_ctx[1]; /* encryption context */
|
||||||
|
hmac_ctx auth_ctx[1]; /* authentication context */
|
||||||
|
unsigned int encr_pos; /* block position (enc) */
|
||||||
|
unsigned int pwd_len; /* password length */
|
||||||
|
unsigned int mode; /* File encryption mode */
|
||||||
|
} fcrypt_ctx;
|
||||||
|
|
||||||
|
/* initialise file encryption or decryption */
|
||||||
|
|
||||||
|
int fcrypt_init(
|
||||||
|
int mode, /* the mode to be used (input) */
|
||||||
|
const unsigned char pwd[], /* the user specified password (input) */
|
||||||
|
unsigned int pwd_len, /* the length of the password (input) */
|
||||||
|
const unsigned char salt[], /* the salt (input) */
|
||||||
|
#ifdef PASSWORD_VERIFIER
|
||||||
|
unsigned char pwd_ver[PWD_VER_LENGTH], /* 2 byte password verifier (output) */
|
||||||
|
#endif
|
||||||
|
fcrypt_ctx cx[1]); /* the file encryption context (output) */
|
||||||
|
|
||||||
|
/* perform 'in place' encryption or decryption and authentication */
|
||||||
|
|
||||||
|
void fcrypt_encrypt(unsigned char data[], unsigned int data_len, fcrypt_ctx cx[1]);
|
||||||
|
void fcrypt_decrypt(unsigned char data[], unsigned int data_len, fcrypt_ctx cx[1]);
|
||||||
|
|
||||||
|
/* close encryption/decryption and return the MAC value */
|
||||||
|
/* the return value is the length of the MAC */
|
||||||
|
|
||||||
|
int fcrypt_end(unsigned char mac[], /* the MAC value (output) */
|
||||||
|
fcrypt_ctx cx[1]); /* the context (input) */
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
209
SSZipArchive/minizip/aes/hmac.c
Normal file
209
SSZipArchive/minizip/aes/hmac.c
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
|
||||||
|
|
||||||
|
The redistribution and use of this software (with or without changes)
|
||||||
|
is allowed without the payment of fees or royalties provided that:
|
||||||
|
|
||||||
|
source code distributions include the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer;
|
||||||
|
|
||||||
|
binary distributions include the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer in their documentation.
|
||||||
|
|
||||||
|
This software is provided 'as is' with no explicit or implied warranties
|
||||||
|
in respect of its operation, including, but not limited to, correctness
|
||||||
|
and fitness for purpose.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Issue Date: 20/12/2007
|
||||||
|
|
||||||
|
This is an implementation of HMAC, the FIPS standard keyed hash function
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "hmac.h"
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* initialise the HMAC context to zero */
|
||||||
|
int hmac_sha_begin(enum hmac_hash hash, hmac_ctx cx[1])
|
||||||
|
{
|
||||||
|
memset(cx, 0, sizeof(hmac_ctx));
|
||||||
|
switch(hash)
|
||||||
|
{
|
||||||
|
#ifdef SHA_1
|
||||||
|
case HMAC_SHA1:
|
||||||
|
cx->f_begin = (hf_begin *)sha1_begin;
|
||||||
|
cx->f_hash = (hf_hash *)sha1_hash;
|
||||||
|
cx->f_end = (hf_end *)sha1_end;
|
||||||
|
cx->input_len = SHA1_BLOCK_SIZE;
|
||||||
|
cx->output_len = SHA1_DIGEST_SIZE;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef SHA_224
|
||||||
|
case HMAC_SHA224:
|
||||||
|
cx->f_begin = (hf_begin *)sha224_begin;
|
||||||
|
cx->f_hash = (hf_hash *)sha224_hash;
|
||||||
|
cx->f_end = (hf_end *)sha224_end;
|
||||||
|
cx->input_len = SHA224_BLOCK_SIZE;
|
||||||
|
cx->output_len = SHA224_DIGEST_SIZE;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef SHA_256
|
||||||
|
case HMAC_SHA256:
|
||||||
|
cx->f_begin = (hf_begin *)sha256_begin;
|
||||||
|
cx->f_hash = (hf_hash *)sha256_hash;
|
||||||
|
cx->f_end = (hf_end *)sha256_end;
|
||||||
|
cx->input_len = SHA256_BLOCK_SIZE;
|
||||||
|
cx->output_len = SHA256_DIGEST_SIZE;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef SHA_384
|
||||||
|
case HMAC_SHA384:
|
||||||
|
cx->f_begin = (hf_begin *)sha384_begin;
|
||||||
|
cx->f_hash = (hf_hash *)sha384_hash;
|
||||||
|
cx->f_end = (hf_end *)sha384_end;
|
||||||
|
cx->input_len = SHA384_BLOCK_SIZE;
|
||||||
|
cx->output_len = SHA384_DIGEST_SIZE;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef SHA_512
|
||||||
|
case HMAC_SHA512:
|
||||||
|
cx->f_begin = (hf_begin *)sha512_begin;
|
||||||
|
cx->f_hash = (hf_hash *)sha512_hash;
|
||||||
|
cx->f_end = (hf_end *)sha512_end;
|
||||||
|
cx->input_len = SHA512_BLOCK_SIZE;
|
||||||
|
cx->output_len = SHA512_DIGEST_SIZE;
|
||||||
|
break;
|
||||||
|
case HMAC_SHA512_256:
|
||||||
|
cx->f_begin = (hf_begin *)sha512_256_begin;
|
||||||
|
cx->f_hash = (hf_hash *)sha512_256_hash;
|
||||||
|
cx->f_end = (hf_end *)sha512_256_end;
|
||||||
|
cx->input_len = SHA512_256_BLOCK_SIZE;
|
||||||
|
cx->output_len = SHA512_256_DIGEST_SIZE;
|
||||||
|
break;
|
||||||
|
case HMAC_SHA512_224:
|
||||||
|
cx->f_begin = (hf_begin *)sha512_224_begin;
|
||||||
|
cx->f_hash = (hf_hash *)sha512_224_hash;
|
||||||
|
cx->f_end = (hf_end *)sha512_224_end;
|
||||||
|
cx->input_len = SHA512_224_BLOCK_SIZE;
|
||||||
|
cx->output_len = SHA512_224_DIGEST_SIZE;
|
||||||
|
break;
|
||||||
|
case HMAC_SHA512_192:
|
||||||
|
cx->f_begin = (hf_begin *)sha512_192_begin;
|
||||||
|
cx->f_hash = (hf_hash *)sha512_192_hash;
|
||||||
|
cx->f_end = (hf_end *)sha512_192_end;
|
||||||
|
cx->input_len = SHA512_192_BLOCK_SIZE;
|
||||||
|
cx->output_len = SHA512_192_DIGEST_SIZE;
|
||||||
|
break;
|
||||||
|
case HMAC_SHA512_128:
|
||||||
|
cx->f_begin = (hf_begin *)sha512_128_begin;
|
||||||
|
cx->f_hash = (hf_hash *)sha512_128_hash;
|
||||||
|
cx->f_end = (hf_begin *)sha512_128_end;
|
||||||
|
cx->input_len = SHA512_128_BLOCK_SIZE;
|
||||||
|
cx->output_len = SHA512_128_DIGEST_SIZE;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return (int)cx->output_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* input the HMAC key (can be called multiple times) */
|
||||||
|
int hmac_sha_key(const unsigned char key[], unsigned long key_len, hmac_ctx cx[1])
|
||||||
|
{
|
||||||
|
if(cx->klen == HMAC_IN_DATA) /* error if further key input */
|
||||||
|
return EXIT_FAILURE; /* is attempted in data mode */
|
||||||
|
|
||||||
|
if(cx->klen + key_len > cx->input_len) /* if the key has to be hashed */
|
||||||
|
{
|
||||||
|
if(cx->klen <= cx->input_len) /* if the hash has not yet been */
|
||||||
|
{ /* started, initialise it and */
|
||||||
|
cx->f_begin(cx->sha_ctx); /* hash stored key characters */
|
||||||
|
cx->f_hash(cx->key, cx->klen, cx->sha_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
cx->f_hash(key, key_len, cx->sha_ctx); /* hash long key data into hash */
|
||||||
|
}
|
||||||
|
else /* otherwise store key data */
|
||||||
|
memcpy(cx->key + cx->klen, key, key_len);
|
||||||
|
|
||||||
|
cx->klen += key_len; /* update the key length count */
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* input the HMAC data (can be called multiple times) - */
|
||||||
|
/* note that this call terminates the key input phase */
|
||||||
|
void hmac_sha_data(const unsigned char data[], unsigned long data_len, hmac_ctx cx[1])
|
||||||
|
{ unsigned int i;
|
||||||
|
|
||||||
|
if(cx->klen != HMAC_IN_DATA) /* if not yet in data phase */
|
||||||
|
{
|
||||||
|
if(cx->klen > cx->input_len) /* if key is being hashed */
|
||||||
|
{ /* complete the hash and */
|
||||||
|
cx->f_end(cx->key, cx->sha_ctx); /* store the result as the */
|
||||||
|
cx->klen = cx->output_len; /* key and set new length */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pad the key if necessary */
|
||||||
|
memset(cx->key + cx->klen, 0, cx->input_len - cx->klen);
|
||||||
|
|
||||||
|
/* xor ipad into key value */
|
||||||
|
for(i = 0; i < (cx->input_len >> 2); ++i)
|
||||||
|
((uint32_t*)cx->key)[i] ^= 0x36363636;
|
||||||
|
|
||||||
|
/* and start hash operation */
|
||||||
|
cx->f_begin(cx->sha_ctx);
|
||||||
|
cx->f_hash(cx->key, cx->input_len, cx->sha_ctx);
|
||||||
|
|
||||||
|
/* mark as now in data mode */
|
||||||
|
cx->klen = HMAC_IN_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* hash the data (if any) */
|
||||||
|
if(data_len)
|
||||||
|
cx->f_hash(data, data_len, cx->sha_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* compute and output the MAC value */
|
||||||
|
void hmac_sha_end(unsigned char mac[], unsigned long mac_len, hmac_ctx cx[1])
|
||||||
|
{ unsigned char dig[HMAC_MAX_OUTPUT_SIZE];
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
/* if no data has been entered perform a null data phase */
|
||||||
|
if(cx->klen != HMAC_IN_DATA)
|
||||||
|
hmac_sha_data((const unsigned char*)0, 0, cx);
|
||||||
|
|
||||||
|
cx->f_end(dig, cx->sha_ctx); /* complete the inner hash */
|
||||||
|
|
||||||
|
/* set outer key value using opad and removing ipad */
|
||||||
|
for(i = 0; i < (cx->input_len >> 2); ++i)
|
||||||
|
((uint32_t*)cx->key)[i] ^= 0x36363636 ^ 0x5c5c5c5c;
|
||||||
|
|
||||||
|
/* perform the outer hash operation */
|
||||||
|
cx->f_begin(cx->sha_ctx);
|
||||||
|
cx->f_hash(cx->key, cx->input_len, cx->sha_ctx);
|
||||||
|
cx->f_hash(dig, cx->output_len, cx->sha_ctx);
|
||||||
|
cx->f_end(dig, cx->sha_ctx);
|
||||||
|
|
||||||
|
/* output the hash value */
|
||||||
|
for(i = 0; i < mac_len; ++i)
|
||||||
|
mac[i] = dig[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 'do it all in one go' subroutine */
|
||||||
|
void hmac_sha(enum hmac_hash hash, const unsigned char key[], unsigned long key_len,
|
||||||
|
const unsigned char data[], unsigned long data_len,
|
||||||
|
unsigned char mac[], unsigned long mac_len)
|
||||||
|
{ hmac_ctx cx[1];
|
||||||
|
|
||||||
|
hmac_sha_begin(hash, cx);
|
||||||
|
hmac_sha_key(key, key_len, cx);
|
||||||
|
hmac_sha_data(data, data_len, cx);
|
||||||
|
hmac_sha_end(mac, mac_len, cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
119
SSZipArchive/minizip/aes/hmac.h
Normal file
119
SSZipArchive/minizip/aes/hmac.h
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
|
||||||
|
|
||||||
|
The redistribution and use of this software (with or without changes)
|
||||||
|
is allowed without the payment of fees or royalties provided that:
|
||||||
|
|
||||||
|
source code distributions include the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer;
|
||||||
|
|
||||||
|
binary distributions include the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer in their documentation.
|
||||||
|
|
||||||
|
This software is provided 'as is' with no explicit or implied warranties
|
||||||
|
in respect of its operation, including, but not limited to, correctness
|
||||||
|
and fitness for purpose.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Issue Date: 20/12/2007
|
||||||
|
|
||||||
|
This is an implementation of HMAC, the FIPS standard keyed hash function
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _HMAC2_H
|
||||||
|
#define _HMAC2_H
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "sha1.h"
|
||||||
|
|
||||||
|
#if defined(SHA_224) || defined(SHA_256) || defined(SHA_384) || defined(SHA_512)
|
||||||
|
#define HMAC_MAX_OUTPUT_SIZE SHA2_MAX_DIGEST_SIZE
|
||||||
|
#define HMAC_MAX_BLOCK_SIZE SHA2_MAX_BLOCK_SIZE
|
||||||
|
#else
|
||||||
|
#define HMAC_MAX_OUTPUT_SIZE SHA1_DIGEST_SIZE
|
||||||
|
#define HMAC_MAX_BLOCK_SIZE SHA1_BLOCK_SIZE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define HMAC_IN_DATA 0xffffffff
|
||||||
|
|
||||||
|
enum hmac_hash
|
||||||
|
{
|
||||||
|
#ifdef SHA_1
|
||||||
|
HMAC_SHA1,
|
||||||
|
#endif
|
||||||
|
#ifdef SHA_224
|
||||||
|
HMAC_SHA224,
|
||||||
|
#endif
|
||||||
|
#ifdef SHA_256
|
||||||
|
HMAC_SHA256,
|
||||||
|
#endif
|
||||||
|
#ifdef SHA_384
|
||||||
|
HMAC_SHA384,
|
||||||
|
#endif
|
||||||
|
#ifdef SHA_512
|
||||||
|
HMAC_SHA512,
|
||||||
|
HMAC_SHA512_256,
|
||||||
|
HMAC_SHA512_224,
|
||||||
|
HMAC_SHA512_192,
|
||||||
|
HMAC_SHA512_128
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef VOID_RETURN hf_begin(void*);
|
||||||
|
typedef VOID_RETURN hf_hash(const void*, unsigned long len, void*);
|
||||||
|
typedef VOID_RETURN hf_end(void*, void*);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{ hf_begin *f_begin;
|
||||||
|
hf_hash *f_hash;
|
||||||
|
hf_end *f_end;
|
||||||
|
unsigned char key[HMAC_MAX_BLOCK_SIZE];
|
||||||
|
union
|
||||||
|
{
|
||||||
|
#ifdef SHA_1
|
||||||
|
sha1_ctx u_sha1;
|
||||||
|
#endif
|
||||||
|
#ifdef SHA_224
|
||||||
|
sha224_ctx u_sha224;
|
||||||
|
#endif
|
||||||
|
#ifdef SHA_256
|
||||||
|
sha256_ctx u_sha256;
|
||||||
|
#endif
|
||||||
|
#ifdef SHA_384
|
||||||
|
sha384_ctx u_sha384;
|
||||||
|
#endif
|
||||||
|
#ifdef SHA_512
|
||||||
|
sha512_ctx u_sha512;
|
||||||
|
#endif
|
||||||
|
} sha_ctx[1];
|
||||||
|
unsigned long input_len;
|
||||||
|
unsigned long output_len;
|
||||||
|
unsigned long klen;
|
||||||
|
} hmac_ctx;
|
||||||
|
|
||||||
|
/* returns the length of hash digest for the hash used */
|
||||||
|
/* mac_len must not be greater than this */
|
||||||
|
int hmac_sha_begin(enum hmac_hash hash, hmac_ctx cx[1]);
|
||||||
|
|
||||||
|
int hmac_sha_key(const unsigned char key[], unsigned long key_len, hmac_ctx cx[1]);
|
||||||
|
|
||||||
|
void hmac_sha_data(const unsigned char data[], unsigned long data_len, hmac_ctx cx[1]);
|
||||||
|
|
||||||
|
void hmac_sha_end(unsigned char mac[], unsigned long mac_len, hmac_ctx cx[1]);
|
||||||
|
|
||||||
|
void hmac_sha(enum hmac_hash hash, const unsigned char key[], unsigned long key_len,
|
||||||
|
const unsigned char data[], unsigned long data_len,
|
||||||
|
unsigned char mac[], unsigned long mac_len);
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
155
SSZipArchive/minizip/aes/prng.c
Normal file
155
SSZipArchive/minizip/aes/prng.c
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Copyright (c) 2002, Dr Brian Gladman < >, Worcester, UK.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
LICENSE TERMS
|
||||||
|
|
||||||
|
The free distribution and use of this software in both source and binary
|
||||||
|
form is allowed (with or without changes) provided that:
|
||||||
|
|
||||||
|
1. distributions of this source code include the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer;
|
||||||
|
|
||||||
|
2. distributions in binary form include the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other associated materials;
|
||||||
|
|
||||||
|
3. the copyright holder's name is not used to endorse products
|
||||||
|
built using this software without specific written permission.
|
||||||
|
|
||||||
|
ALTERNATIVELY, provided that this notice is retained in full, this product
|
||||||
|
may be distributed under the terms of the GNU General Public License (GPL),
|
||||||
|
in which case the provisions of the GPL apply INSTEAD OF those given above.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
|
||||||
|
This software is provided 'as is' with no explicit or implied warranties
|
||||||
|
in respect of its properties, including, but not limited to, correctness
|
||||||
|
and/or fitness for purpose.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Issue Date: 24/01/2003
|
||||||
|
|
||||||
|
This file implements a random data pool based on the use of an external
|
||||||
|
entropy function. It is based on the ideas advocated by Peter Gutmann in
|
||||||
|
his work on pseudo random sequence generators. It is not a 'paranoid'
|
||||||
|
random sequence generator and no attempt is made to protect the pool
|
||||||
|
from prying eyes either by memory locking or by techniques to obscure
|
||||||
|
its location in memory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "prng.h"
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* mix a random data pool using the SHA1 compression function (as */
|
||||||
|
/* suggested by Peter Gutmann in his paper on random pools) */
|
||||||
|
|
||||||
|
static void prng_mix(unsigned char buf[])
|
||||||
|
{ unsigned int i, len;
|
||||||
|
sha1_ctx ctx[1];
|
||||||
|
|
||||||
|
/*lint -e{663} unusual array to pointer conversion */
|
||||||
|
for(i = 0; i < PRNG_POOL_SIZE; i += SHA1_DIGEST_SIZE)
|
||||||
|
{
|
||||||
|
/* copy digest size pool block into SHA1 hash block */
|
||||||
|
memcpy(ctx->hash, buf + (i ? i : PRNG_POOL_SIZE)
|
||||||
|
- SHA1_DIGEST_SIZE, SHA1_DIGEST_SIZE);
|
||||||
|
|
||||||
|
/* copy data from pool into the SHA1 data buffer */
|
||||||
|
len = PRNG_POOL_SIZE - i;
|
||||||
|
memcpy(ctx->wbuf, buf + i, (len > SHA1_BLOCK_SIZE ? SHA1_BLOCK_SIZE : len));
|
||||||
|
|
||||||
|
if(len < SHA1_BLOCK_SIZE)
|
||||||
|
memcpy(((char*)ctx->wbuf) + len, buf, SHA1_BLOCK_SIZE - len);
|
||||||
|
|
||||||
|
/* compress using the SHA1 compression function */
|
||||||
|
sha1_compile(ctx);
|
||||||
|
|
||||||
|
/* put digest size block back into the random pool */
|
||||||
|
memcpy(buf + i, ctx->hash, SHA1_DIGEST_SIZE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* refresh the output buffer and update the random pool by adding */
|
||||||
|
/* entropy and remixing */
|
||||||
|
|
||||||
|
static void update_pool(prng_ctx ctx[1])
|
||||||
|
{ unsigned int i = 0;
|
||||||
|
|
||||||
|
/* transfer random pool data to the output buffer */
|
||||||
|
memcpy(ctx->obuf, ctx->rbuf, PRNG_POOL_SIZE);
|
||||||
|
|
||||||
|
/* enter entropy data into the pool */
|
||||||
|
while(i < PRNG_POOL_SIZE)
|
||||||
|
i += ctx->entropy(ctx->rbuf + i, PRNG_POOL_SIZE - i);
|
||||||
|
|
||||||
|
/* invert and xor the original pool data into the pool */
|
||||||
|
for(i = 0; i < PRNG_POOL_SIZE; ++i)
|
||||||
|
ctx->rbuf[i] ^= ~ctx->obuf[i];
|
||||||
|
|
||||||
|
/* mix the pool and the output buffer */
|
||||||
|
prng_mix(ctx->rbuf);
|
||||||
|
prng_mix(ctx->obuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void prng_init(prng_entropy_fn fun, prng_ctx ctx[1])
|
||||||
|
{ int i;
|
||||||
|
|
||||||
|
/* clear the buffers and the counter in the context */
|
||||||
|
memset(ctx, 0, sizeof(prng_ctx));
|
||||||
|
|
||||||
|
/* set the pointer to the entropy collection function */
|
||||||
|
ctx->entropy = fun;
|
||||||
|
|
||||||
|
/* initialise the random data pool */
|
||||||
|
update_pool(ctx);
|
||||||
|
|
||||||
|
/* mix the pool a minimum number of times */
|
||||||
|
for(i = 0; i < PRNG_MIN_MIX; ++i)
|
||||||
|
prng_mix(ctx->rbuf);
|
||||||
|
|
||||||
|
/* update the pool to prime the pool output buffer */
|
||||||
|
update_pool(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* provide random bytes from the random data pool */
|
||||||
|
|
||||||
|
void prng_rand(unsigned char data[], unsigned int data_len, prng_ctx ctx[1])
|
||||||
|
{ unsigned char *rp = data;
|
||||||
|
unsigned int len, pos = ctx->pos;
|
||||||
|
|
||||||
|
while(data_len)
|
||||||
|
{
|
||||||
|
/* transfer 'data_len' bytes (or the number of bytes remaining */
|
||||||
|
/* the pool output buffer if less) into the output */
|
||||||
|
len = (data_len < PRNG_POOL_SIZE - pos ? data_len : PRNG_POOL_SIZE - pos);
|
||||||
|
memcpy(rp, ctx->obuf + pos, len);
|
||||||
|
rp += len; /* update ouput buffer position pointer */
|
||||||
|
pos += len; /* update pool output buffer pointer */
|
||||||
|
data_len -= len; /* update the remaining data count */
|
||||||
|
|
||||||
|
/* refresh the random pool if necessary */
|
||||||
|
if(pos == PRNG_POOL_SIZE)
|
||||||
|
{
|
||||||
|
update_pool(ctx); pos = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->pos = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void prng_end(prng_ctx ctx[1])
|
||||||
|
{
|
||||||
|
/* ensure the data in the context is destroyed */
|
||||||
|
memset(ctx, 0, sizeof(prng_ctx));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
82
SSZipArchive/minizip/aes/prng.h
Normal file
82
SSZipArchive/minizip/aes/prng.h
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Copyright (c) 2002, Dr Brian Gladman < >, Worcester, UK.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
LICENSE TERMS
|
||||||
|
|
||||||
|
The free distribution and use of this software in both source and binary
|
||||||
|
form is allowed (with or without changes) provided that:
|
||||||
|
|
||||||
|
1. distributions of this source code include the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer;
|
||||||
|
|
||||||
|
2. distributions in binary form include the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other associated materials;
|
||||||
|
|
||||||
|
3. the copyright holder's name is not used to endorse products
|
||||||
|
built using this software without specific written permission.
|
||||||
|
|
||||||
|
ALTERNATIVELY, provided that this notice is retained in full, this product
|
||||||
|
may be distributed under the terms of the GNU General Public License (GPL),
|
||||||
|
in which case the provisions of the GPL apply INSTEAD OF those given above.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
|
||||||
|
This software is provided 'as is' with no explicit or implied warranties
|
||||||
|
in respect of its properties, including, but not limited to, correctness
|
||||||
|
and/or fitness for purpose.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Issue Date: 24/01/2003
|
||||||
|
|
||||||
|
This is the header file for an implementation of a random data pool based on
|
||||||
|
the use of an external entropy function (inspired by Peter Gutmann's work).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PRNG_H
|
||||||
|
#define _PRNG_H
|
||||||
|
|
||||||
|
#include "sha1.h"
|
||||||
|
|
||||||
|
#define PRNG_POOL_LEN 256 /* minimum random pool size */
|
||||||
|
#define PRNG_MIN_MIX 20 /* min initial pool mixing iterations */
|
||||||
|
|
||||||
|
/* ensure that pool length is a multiple of the SHA1 digest size */
|
||||||
|
|
||||||
|
#define PRNG_POOL_SIZE (SHA1_DIGEST_SIZE * (1 + (PRNG_POOL_LEN - 1) / SHA1_DIGEST_SIZE))
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* A function for providing entropy is a parameter in the prng_init() */
|
||||||
|
/* call. This function has the following form and returns a maximum */
|
||||||
|
/* of 'len' bytes of pseudo random data in the buffer 'buf'. It can */
|
||||||
|
/* return less than 'len' bytes but will be repeatedly called for more */
|
||||||
|
/* data in this case. */
|
||||||
|
|
||||||
|
typedef int (*prng_entropy_fn)(unsigned char buf[], unsigned int len);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{ unsigned char rbuf[PRNG_POOL_SIZE]; /* the random pool */
|
||||||
|
unsigned char obuf[PRNG_POOL_SIZE]; /* pool output buffer */
|
||||||
|
unsigned int pos; /* output buffer position */
|
||||||
|
prng_entropy_fn entropy; /* entropy function pointer */
|
||||||
|
} prng_ctx;
|
||||||
|
|
||||||
|
/* initialise the random stream generator */
|
||||||
|
void prng_init(prng_entropy_fn fun, prng_ctx ctx[1]);
|
||||||
|
|
||||||
|
/* obtain random bytes from the generator */
|
||||||
|
void prng_rand(unsigned char data[], unsigned int data_len, prng_ctx ctx[1]);
|
||||||
|
|
||||||
|
/* close the random stream generator */
|
||||||
|
void prng_end(prng_ctx ctx[1]);
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
181
SSZipArchive/minizip/aes/pwd2key.c
Normal file
181
SSZipArchive/minizip/aes/pwd2key.c
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
|
||||||
|
|
||||||
|
The redistribution and use of this software (with or without changes)
|
||||||
|
is allowed without the payment of fees or royalties provided that:
|
||||||
|
|
||||||
|
source code distributions include the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer;
|
||||||
|
|
||||||
|
binary distributions include the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer in their documentation.
|
||||||
|
|
||||||
|
This software is provided 'as is' with no explicit or implied warranties
|
||||||
|
in respect of its operation, including, but not limited to, correctness
|
||||||
|
and fitness for purpose.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Issue Date: 20/12/2007
|
||||||
|
|
||||||
|
This is an implementation of RFC2898, which specifies key derivation from
|
||||||
|
a password and a salt value.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "hmac.h"
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void derive_key(const unsigned char pwd[], /* the PASSWORD */
|
||||||
|
unsigned int pwd_len, /* and its length */
|
||||||
|
const unsigned char salt[], /* the SALT and its */
|
||||||
|
unsigned int salt_len, /* length */
|
||||||
|
unsigned int iter, /* the number of iterations */
|
||||||
|
unsigned char key[], /* space for the output key */
|
||||||
|
unsigned int key_len)/* and its required length */
|
||||||
|
{
|
||||||
|
unsigned int i, j, k, n_blk, h_size;
|
||||||
|
unsigned char uu[HMAC_MAX_OUTPUT_SIZE], ux[HMAC_MAX_OUTPUT_SIZE];
|
||||||
|
hmac_ctx c1[1], c2[1], c3[1];
|
||||||
|
|
||||||
|
/* set HMAC context (c1) for password */
|
||||||
|
h_size = hmac_sha_begin(HMAC_SHA1, c1);
|
||||||
|
hmac_sha_key(pwd, pwd_len, c1);
|
||||||
|
|
||||||
|
/* set HMAC context (c2) for password and salt */
|
||||||
|
memcpy(c2, c1, sizeof(hmac_ctx));
|
||||||
|
hmac_sha_data(salt, salt_len, c2);
|
||||||
|
|
||||||
|
/* find the number of SHA blocks in the key */
|
||||||
|
n_blk = 1 + (key_len - 1) / h_size;
|
||||||
|
|
||||||
|
for(i = 0; i < n_blk; ++i) /* for each block in key */
|
||||||
|
{
|
||||||
|
/* ux[] holds the running xor value */
|
||||||
|
memset(ux, 0, h_size);
|
||||||
|
|
||||||
|
/* set HMAC context (c3) for password and salt */
|
||||||
|
memcpy(c3, c2, sizeof(hmac_ctx));
|
||||||
|
|
||||||
|
/* enter additional data for 1st block into uu */
|
||||||
|
uu[0] = (unsigned char)((i + 1) >> 24);
|
||||||
|
uu[1] = (unsigned char)((i + 1) >> 16);
|
||||||
|
uu[2] = (unsigned char)((i + 1) >> 8);
|
||||||
|
uu[3] = (unsigned char)(i + 1);
|
||||||
|
|
||||||
|
/* this is the key mixing iteration */
|
||||||
|
for(j = 0, k = 4; j < iter; ++j)
|
||||||
|
{
|
||||||
|
/* add previous round data to HMAC */
|
||||||
|
hmac_sha_data(uu, k, c3);
|
||||||
|
|
||||||
|
/* obtain HMAC for uu[] */
|
||||||
|
hmac_sha_end(uu, h_size, c3);
|
||||||
|
|
||||||
|
/* xor into the running xor block */
|
||||||
|
for(k = 0; k < h_size; ++k)
|
||||||
|
ux[k] ^= uu[k];
|
||||||
|
|
||||||
|
/* set HMAC context (c3) for password */
|
||||||
|
memcpy(c3, c1, sizeof(hmac_ctx));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* compile key blocks into the key output */
|
||||||
|
j = 0; k = i * h_size;
|
||||||
|
while(j < h_size && k < key_len)
|
||||||
|
key[k++] = ux[j++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
struct
|
||||||
|
{ unsigned int pwd_len;
|
||||||
|
unsigned int salt_len;
|
||||||
|
unsigned int it_count;
|
||||||
|
unsigned char *pwd;
|
||||||
|
unsigned char salt[32];
|
||||||
|
unsigned char key[32];
|
||||||
|
} tests[] =
|
||||||
|
{
|
||||||
|
{ 8, 4, 5, (unsigned char*)"password",
|
||||||
|
{
|
||||||
|
0x12, 0x34, 0x56, 0x78
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0x5c, 0x75, 0xce, 0xf0, 0x1a, 0x96, 0x0d, 0xf7,
|
||||||
|
0x4c, 0xb6, 0xb4, 0x9b, 0x9e, 0x38, 0xe6, 0xb5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ 8, 8, 5, (unsigned char*)"password",
|
||||||
|
{
|
||||||
|
0x12, 0x34, 0x56, 0x78, 0x78, 0x56, 0x34, 0x12
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0xd1, 0xda, 0xa7, 0x86, 0x15, 0xf2, 0x87, 0xe6,
|
||||||
|
0xa1, 0xc8, 0xb1, 0x20, 0xd7, 0x06, 0x2a, 0x49
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ 8, 21, 1, (unsigned char*)"password",
|
||||||
|
{
|
||||||
|
"ATHENA.MIT.EDUraeburn"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0xcd, 0xed, 0xb5, 0x28, 0x1b, 0xb2, 0xf8, 0x01,
|
||||||
|
0x56, 0x5a, 0x11, 0x22, 0xb2, 0x56, 0x35, 0x15
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ 8, 21, 2, (unsigned char*)"password",
|
||||||
|
{
|
||||||
|
"ATHENA.MIT.EDUraeburn"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0x01, 0xdb, 0xee, 0x7f, 0x4a, 0x9e, 0x24, 0x3e,
|
||||||
|
0x98, 0x8b, 0x62, 0xc7, 0x3c, 0xda, 0x93, 0x5d
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ 8, 21, 1200, (unsigned char*)"password",
|
||||||
|
{
|
||||||
|
"ATHENA.MIT.EDUraeburn"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0x5c, 0x08, 0xeb, 0x61, 0xfd, 0xf7, 0x1e, 0x4e,
|
||||||
|
0x4e, 0xc3, 0xcf, 0x6b, 0xa1, 0xf5, 0x51, 0x2b
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{ unsigned int i, j, key_len = 256;
|
||||||
|
unsigned char key[256];
|
||||||
|
|
||||||
|
printf("\nTest of RFC2898 Password Based Key Derivation");
|
||||||
|
for(i = 0; i < 5; ++i)
|
||||||
|
{
|
||||||
|
derive_key(tests[i].pwd, tests[i].pwd_len, tests[i].salt,
|
||||||
|
tests[i].salt_len, tests[i].it_count, key, key_len);
|
||||||
|
|
||||||
|
printf("\ntest %i: ", i + 1);
|
||||||
|
printf("key %s", memcmp(tests[i].key, key, 16) ? "is bad" : "is good");
|
||||||
|
for(j = 0; j < key_len && j < 64; j += 4)
|
||||||
|
{
|
||||||
|
if(j % 16 == 0)
|
||||||
|
printf("\n");
|
||||||
|
printf("0x%02x%02x%02x%02x ", key[j], key[j + 1], key[j + 2], key[j + 3]);
|
||||||
|
}
|
||||||
|
printf(j < key_len ? " ... \n" : "\n");
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
45
SSZipArchive/minizip/aes/pwd2key.h
Normal file
45
SSZipArchive/minizip/aes/pwd2key.h
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
|
||||||
|
|
||||||
|
The redistribution and use of this software (with or without changes)
|
||||||
|
is allowed without the payment of fees or royalties provided that:
|
||||||
|
|
||||||
|
source code distributions include the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer;
|
||||||
|
|
||||||
|
binary distributions include the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer in their documentation.
|
||||||
|
|
||||||
|
This software is provided 'as is' with no explicit or implied warranties
|
||||||
|
in respect of its operation, including, but not limited to, correctness
|
||||||
|
and fitness for purpose.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Issue Date: 20/12/2007
|
||||||
|
|
||||||
|
This is an implementation of RFC2898, which specifies key derivation from
|
||||||
|
a password and a salt value.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PWD2KEY_H
|
||||||
|
#define PWD2KEY_H
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void derive_key(
|
||||||
|
const unsigned char pwd[], /* the PASSWORD, and */
|
||||||
|
unsigned int pwd_len, /* its length */
|
||||||
|
const unsigned char salt[], /* the SALT and its */
|
||||||
|
unsigned int salt_len, /* length */
|
||||||
|
unsigned int iter, /* the number of iterations */
|
||||||
|
unsigned char key[], /* space for the output key */
|
||||||
|
unsigned int key_len); /* and its required length */
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
283
SSZipArchive/minizip/aes/sha1.c
Normal file
283
SSZipArchive/minizip/aes/sha1.c
Normal file
@@ -0,0 +1,283 @@
|
|||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
|
||||||
|
|
||||||
|
The redistribution and use of this software (with or without changes)
|
||||||
|
is allowed without the payment of fees or royalties provided that:
|
||||||
|
|
||||||
|
source code distributions include the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer;
|
||||||
|
|
||||||
|
binary distributions include the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer in their documentation.
|
||||||
|
|
||||||
|
This software is provided 'as is' with no explicit or implied warranties
|
||||||
|
in respect of its operation, including, but not limited to, correctness
|
||||||
|
and fitness for purpose.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Issue Date: 20/12/2007
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h> /* for memcpy() etc. */
|
||||||
|
|
||||||
|
#include "sha1.h"
|
||||||
|
#include "brg_endian.h"
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( _MSC_VER ) && ( _MSC_VER > 800 )
|
||||||
|
#pragma intrinsic(memcpy)
|
||||||
|
#pragma intrinsic(memset)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0 && defined(_MSC_VER)
|
||||||
|
#define rotl32 _lrotl
|
||||||
|
#define rotr32 _lrotr
|
||||||
|
#else
|
||||||
|
#define rotl32(x,n) (((x) << n) | ((x) >> (32 - n)))
|
||||||
|
#define rotr32(x,n) (((x) >> n) | ((x) << (32 - n)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(bswap_32)
|
||||||
|
#define bswap_32(x) ((rotr32((x), 24) & 0x00ff00ff) | (rotr32((x), 8) & 0xff00ff00))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
|
||||||
|
#define SWAP_BYTES
|
||||||
|
#else
|
||||||
|
#undef SWAP_BYTES
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(SWAP_BYTES)
|
||||||
|
#define bsw_32(p,n) \
|
||||||
|
{ int _i = (n); while(_i--) ((uint32_t*)p)[_i] = bswap_32(((uint32_t*)p)[_i]); }
|
||||||
|
#else
|
||||||
|
#define bsw_32(p,n)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SHA1_MASK (SHA1_BLOCK_SIZE - 1)
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
#define ch(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
|
||||||
|
#define parity(x,y,z) ((x) ^ (y) ^ (z))
|
||||||
|
#define maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
|
||||||
|
|
||||||
|
#else /* Discovered by Rich Schroeppel and Colin Plumb */
|
||||||
|
|
||||||
|
#define ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
|
||||||
|
#define parity(x,y,z) ((x) ^ (y) ^ (z))
|
||||||
|
#define maj(x,y,z) (((x) & (y)) | ((z) & ((x) ^ (y))))
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Compile 64 bytes of hash data into SHA1 context. Note */
|
||||||
|
/* that this routine assumes that the byte order in the */
|
||||||
|
/* ctx->wbuf[] at this point is in such an order that low */
|
||||||
|
/* address bytes in the ORIGINAL byte stream will go in */
|
||||||
|
/* this buffer to the high end of 32-bit words on BOTH big */
|
||||||
|
/* and little endian systems */
|
||||||
|
|
||||||
|
#ifdef ARRAY
|
||||||
|
#define q(v,n) v[n]
|
||||||
|
#else
|
||||||
|
#define q(v,n) v##n
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SHA_1
|
||||||
|
|
||||||
|
#define one_cycle(v,a,b,c,d,e,f,k,h) \
|
||||||
|
q(v,e) += rotr32(q(v,a),27) + \
|
||||||
|
f(q(v,b),q(v,c),q(v,d)) + k + h; \
|
||||||
|
q(v,b) = rotr32(q(v,b), 2)
|
||||||
|
|
||||||
|
#define five_cycle(v,f,k,i) \
|
||||||
|
one_cycle(v, 0,1,2,3,4, f,k,hf(i )); \
|
||||||
|
one_cycle(v, 4,0,1,2,3, f,k,hf(i+1)); \
|
||||||
|
one_cycle(v, 3,4,0,1,2, f,k,hf(i+2)); \
|
||||||
|
one_cycle(v, 2,3,4,0,1, f,k,hf(i+3)); \
|
||||||
|
one_cycle(v, 1,2,3,4,0, f,k,hf(i+4))
|
||||||
|
|
||||||
|
VOID_RETURN sha1_compile(sha1_ctx ctx[1])
|
||||||
|
{ uint32_t *w = ctx->wbuf;
|
||||||
|
|
||||||
|
#ifdef ARRAY
|
||||||
|
uint32_t v[5];
|
||||||
|
memcpy(v, ctx->hash, sizeof(ctx->hash));
|
||||||
|
#else
|
||||||
|
uint32_t v0, v1, v2, v3, v4;
|
||||||
|
v0 = ctx->hash[0]; v1 = ctx->hash[1];
|
||||||
|
v2 = ctx->hash[2]; v3 = ctx->hash[3];
|
||||||
|
v4 = ctx->hash[4];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define hf(i) w[i]
|
||||||
|
|
||||||
|
five_cycle(v, ch, 0x5a827999, 0);
|
||||||
|
five_cycle(v, ch, 0x5a827999, 5);
|
||||||
|
five_cycle(v, ch, 0x5a827999, 10);
|
||||||
|
one_cycle(v,0,1,2,3,4, ch, 0x5a827999, hf(15)); \
|
||||||
|
|
||||||
|
#undef hf
|
||||||
|
#define hf(i) (w[(i) & 15] = rotl32( \
|
||||||
|
w[((i) + 13) & 15] ^ w[((i) + 8) & 15] \
|
||||||
|
^ w[((i) + 2) & 15] ^ w[(i) & 15], 1))
|
||||||
|
|
||||||
|
one_cycle(v,4,0,1,2,3, ch, 0x5a827999, hf(16));
|
||||||
|
one_cycle(v,3,4,0,1,2, ch, 0x5a827999, hf(17));
|
||||||
|
one_cycle(v,2,3,4,0,1, ch, 0x5a827999, hf(18));
|
||||||
|
one_cycle(v,1,2,3,4,0, ch, 0x5a827999, hf(19));
|
||||||
|
|
||||||
|
five_cycle(v, parity, 0x6ed9eba1, 20);
|
||||||
|
five_cycle(v, parity, 0x6ed9eba1, 25);
|
||||||
|
five_cycle(v, parity, 0x6ed9eba1, 30);
|
||||||
|
five_cycle(v, parity, 0x6ed9eba1, 35);
|
||||||
|
|
||||||
|
five_cycle(v, maj, 0x8f1bbcdc, 40);
|
||||||
|
five_cycle(v, maj, 0x8f1bbcdc, 45);
|
||||||
|
five_cycle(v, maj, 0x8f1bbcdc, 50);
|
||||||
|
five_cycle(v, maj, 0x8f1bbcdc, 55);
|
||||||
|
|
||||||
|
five_cycle(v, parity, 0xca62c1d6, 60);
|
||||||
|
five_cycle(v, parity, 0xca62c1d6, 65);
|
||||||
|
five_cycle(v, parity, 0xca62c1d6, 70);
|
||||||
|
five_cycle(v, parity, 0xca62c1d6, 75);
|
||||||
|
|
||||||
|
#ifdef ARRAY
|
||||||
|
ctx->hash[0] += v[0]; ctx->hash[1] += v[1];
|
||||||
|
ctx->hash[2] += v[2]; ctx->hash[3] += v[3];
|
||||||
|
ctx->hash[4] += v[4];
|
||||||
|
#else
|
||||||
|
ctx->hash[0] += v0; ctx->hash[1] += v1;
|
||||||
|
ctx->hash[2] += v2; ctx->hash[3] += v3;
|
||||||
|
ctx->hash[4] += v4;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID_RETURN sha1_begin(sha1_ctx ctx[1])
|
||||||
|
{
|
||||||
|
memset(ctx, 0, sizeof(sha1_ctx));
|
||||||
|
ctx->hash[0] = 0x67452301;
|
||||||
|
ctx->hash[1] = 0xefcdab89;
|
||||||
|
ctx->hash[2] = 0x98badcfe;
|
||||||
|
ctx->hash[3] = 0x10325476;
|
||||||
|
ctx->hash[4] = 0xc3d2e1f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SHA1 hash data in an array of bytes into hash buffer and */
|
||||||
|
/* call the hash_compile function as required. For both the */
|
||||||
|
/* bit and byte orientated versions, the block length 'len' */
|
||||||
|
/* must not be greater than 2^32 - 1 bits (2^29 - 1 bytes) */
|
||||||
|
|
||||||
|
VOID_RETURN sha1_hash(const unsigned char data[], unsigned long len, sha1_ctx ctx[1])
|
||||||
|
{ uint32_t pos = (uint32_t)((ctx->count[0] >> 3) & SHA1_MASK);
|
||||||
|
const unsigned char *sp = data;
|
||||||
|
unsigned char *w = (unsigned char*)ctx->wbuf;
|
||||||
|
#if SHA1_BITS == 1
|
||||||
|
uint32_t ofs = (ctx->count[0] & 7);
|
||||||
|
#else
|
||||||
|
len <<= 3;
|
||||||
|
#endif
|
||||||
|
if((ctx->count[0] += len) < len)
|
||||||
|
++(ctx->count[1]);
|
||||||
|
#if SHA1_BITS == 1
|
||||||
|
if(ofs) /* if not on a byte boundary */
|
||||||
|
{
|
||||||
|
if(ofs + len < 8) /* if no added bytes are needed */
|
||||||
|
{
|
||||||
|
w[pos] |= (*sp >> ofs);
|
||||||
|
}
|
||||||
|
else /* otherwise and add bytes */
|
||||||
|
{ unsigned char part = w[pos];
|
||||||
|
|
||||||
|
while((int)(ofs + (len -= 8)) >= 0)
|
||||||
|
{
|
||||||
|
w[pos++] = part | (*sp >> ofs);
|
||||||
|
part = *sp++ << (8 - ofs);
|
||||||
|
if(pos == SHA1_BLOCK_SIZE)
|
||||||
|
{
|
||||||
|
bsw_32(w, SHA1_BLOCK_SIZE >> 2);
|
||||||
|
sha1_compile(ctx); pos = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
w[pos] = part;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else /* data is byte aligned */
|
||||||
|
#endif
|
||||||
|
{ uint32_t space = SHA1_BLOCK_SIZE - pos;
|
||||||
|
|
||||||
|
while(len >= (space << 3))
|
||||||
|
{
|
||||||
|
memcpy(w + pos, sp, space);
|
||||||
|
bsw_32(w, SHA1_BLOCK_SIZE >> 2);
|
||||||
|
sha1_compile(ctx);
|
||||||
|
sp += space; len -= (space << 3);
|
||||||
|
space = SHA1_BLOCK_SIZE; pos = 0;
|
||||||
|
}
|
||||||
|
memcpy(w + pos, sp, (len + 7 * SHA1_BITS) >> 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SHA1 final padding and digest calculation */
|
||||||
|
|
||||||
|
VOID_RETURN sha1_end(unsigned char hval[], sha1_ctx ctx[1])
|
||||||
|
{ uint32_t i = (uint32_t)((ctx->count[0] >> 3) & SHA1_MASK), m1;
|
||||||
|
|
||||||
|
/* put bytes in the buffer in an order in which references to */
|
||||||
|
/* 32-bit words will put bytes with lower addresses into the */
|
||||||
|
/* top of 32 bit words on BOTH big and little endian machines */
|
||||||
|
bsw_32(ctx->wbuf, (i + 3 + SHA1_BITS) >> 2);
|
||||||
|
|
||||||
|
/* we now need to mask valid bytes and add the padding which is */
|
||||||
|
/* a single 1 bit and as many zero bits as necessary. Note that */
|
||||||
|
/* we can always add the first padding byte here because the */
|
||||||
|
/* buffer always has at least one empty slot */
|
||||||
|
m1 = (unsigned char)0x80 >> (ctx->count[0] & 7);
|
||||||
|
ctx->wbuf[i >> 2] &= ((0xffffff00 | (~m1 + 1)) << 8 * (~i & 3));
|
||||||
|
ctx->wbuf[i >> 2] |= (m1 << 8 * (~i & 3));
|
||||||
|
|
||||||
|
/* we need 9 or more empty positions, one for the padding byte */
|
||||||
|
/* (above) and eight for the length count. If there is not */
|
||||||
|
/* enough space, pad and empty the buffer */
|
||||||
|
if(i > SHA1_BLOCK_SIZE - 9)
|
||||||
|
{
|
||||||
|
if(i < 60) ctx->wbuf[15] = 0;
|
||||||
|
sha1_compile(ctx);
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
else /* compute a word index for the empty buffer positions */
|
||||||
|
i = (i >> 2) + 1;
|
||||||
|
|
||||||
|
while(i < 14) /* and zero pad all but last two positions */
|
||||||
|
ctx->wbuf[i++] = 0;
|
||||||
|
|
||||||
|
/* the following 32-bit length fields are assembled in the */
|
||||||
|
/* wrong byte order on little endian machines but this is */
|
||||||
|
/* corrected later since they are only ever used as 32-bit */
|
||||||
|
/* word values. */
|
||||||
|
ctx->wbuf[14] = ctx->count[1];
|
||||||
|
ctx->wbuf[15] = ctx->count[0];
|
||||||
|
sha1_compile(ctx);
|
||||||
|
|
||||||
|
/* extract the hash value as bytes in case the hash buffer is */
|
||||||
|
/* misaligned for 32-bit words */
|
||||||
|
for(i = 0; i < SHA1_DIGEST_SIZE; ++i)
|
||||||
|
hval[i] = ((ctx->hash[i >> 2] >> (8 * (~i & 3))) & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID_RETURN sha1(unsigned char hval[], const unsigned char data[], unsigned long len)
|
||||||
|
{ sha1_ctx cx[1];
|
||||||
|
|
||||||
|
sha1_begin(cx); sha1_hash(data, len, cx); sha1_end(hval, cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
72
SSZipArchive/minizip/aes/sha1.h
Normal file
72
SSZipArchive/minizip/aes/sha1.h
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
|
||||||
|
|
||||||
|
The redistribution and use of this software (with or without changes)
|
||||||
|
is allowed without the payment of fees or royalties provided that:
|
||||||
|
|
||||||
|
source code distributions include the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer;
|
||||||
|
|
||||||
|
binary distributions include the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer in their documentation.
|
||||||
|
|
||||||
|
This software is provided 'as is' with no explicit or implied warranties
|
||||||
|
in respect of its operation, including, but not limited to, correctness
|
||||||
|
and fitness for purpose.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Issue Date: 20/12/2007
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SHA1_H
|
||||||
|
#define _SHA1_H
|
||||||
|
|
||||||
|
#define SHA_1
|
||||||
|
|
||||||
|
/* define for bit or byte oriented SHA */
|
||||||
|
#if 1
|
||||||
|
# define SHA1_BITS 0 /* byte oriented */
|
||||||
|
#else
|
||||||
|
# define SHA1_BITS 1 /* bit oriented */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "brg_types.h"
|
||||||
|
|
||||||
|
#define SHA1_BLOCK_SIZE 64
|
||||||
|
#define SHA1_DIGEST_SIZE 20
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* type to hold the SHA256 context */
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{ uint32_t count[2];
|
||||||
|
uint32_t hash[SHA1_DIGEST_SIZE >> 2];
|
||||||
|
uint32_t wbuf[SHA1_BLOCK_SIZE >> 2];
|
||||||
|
} sha1_ctx;
|
||||||
|
|
||||||
|
/* Note that these prototypes are the same for both bit and */
|
||||||
|
/* byte oriented implementations. However the length fields */
|
||||||
|
/* are in bytes or bits as appropriate for the version used */
|
||||||
|
/* and bit sequences are input as arrays of bytes in which */
|
||||||
|
/* bit sequences run from the most to the least significant */
|
||||||
|
/* end of each byte. The value 'len' in sha1_hash for the */
|
||||||
|
/* byte oriented version of SHA1 is limited to 2^29 bytes, */
|
||||||
|
/* but multiple calls will handle longer data blocks. */
|
||||||
|
|
||||||
|
VOID_RETURN sha1_compile(sha1_ctx ctx[1]);
|
||||||
|
|
||||||
|
VOID_RETURN sha1_begin(sha1_ctx ctx[1]);
|
||||||
|
VOID_RETURN sha1_hash(const unsigned char data[], unsigned long len, sha1_ctx ctx[1]);
|
||||||
|
VOID_RETURN sha1_end(unsigned char hval[], sha1_ctx ctx[1]);
|
||||||
|
VOID_RETURN sha1(unsigned char hval[], const unsigned char data[], unsigned long len);
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
144
SSZipArchive/minizip/crypt.c
Normal file
144
SSZipArchive/minizip/crypt.c
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
/* crypt.c -- base code for traditional PKWARE encryption
|
||||||
|
Version 1.2.0, September 16th, 2017
|
||||||
|
|
||||||
|
Copyright (C) 2012-2017 Nathan Moinvaziri
|
||||||
|
https://github.com/nmoinvaz/minizip
|
||||||
|
Copyright (C) 1998-2005 Gilles Vollant
|
||||||
|
Modifications for Info-ZIP crypting
|
||||||
|
http://www.winimage.com/zLibDll/minizip.html
|
||||||
|
Copyright (C) 2003 Terry Thorsen
|
||||||
|
|
||||||
|
This code is a modified version of crypting code in Info-ZIP distribution
|
||||||
|
|
||||||
|
Copyright (C) 1990-2000 Info-ZIP. All rights reserved.
|
||||||
|
|
||||||
|
This program is distributed under the terms of the same license as zlib.
|
||||||
|
See the accompanying LICENSE file for the full text of the license.
|
||||||
|
|
||||||
|
This encryption code is a direct transcription of the algorithm from
|
||||||
|
Roger Schlafly, described by Phil Katz in the file appnote.txt. This
|
||||||
|
file (appnote.txt) is distributed with the PKZIP program (even in the
|
||||||
|
version without encryption capabilities).
|
||||||
|
|
||||||
|
If you don't need crypting in your application, just define symbols
|
||||||
|
NOCRYPT and NOUNCRYPT.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
# include <windows.h>
|
||||||
|
# include <wincrypt.h>
|
||||||
|
#else
|
||||||
|
# include <sys/stat.h>
|
||||||
|
# include <fcntl.h>
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "zlib.h"
|
||||||
|
|
||||||
|
#include "crypt.h"
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
|
#define CRC32(c, b) ((*(pcrc_32_tab+(((uint32_t)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
|
uint8_t decrypt_byte(uint32_t *pkeys)
|
||||||
|
{
|
||||||
|
unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
|
||||||
|
* unpredictable manner on 16-bit systems; not a problem
|
||||||
|
* with any known compiler so far, though */
|
||||||
|
|
||||||
|
temp = ((uint32_t)(*(pkeys+2)) & 0xffff) | 2;
|
||||||
|
return (uint8_t)(((temp * (temp ^ 1)) >> 8) & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t update_keys(uint32_t *pkeys, const z_crc_t *pcrc_32_tab, int32_t c)
|
||||||
|
{
|
||||||
|
(*(pkeys+0)) = (uint32_t)CRC32((*(pkeys+0)), c);
|
||||||
|
(*(pkeys+1)) += (*(pkeys+0)) & 0xff;
|
||||||
|
(*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
|
||||||
|
{
|
||||||
|
register int32_t keyshift = (int32_t)((*(pkeys + 1)) >> 24);
|
||||||
|
(*(pkeys+2)) = (uint32_t)CRC32((*(pkeys+2)), keyshift);
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_keys(const char *passwd, uint32_t *pkeys, const z_crc_t *pcrc_32_tab)
|
||||||
|
{
|
||||||
|
*(pkeys+0) = 305419896L;
|
||||||
|
*(pkeys+1) = 591751049L;
|
||||||
|
*(pkeys+2) = 878082192L;
|
||||||
|
while (*passwd != 0)
|
||||||
|
{
|
||||||
|
update_keys(pkeys, pcrc_32_tab, *passwd);
|
||||||
|
passwd += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
|
int cryptrand(unsigned char *buf, unsigned int len)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
HCRYPTPROV provider;
|
||||||
|
unsigned __int64 pentium_tsc[1];
|
||||||
|
int rlen = 0;
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
|
||||||
|
if (CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
|
||||||
|
{
|
||||||
|
result = CryptGenRandom(provider, len, buf);
|
||||||
|
CryptReleaseContext(provider, 0);
|
||||||
|
if (result)
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (rlen = 0; rlen < (int)len; ++rlen)
|
||||||
|
{
|
||||||
|
if (rlen % 8 == 0)
|
||||||
|
QueryPerformanceCounter((LARGE_INTEGER *)pentium_tsc);
|
||||||
|
buf[rlen] = ((unsigned char*)pentium_tsc)[rlen % 8];
|
||||||
|
}
|
||||||
|
|
||||||
|
return rlen;
|
||||||
|
#else
|
||||||
|
arc4random_buf(buf, len);
|
||||||
|
return len;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int crypthead(const char *passwd, uint8_t *buf, int buf_size, uint32_t *pkeys,
|
||||||
|
const z_crc_t *pcrc_32_tab, uint8_t verify1, uint8_t verify2)
|
||||||
|
{
|
||||||
|
uint8_t n = 0; /* index in random header */
|
||||||
|
uint8_t header[RAND_HEAD_LEN-2]; /* random header */
|
||||||
|
uint16_t t = 0; /* temporary */
|
||||||
|
|
||||||
|
if (buf_size < RAND_HEAD_LEN)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
init_keys(passwd, pkeys, pcrc_32_tab);
|
||||||
|
|
||||||
|
/* First generate RAND_HEAD_LEN-2 random bytes. */
|
||||||
|
cryptrand(header, RAND_HEAD_LEN-2);
|
||||||
|
|
||||||
|
/* Encrypt random header (last two bytes is high word of crc) */
|
||||||
|
init_keys(passwd, pkeys, pcrc_32_tab);
|
||||||
|
|
||||||
|
for (n = 0; n < RAND_HEAD_LEN-2; n++)
|
||||||
|
buf[n] = (uint8_t)zencode(pkeys, pcrc_32_tab, header[n], t);
|
||||||
|
|
||||||
|
buf[n++] = (uint8_t)zencode(pkeys, pcrc_32_tab, verify1, t);
|
||||||
|
buf[n++] = (uint8_t)zencode(pkeys, pcrc_32_tab, verify2, t);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
64
SSZipArchive/minizip/crypt.h
Normal file
64
SSZipArchive/minizip/crypt.h
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
/* crypt.h -- base code for traditional PKWARE encryption
|
||||||
|
Version 1.2.0, September 16th, 2017
|
||||||
|
|
||||||
|
Copyright (C) 2012-2017 Nathan Moinvaziri
|
||||||
|
https://github.com/nmoinvaz/minizip
|
||||||
|
Copyright (C) 1998-2005 Gilles Vollant
|
||||||
|
Modifications for Info-ZIP crypting
|
||||||
|
http://www.winimage.com/zLibDll/minizip.html
|
||||||
|
Copyright (C) 2003 Terry Thorsen
|
||||||
|
|
||||||
|
This code is a modified version of crypting code in Info-ZIP distribution
|
||||||
|
|
||||||
|
Copyright (C) 1990-2000 Info-ZIP. All rights reserved.
|
||||||
|
|
||||||
|
This program is distributed under the terms of the same license as zlib.
|
||||||
|
See the accompanying LICENSE file for the full text of the license.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MINICRYPT_H
|
||||||
|
#define _MINICRYPT_H
|
||||||
|
|
||||||
|
#if ZLIB_VERNUM < 0x1270
|
||||||
|
typedef unsigned long z_crc_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define RAND_HEAD_LEN 12
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
|
#define zdecode(pkeys,pcrc_32_tab,c) \
|
||||||
|
(update_keys(pkeys,pcrc_32_tab, c ^= decrypt_byte(pkeys)))
|
||||||
|
|
||||||
|
#define zencode(pkeys,pcrc_32_tab,c,t) \
|
||||||
|
(t = decrypt_byte(pkeys), update_keys(pkeys,pcrc_32_tab,c), t^(c))
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
|
/* Return the next byte in the pseudo-random sequence */
|
||||||
|
uint8_t decrypt_byte(uint32_t *pkeys);
|
||||||
|
|
||||||
|
/* Update the encryption keys with the next byte of plain text */
|
||||||
|
uint8_t update_keys(uint32_t *pkeys, const z_crc_t *pcrc_32_tab, int32_t c);
|
||||||
|
|
||||||
|
/* Initialize the encryption keys and the random header according to the given password. */
|
||||||
|
void init_keys(const char *passwd, uint32_t *pkeys, const z_crc_t *pcrc_32_tab);
|
||||||
|
|
||||||
|
/* Generate cryptographically secure random numbers */
|
||||||
|
int cryptrand(unsigned char *buf, unsigned int len);
|
||||||
|
|
||||||
|
/* Create encryption header */
|
||||||
|
int crypthead(const char *passwd, uint8_t *buf, int buf_size, uint32_t *pkeys,
|
||||||
|
const z_crc_t *pcrc_32_tab, uint8_t verify1, uint8_t verify2);
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
353
SSZipArchive/minizip/ioapi.c
Normal file
353
SSZipArchive/minizip/ioapi.c
Normal file
@@ -0,0 +1,353 @@
|
|||||||
|
/* ioapi.c -- IO base function header for compress/uncompress .zip
|
||||||
|
part of the MiniZip project
|
||||||
|
|
||||||
|
Copyright (C) 2012-2017 Nathan Moinvaziri
|
||||||
|
https://github.com/nmoinvaz/minizip
|
||||||
|
Modifications for Zip64 support
|
||||||
|
Copyright (C) 2009-2010 Mathias Svensson
|
||||||
|
http://result42.com
|
||||||
|
Copyright (C) 1998-2010 Gilles Vollant
|
||||||
|
http://www.winimage.com/zLibDll/minizip.html
|
||||||
|
|
||||||
|
This program is distributed under the terms of the same license as zlib.
|
||||||
|
See the accompanying LICENSE file for the full text of the license.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if defined unix || defined __APPLE__
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "ioapi.h"
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
# define snprintf _snprintf
|
||||||
|
#endif
|
||||||
|
|
||||||
|
voidpf call_zopen64(const zlib_filefunc64_32_def *pfilefunc, const void *filename, int mode)
|
||||||
|
{
|
||||||
|
if (pfilefunc->zfile_func64.zopen64_file != NULL)
|
||||||
|
return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque, filename, mode);
|
||||||
|
return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque, (const char*)filename, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
voidpf call_zopendisk64(const zlib_filefunc64_32_def *pfilefunc, voidpf filestream, uint32_t number_disk, int mode)
|
||||||
|
{
|
||||||
|
if (pfilefunc->zfile_func64.zopendisk64_file != NULL)
|
||||||
|
return (*(pfilefunc->zfile_func64.zopendisk64_file)) (pfilefunc->zfile_func64.opaque, filestream, number_disk, mode);
|
||||||
|
return (*(pfilefunc->zopendisk32_file))(pfilefunc->zfile_func64.opaque, filestream, number_disk, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
long call_zseek64(const zlib_filefunc64_32_def *pfilefunc, voidpf filestream, uint64_t offset, int origin)
|
||||||
|
{
|
||||||
|
uint32_t offset_truncated = 0;
|
||||||
|
if (pfilefunc->zfile_func64.zseek64_file != NULL)
|
||||||
|
return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin);
|
||||||
|
offset_truncated = (uint32_t)offset;
|
||||||
|
if (offset_truncated != offset)
|
||||||
|
return -1;
|
||||||
|
return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream, offset_truncated, origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t call_ztell64(const zlib_filefunc64_32_def *pfilefunc, voidpf filestream)
|
||||||
|
{
|
||||||
|
uint64_t position;
|
||||||
|
if (pfilefunc->zfile_func64.zseek64_file != NULL)
|
||||||
|
return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque, filestream);
|
||||||
|
position = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque, filestream);
|
||||||
|
if ((position) == UINT32_MAX)
|
||||||
|
return (uint64_t)-1;
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def *p_filefunc64_32, const zlib_filefunc_def *p_filefunc32)
|
||||||
|
{
|
||||||
|
p_filefunc64_32->zfile_func64.zopen64_file = NULL;
|
||||||
|
p_filefunc64_32->zfile_func64.zopendisk64_file = NULL;
|
||||||
|
p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file;
|
||||||
|
p_filefunc64_32->zopendisk32_file = p_filefunc32->zopendisk_file;
|
||||||
|
p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
|
||||||
|
p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file;
|
||||||
|
p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file;
|
||||||
|
p_filefunc64_32->zfile_func64.ztell64_file = NULL;
|
||||||
|
p_filefunc64_32->zfile_func64.zseek64_file = NULL;
|
||||||
|
p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file;
|
||||||
|
p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
|
||||||
|
p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque;
|
||||||
|
p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file;
|
||||||
|
p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file;
|
||||||
|
}
|
||||||
|
|
||||||
|
static voidpf ZCALLBACK fopen_file_func(ZIP_UNUSED voidpf opaque, const char *filename, int mode);
|
||||||
|
static uint32_t ZCALLBACK fread_file_func(voidpf opaque, voidpf stream, void* buf, uint32_t size);
|
||||||
|
static uint32_t ZCALLBACK fwrite_file_func(voidpf opaque, voidpf stream, const void *buf, uint32_t size);
|
||||||
|
static uint64_t ZCALLBACK ftell64_file_func(voidpf opaque, voidpf stream);
|
||||||
|
static long ZCALLBACK fseek64_file_func(voidpf opaque, voidpf stream, uint64_t offset, int origin);
|
||||||
|
static int ZCALLBACK fclose_file_func(voidpf opaque, voidpf stream);
|
||||||
|
static int ZCALLBACK ferror_file_func(voidpf opaque, voidpf stream);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
FILE *file;
|
||||||
|
int filenameLength;
|
||||||
|
void *filename;
|
||||||
|
} FILE_IOPOSIX;
|
||||||
|
|
||||||
|
static voidpf file_build_ioposix(FILE *file, const char *filename)
|
||||||
|
{
|
||||||
|
FILE_IOPOSIX *ioposix = NULL;
|
||||||
|
if (file == NULL)
|
||||||
|
return NULL;
|
||||||
|
ioposix = (FILE_IOPOSIX*)malloc(sizeof(FILE_IOPOSIX));
|
||||||
|
ioposix->file = file;
|
||||||
|
ioposix->filenameLength = (int)strlen(filename) + 1;
|
||||||
|
ioposix->filename = (char*)malloc(ioposix->filenameLength * sizeof(char));
|
||||||
|
strncpy((char*)ioposix->filename, filename, ioposix->filenameLength);
|
||||||
|
return (voidpf)ioposix;
|
||||||
|
}
|
||||||
|
|
||||||
|
static voidpf ZCALLBACK fopen_file_func(ZIP_UNUSED voidpf opaque, const char *filename, int mode)
|
||||||
|
{
|
||||||
|
FILE* file = NULL;
|
||||||
|
const char *mode_fopen = NULL;
|
||||||
|
if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ)
|
||||||
|
mode_fopen = "rb";
|
||||||
|
else if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
|
||||||
|
mode_fopen = "r+b";
|
||||||
|
else if (mode & ZLIB_FILEFUNC_MODE_CREATE)
|
||||||
|
mode_fopen = "wb";
|
||||||
|
|
||||||
|
if ((filename != NULL) && (mode_fopen != NULL))
|
||||||
|
{
|
||||||
|
file = fopen(filename, mode_fopen);
|
||||||
|
return file_build_ioposix(file, filename);
|
||||||
|
}
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
static voidpf ZCALLBACK fopen64_file_func(ZIP_UNUSED voidpf opaque, const void *filename, int mode)
|
||||||
|
{
|
||||||
|
FILE* file = NULL;
|
||||||
|
const char *mode_fopen = NULL;
|
||||||
|
if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ)
|
||||||
|
mode_fopen = "rb";
|
||||||
|
else if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
|
||||||
|
mode_fopen = "r+b";
|
||||||
|
else if (mode & ZLIB_FILEFUNC_MODE_CREATE)
|
||||||
|
mode_fopen = "wb";
|
||||||
|
|
||||||
|
if ((filename != NULL) && (mode_fopen != NULL))
|
||||||
|
{
|
||||||
|
file = fopen64((const char*)filename, mode_fopen);
|
||||||
|
return file_build_ioposix(file, (const char*)filename);
|
||||||
|
}
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
static voidpf ZCALLBACK fopendisk64_file_func(voidpf opaque, voidpf stream, uint32_t number_disk, int mode)
|
||||||
|
{
|
||||||
|
FILE_IOPOSIX *ioposix = NULL;
|
||||||
|
char *diskFilename = NULL;
|
||||||
|
voidpf ret = NULL;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
if (stream == NULL)
|
||||||
|
return NULL;
|
||||||
|
ioposix = (FILE_IOPOSIX*)stream;
|
||||||
|
diskFilename = (char*)malloc(ioposix->filenameLength * sizeof(char));
|
||||||
|
strncpy(diskFilename, (const char*)ioposix->filename, ioposix->filenameLength);
|
||||||
|
for (i = ioposix->filenameLength - 1; i >= 0; i -= 1)
|
||||||
|
{
|
||||||
|
if (diskFilename[i] != '.')
|
||||||
|
continue;
|
||||||
|
snprintf(&diskFilename[i], ioposix->filenameLength - i, ".z%02u", number_disk + 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i >= 0)
|
||||||
|
ret = fopen64_file_func(opaque, diskFilename, mode);
|
||||||
|
free(diskFilename);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static voidpf ZCALLBACK fopendisk_file_func(voidpf opaque, voidpf stream, uint32_t number_disk, int mode)
|
||||||
|
{
|
||||||
|
FILE_IOPOSIX *ioposix = NULL;
|
||||||
|
char *diskFilename = NULL;
|
||||||
|
voidpf ret = NULL;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
if (stream == NULL)
|
||||||
|
return NULL;
|
||||||
|
ioposix = (FILE_IOPOSIX*)stream;
|
||||||
|
diskFilename = (char*)malloc(ioposix->filenameLength * sizeof(char));
|
||||||
|
strncpy(diskFilename, (const char*)ioposix->filename, ioposix->filenameLength);
|
||||||
|
for (i = ioposix->filenameLength - 1; i >= 0; i -= 1)
|
||||||
|
{
|
||||||
|
if (diskFilename[i] != '.')
|
||||||
|
continue;
|
||||||
|
snprintf(&diskFilename[i], ioposix->filenameLength - i, ".z%02u", number_disk + 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i >= 0)
|
||||||
|
ret = fopen_file_func(opaque, diskFilename, mode);
|
||||||
|
free(diskFilename);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t ZCALLBACK fread_file_func(ZIP_UNUSED voidpf opaque, voidpf stream, void* buf, uint32_t size)
|
||||||
|
{
|
||||||
|
FILE_IOPOSIX *ioposix = NULL;
|
||||||
|
uint32_t read = (uint32_t)-1;
|
||||||
|
if (stream == NULL)
|
||||||
|
return read;
|
||||||
|
ioposix = (FILE_IOPOSIX*)stream;
|
||||||
|
read = (uint32_t)fread(buf, 1, (size_t)size, ioposix->file);
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t ZCALLBACK fwrite_file_func(ZIP_UNUSED voidpf opaque, voidpf stream, const void *buf, uint32_t size)
|
||||||
|
{
|
||||||
|
FILE_IOPOSIX *ioposix = NULL;
|
||||||
|
uint32_t written = (uint32_t)-1;
|
||||||
|
if (stream == NULL)
|
||||||
|
return written;
|
||||||
|
ioposix = (FILE_IOPOSIX*)stream;
|
||||||
|
written = (uint32_t)fwrite(buf, 1, (size_t)size, ioposix->file);
|
||||||
|
return written;
|
||||||
|
}
|
||||||
|
|
||||||
|
static long ZCALLBACK ftell_file_func(ZIP_UNUSED voidpf opaque, voidpf stream)
|
||||||
|
{
|
||||||
|
FILE_IOPOSIX *ioposix = NULL;
|
||||||
|
long ret = -1;
|
||||||
|
if (stream == NULL)
|
||||||
|
return ret;
|
||||||
|
ioposix = (FILE_IOPOSIX*)stream;
|
||||||
|
ret = ftell(ioposix->file);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint64_t ZCALLBACK ftell64_file_func(ZIP_UNUSED voidpf opaque, voidpf stream)
|
||||||
|
{
|
||||||
|
FILE_IOPOSIX *ioposix = NULL;
|
||||||
|
uint64_t ret = (uint64_t)-1;
|
||||||
|
if (stream == NULL)
|
||||||
|
return ret;
|
||||||
|
ioposix = (FILE_IOPOSIX*)stream;
|
||||||
|
ret = ftello64(ioposix->file);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static long ZCALLBACK fseek_file_func(ZIP_UNUSED voidpf opaque, voidpf stream, uint32_t offset, int origin)
|
||||||
|
{
|
||||||
|
FILE_IOPOSIX *ioposix = NULL;
|
||||||
|
int fseek_origin = 0;
|
||||||
|
long ret = 0;
|
||||||
|
|
||||||
|
if (stream == NULL)
|
||||||
|
return -1;
|
||||||
|
ioposix = (FILE_IOPOSIX*)stream;
|
||||||
|
|
||||||
|
switch (origin)
|
||||||
|
{
|
||||||
|
case ZLIB_FILEFUNC_SEEK_CUR:
|
||||||
|
fseek_origin = SEEK_CUR;
|
||||||
|
break;
|
||||||
|
case ZLIB_FILEFUNC_SEEK_END:
|
||||||
|
fseek_origin = SEEK_END;
|
||||||
|
break;
|
||||||
|
case ZLIB_FILEFUNC_SEEK_SET:
|
||||||
|
fseek_origin = SEEK_SET;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (fseek(ioposix->file, offset, fseek_origin) != 0)
|
||||||
|
ret = -1;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static long ZCALLBACK fseek64_file_func(ZIP_UNUSED voidpf opaque, voidpf stream, uint64_t offset, int origin)
|
||||||
|
{
|
||||||
|
FILE_IOPOSIX *ioposix = NULL;
|
||||||
|
int fseek_origin = 0;
|
||||||
|
long ret = 0;
|
||||||
|
|
||||||
|
if (stream == NULL)
|
||||||
|
return -1;
|
||||||
|
ioposix = (FILE_IOPOSIX*)stream;
|
||||||
|
|
||||||
|
switch (origin)
|
||||||
|
{
|
||||||
|
case ZLIB_FILEFUNC_SEEK_CUR:
|
||||||
|
fseek_origin = SEEK_CUR;
|
||||||
|
break;
|
||||||
|
case ZLIB_FILEFUNC_SEEK_END:
|
||||||
|
fseek_origin = SEEK_END;
|
||||||
|
break;
|
||||||
|
case ZLIB_FILEFUNC_SEEK_SET:
|
||||||
|
fseek_origin = SEEK_SET;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fseeko64(ioposix->file, offset, fseek_origin) != 0)
|
||||||
|
ret = -1;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ZCALLBACK fclose_file_func(ZIP_UNUSED voidpf opaque, voidpf stream)
|
||||||
|
{
|
||||||
|
FILE_IOPOSIX *ioposix = NULL;
|
||||||
|
int ret = -1;
|
||||||
|
if (stream == NULL)
|
||||||
|
return ret;
|
||||||
|
ioposix = (FILE_IOPOSIX*)stream;
|
||||||
|
if (ioposix->filename != NULL)
|
||||||
|
free(ioposix->filename);
|
||||||
|
ret = fclose(ioposix->file);
|
||||||
|
free(ioposix);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ZCALLBACK ferror_file_func(ZIP_UNUSED voidpf opaque, voidpf stream)
|
||||||
|
{
|
||||||
|
FILE_IOPOSIX *ioposix = NULL;
|
||||||
|
int ret = -1;
|
||||||
|
if (stream == NULL)
|
||||||
|
return ret;
|
||||||
|
ioposix = (FILE_IOPOSIX*)stream;
|
||||||
|
ret = ferror(ioposix->file);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fill_fopen_filefunc(zlib_filefunc_def *pzlib_filefunc_def)
|
||||||
|
{
|
||||||
|
pzlib_filefunc_def->zopen_file = fopen_file_func;
|
||||||
|
pzlib_filefunc_def->zopendisk_file = fopendisk_file_func;
|
||||||
|
pzlib_filefunc_def->zread_file = fread_file_func;
|
||||||
|
pzlib_filefunc_def->zwrite_file = fwrite_file_func;
|
||||||
|
pzlib_filefunc_def->ztell_file = ftell_file_func;
|
||||||
|
pzlib_filefunc_def->zseek_file = fseek_file_func;
|
||||||
|
pzlib_filefunc_def->zclose_file = fclose_file_func;
|
||||||
|
pzlib_filefunc_def->zerror_file = ferror_file_func;
|
||||||
|
pzlib_filefunc_def->opaque = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fill_fopen64_filefunc(zlib_filefunc64_def *pzlib_filefunc_def)
|
||||||
|
{
|
||||||
|
pzlib_filefunc_def->zopen64_file = fopen64_file_func;
|
||||||
|
pzlib_filefunc_def->zopendisk64_file = fopendisk64_file_func;
|
||||||
|
pzlib_filefunc_def->zread_file = fread_file_func;
|
||||||
|
pzlib_filefunc_def->zwrite_file = fwrite_file_func;
|
||||||
|
pzlib_filefunc_def->ztell64_file = ftell64_file_func;
|
||||||
|
pzlib_filefunc_def->zseek64_file = fseek64_file_func;
|
||||||
|
pzlib_filefunc_def->zclose_file = fclose_file_func;
|
||||||
|
pzlib_filefunc_def->zerror_file = ferror_file_func;
|
||||||
|
pzlib_filefunc_def->opaque = NULL;
|
||||||
|
}
|
||||||
154
SSZipArchive/minizip/ioapi.h
Normal file
154
SSZipArchive/minizip/ioapi.h
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
/* ioapi.h -- IO base function header for compress/uncompress .zip
|
||||||
|
part of the MiniZip project
|
||||||
|
|
||||||
|
Copyright (C) 2012-2017 Nathan Moinvaziri
|
||||||
|
https://github.com/nmoinvaz/minizip
|
||||||
|
Copyright (C) 2009-2010 Mathias Svensson
|
||||||
|
Modifications for Zip64 support
|
||||||
|
http://result42.com
|
||||||
|
Copyright (C) 1998-2010 Gilles Vollant
|
||||||
|
http://www.winimage.com/zLibDll/minizip.html
|
||||||
|
|
||||||
|
This program is distributed under the terms of the same license as zlib.
|
||||||
|
See the accompanying LICENSE file for the full text of the license.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ZLIBIOAPI64_H
|
||||||
|
#define _ZLIBIOAPI64_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "zlib.h"
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
# define ZIP_UNUSED __attribute__((__unused__))
|
||||||
|
#else
|
||||||
|
# define ZIP_UNUSED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(USE_FILE32API)
|
||||||
|
# define fopen64 fopen
|
||||||
|
# define ftello64 ftell
|
||||||
|
# define fseeko64 fseek
|
||||||
|
#else
|
||||||
|
# if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) || defined(__APPLE__) || defined(__ANDROID__)
|
||||||
|
# define fopen64 fopen
|
||||||
|
# define ftello64 ftello
|
||||||
|
# define fseeko64 fseeko
|
||||||
|
# endif
|
||||||
|
# ifdef _MSC_VER
|
||||||
|
# define fopen64 fopen
|
||||||
|
# if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC)))
|
||||||
|
# define ftello64 _ftelli64
|
||||||
|
# define fseeko64 _fseeki64
|
||||||
|
# else /* old MSC */
|
||||||
|
# define ftello64 ftell
|
||||||
|
# define fseeko64 fseek
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ZLIB_FILEFUNC_SEEK_CUR (1)
|
||||||
|
#define ZLIB_FILEFUNC_SEEK_END (2)
|
||||||
|
#define ZLIB_FILEFUNC_SEEK_SET (0)
|
||||||
|
|
||||||
|
#define ZLIB_FILEFUNC_MODE_READ (1)
|
||||||
|
#define ZLIB_FILEFUNC_MODE_WRITE (2)
|
||||||
|
#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
|
||||||
|
#define ZLIB_FILEFUNC_MODE_EXISTING (4)
|
||||||
|
#define ZLIB_FILEFUNC_MODE_CREATE (8)
|
||||||
|
|
||||||
|
#ifndef ZCALLBACK
|
||||||
|
# if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || \
|
||||||
|
defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
|
||||||
|
# define ZCALLBACK CALLBACK
|
||||||
|
# else
|
||||||
|
# define ZCALLBACK
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef voidpf (ZCALLBACK *open_file_func) (voidpf opaque, const char *filename, int mode);
|
||||||
|
typedef voidpf (ZCALLBACK *opendisk_file_func) (voidpf opaque, voidpf stream, uint32_t number_disk, int mode);
|
||||||
|
typedef uint32_t (ZCALLBACK *read_file_func) (voidpf opaque, voidpf stream, void* buf, uint32_t size);
|
||||||
|
typedef uint32_t (ZCALLBACK *write_file_func) (voidpf opaque, voidpf stream, const void *buf, uint32_t size);
|
||||||
|
typedef int (ZCALLBACK *close_file_func) (voidpf opaque, voidpf stream);
|
||||||
|
typedef int (ZCALLBACK *error_file_func) (voidpf opaque, voidpf stream);
|
||||||
|
|
||||||
|
typedef long (ZCALLBACK *tell_file_func) (voidpf opaque, voidpf stream);
|
||||||
|
typedef long (ZCALLBACK *seek_file_func) (voidpf opaque, voidpf stream, uint32_t offset, int origin);
|
||||||
|
|
||||||
|
/* here is the "old" 32 bits structure structure */
|
||||||
|
typedef struct zlib_filefunc_def_s
|
||||||
|
{
|
||||||
|
open_file_func zopen_file;
|
||||||
|
opendisk_file_func zopendisk_file;
|
||||||
|
read_file_func zread_file;
|
||||||
|
write_file_func zwrite_file;
|
||||||
|
tell_file_func ztell_file;
|
||||||
|
seek_file_func zseek_file;
|
||||||
|
close_file_func zclose_file;
|
||||||
|
error_file_func zerror_file;
|
||||||
|
voidpf opaque;
|
||||||
|
} zlib_filefunc_def;
|
||||||
|
|
||||||
|
typedef uint64_t (ZCALLBACK *tell64_file_func) (voidpf opaque, voidpf stream);
|
||||||
|
typedef long (ZCALLBACK *seek64_file_func) (voidpf opaque, voidpf stream, uint64_t offset, int origin);
|
||||||
|
typedef voidpf (ZCALLBACK *open64_file_func) (voidpf opaque, const void *filename, int mode);
|
||||||
|
typedef voidpf (ZCALLBACK *opendisk64_file_func)(voidpf opaque, voidpf stream, uint32_t number_disk, int mode);
|
||||||
|
|
||||||
|
typedef struct zlib_filefunc64_def_s
|
||||||
|
{
|
||||||
|
open64_file_func zopen64_file;
|
||||||
|
opendisk64_file_func zopendisk64_file;
|
||||||
|
read_file_func zread_file;
|
||||||
|
write_file_func zwrite_file;
|
||||||
|
tell64_file_func ztell64_file;
|
||||||
|
seek64_file_func zseek64_file;
|
||||||
|
close_file_func zclose_file;
|
||||||
|
error_file_func zerror_file;
|
||||||
|
voidpf opaque;
|
||||||
|
} zlib_filefunc64_def;
|
||||||
|
|
||||||
|
void fill_fopen_filefunc(zlib_filefunc_def *pzlib_filefunc_def);
|
||||||
|
void fill_fopen64_filefunc(zlib_filefunc64_def *pzlib_filefunc_def);
|
||||||
|
|
||||||
|
/* now internal definition, only for zip.c and unzip.h */
|
||||||
|
typedef struct zlib_filefunc64_32_def_s
|
||||||
|
{
|
||||||
|
zlib_filefunc64_def zfile_func64;
|
||||||
|
open_file_func zopen32_file;
|
||||||
|
opendisk_file_func zopendisk32_file;
|
||||||
|
tell_file_func ztell32_file;
|
||||||
|
seek_file_func zseek32_file;
|
||||||
|
} zlib_filefunc64_32_def;
|
||||||
|
|
||||||
|
#define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size))
|
||||||
|
#define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size))
|
||||||
|
/*#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream))*/
|
||||||
|
/*#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode))*/
|
||||||
|
#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream))
|
||||||
|
#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream))
|
||||||
|
|
||||||
|
voidpf call_zopen64(const zlib_filefunc64_32_def *pfilefunc,const void*filename, int mode);
|
||||||
|
voidpf call_zopendisk64(const zlib_filefunc64_32_def *pfilefunc, voidpf filestream, uint32_t number_disk, int mode);
|
||||||
|
long call_zseek64(const zlib_filefunc64_32_def *pfilefunc, voidpf filestream, uint64_t offset, int origin);
|
||||||
|
uint64_t call_ztell64(const zlib_filefunc64_32_def *pfilefunc, voidpf filestream);
|
||||||
|
|
||||||
|
void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def *p_filefunc64_32, const zlib_filefunc_def *p_filefunc32);
|
||||||
|
|
||||||
|
#define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode)))
|
||||||
|
#define ZOPENDISK64(filefunc,filestream,diskn,mode) (call_zopendisk64((&(filefunc)),(filestream),(diskn),(mode)))
|
||||||
|
#define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream)))
|
||||||
|
#define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode)))
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
461
SSZipArchive/minizip/ioapi_buf.c
Normal file
461
SSZipArchive/minizip/ioapi_buf.c
Normal file
@@ -0,0 +1,461 @@
|
|||||||
|
/* ioapi_buf.c -- IO base function header for compress/uncompress .zip
|
||||||
|
files using zlib + zip or unzip API
|
||||||
|
|
||||||
|
This version of ioapi is designed to buffer IO.
|
||||||
|
|
||||||
|
Copyright (C) 2012-2017 Nathan Moinvaziri
|
||||||
|
https://github.com/nmoinvaz/minizip
|
||||||
|
|
||||||
|
This program is distributed under the terms of the same license as zlib.
|
||||||
|
See the accompanying LICENSE file for the full text of the license.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include "zlib.h"
|
||||||
|
#include "ioapi.h"
|
||||||
|
|
||||||
|
#include "ioapi_buf.h"
|
||||||
|
|
||||||
|
#ifndef IOBUF_BUFFERSIZE
|
||||||
|
# define IOBUF_BUFFERSIZE (UINT16_MAX)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
# include <conio.h>
|
||||||
|
# define PRINTF _cprintf
|
||||||
|
# define VPRINTF _vcprintf
|
||||||
|
#else
|
||||||
|
# define PRINTF printf
|
||||||
|
# define VPRINTF vprintf
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//#define IOBUF_VERBOSE
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#ifndef max
|
||||||
|
#define max(x,y) ({ \
|
||||||
|
const __typeof__(x) _x = (x); \
|
||||||
|
const __typeof__(y) _y = (y); \
|
||||||
|
(void) (&_x == &_y); \
|
||||||
|
_x > _y ? _x : _y; })
|
||||||
|
#endif /* __GNUC__ */
|
||||||
|
|
||||||
|
#ifndef min
|
||||||
|
#define min(x,y) ({ \
|
||||||
|
const __typeof__(x) _x = (x); \
|
||||||
|
const __typeof__(y) _y = (y); \
|
||||||
|
(void) (&_x == &_y); \
|
||||||
|
_x < _y ? _x : _y; })
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct ourstream_s {
|
||||||
|
char readbuf[IOBUF_BUFFERSIZE];
|
||||||
|
uint32_t readbuf_len;
|
||||||
|
uint32_t readbuf_pos;
|
||||||
|
uint32_t readbuf_hits;
|
||||||
|
uint32_t readbuf_misses;
|
||||||
|
char writebuf[IOBUF_BUFFERSIZE];
|
||||||
|
uint32_t writebuf_len;
|
||||||
|
uint32_t writebuf_pos;
|
||||||
|
uint32_t writebuf_hits;
|
||||||
|
uint32_t writebuf_misses;
|
||||||
|
uint64_t position;
|
||||||
|
voidpf stream;
|
||||||
|
} ourstream_t;
|
||||||
|
|
||||||
|
#if defined(IOBUF_VERBOSE)
|
||||||
|
# define print_buf(o,s,f,...) print_buf_internal(o,s,f,__VA_ARGS__);
|
||||||
|
#else
|
||||||
|
# define print_buf(o,s,f,...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void print_buf_internal(ZIP_UNUSED voidpf opaque, voidpf stream, char *format, ...)
|
||||||
|
{
|
||||||
|
ourstream_t *streamio = (ourstream_t *)stream;
|
||||||
|
va_list arglist;
|
||||||
|
PRINTF("Buf stream %p - ", streamio);
|
||||||
|
va_start(arglist, format);
|
||||||
|
VPRINTF(format, arglist);
|
||||||
|
va_end(arglist);
|
||||||
|
}
|
||||||
|
|
||||||
|
voidpf fopen_buf_internal_func(ZIP_UNUSED voidpf opaque, voidpf stream, ZIP_UNUSED uint32_t number_disk, ZIP_UNUSED int mode)
|
||||||
|
{
|
||||||
|
ourstream_t *streamio = NULL;
|
||||||
|
if (stream == NULL)
|
||||||
|
return NULL;
|
||||||
|
streamio = (ourstream_t *)malloc(sizeof(ourstream_t));
|
||||||
|
if (streamio == NULL)
|
||||||
|
return NULL;
|
||||||
|
memset(streamio, 0, sizeof(ourstream_t));
|
||||||
|
streamio->stream = stream;
|
||||||
|
print_buf(opaque, streamio, "open [num %d mode %d]\n", number_disk, mode);
|
||||||
|
return streamio;
|
||||||
|
}
|
||||||
|
|
||||||
|
voidpf ZCALLBACK fopen_buf_func(voidpf opaque, const char *filename, int mode)
|
||||||
|
{
|
||||||
|
ourbuffer_t *bufio = (ourbuffer_t *)opaque;
|
||||||
|
voidpf stream = bufio->filefunc.zopen_file(bufio->filefunc.opaque, filename, mode);
|
||||||
|
return fopen_buf_internal_func(opaque, stream, 0, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
voidpf ZCALLBACK fopen64_buf_func(voidpf opaque, const void *filename, int mode)
|
||||||
|
{
|
||||||
|
ourbuffer_t *bufio = (ourbuffer_t *)opaque;
|
||||||
|
voidpf stream = bufio->filefunc64.zopen64_file(bufio->filefunc64.opaque, filename, mode);
|
||||||
|
return fopen_buf_internal_func(opaque, stream, 0, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
voidpf ZCALLBACK fopendisk_buf_func(voidpf opaque, voidpf stream_cd, uint32_t number_disk, int mode)
|
||||||
|
{
|
||||||
|
ourbuffer_t *bufio = (ourbuffer_t *)opaque;
|
||||||
|
ourstream_t *streamio = (ourstream_t *)stream_cd;
|
||||||
|
voidpf *stream = bufio->filefunc.zopendisk_file(bufio->filefunc.opaque, streamio->stream, number_disk, mode);
|
||||||
|
return fopen_buf_internal_func(opaque, stream, number_disk, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
voidpf ZCALLBACK fopendisk64_buf_func(voidpf opaque, voidpf stream_cd, uint32_t number_disk, int mode)
|
||||||
|
{
|
||||||
|
ourbuffer_t *bufio = (ourbuffer_t *)opaque;
|
||||||
|
ourstream_t *streamio = (ourstream_t *)stream_cd;
|
||||||
|
voidpf stream = bufio->filefunc64.zopendisk64_file(bufio->filefunc64.opaque, streamio->stream, number_disk, mode);
|
||||||
|
return fopen_buf_internal_func(opaque, stream, number_disk, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
long fflush_buf(voidpf opaque, voidpf stream)
|
||||||
|
{
|
||||||
|
ourbuffer_t *bufio = (ourbuffer_t *)opaque;
|
||||||
|
ourstream_t *streamio = (ourstream_t *)stream;
|
||||||
|
uint32_t total_bytes_to_write = 0;
|
||||||
|
uint32_t bytes_to_write = streamio->writebuf_len;
|
||||||
|
uint32_t bytes_left_to_write = streamio->writebuf_len;
|
||||||
|
long bytes_written = 0;
|
||||||
|
|
||||||
|
while (bytes_left_to_write > 0)
|
||||||
|
{
|
||||||
|
if (bufio->filefunc64.zwrite_file != NULL)
|
||||||
|
bytes_written = bufio->filefunc64.zwrite_file(bufio->filefunc64.opaque, streamio->stream, streamio->writebuf + (bytes_to_write - bytes_left_to_write), bytes_left_to_write);
|
||||||
|
else
|
||||||
|
bytes_written = bufio->filefunc.zwrite_file(bufio->filefunc.opaque, streamio->stream, streamio->writebuf + (bytes_to_write - bytes_left_to_write), bytes_left_to_write);
|
||||||
|
|
||||||
|
streamio->writebuf_misses += 1;
|
||||||
|
|
||||||
|
print_buf(opaque, stream, "write flush [%d:%d len %d]\n", bytes_to_write, bytes_left_to_write, streamio->writebuf_len);
|
||||||
|
|
||||||
|
if (bytes_written < 0)
|
||||||
|
return bytes_written;
|
||||||
|
|
||||||
|
total_bytes_to_write += bytes_written;
|
||||||
|
bytes_left_to_write -= bytes_written;
|
||||||
|
streamio->position += bytes_written;
|
||||||
|
}
|
||||||
|
streamio->writebuf_len = 0;
|
||||||
|
streamio->writebuf_pos = 0;
|
||||||
|
return total_bytes_to_write;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ZCALLBACK fread_buf_func(voidpf opaque, voidpf stream, void *buf, uint32_t size)
|
||||||
|
{
|
||||||
|
ourbuffer_t *bufio = (ourbuffer_t *)opaque;
|
||||||
|
ourstream_t *streamio = (ourstream_t *)stream;
|
||||||
|
uint32_t buf_len = 0;
|
||||||
|
uint32_t bytes_to_read = 0;
|
||||||
|
uint32_t bytes_to_copy = 0;
|
||||||
|
uint32_t bytes_left_to_read = size;
|
||||||
|
uint32_t bytes_read = 0;
|
||||||
|
|
||||||
|
print_buf(opaque, stream, "read [size %ld pos %lld]\n", size, streamio->position);
|
||||||
|
|
||||||
|
if (streamio->writebuf_len > 0)
|
||||||
|
{
|
||||||
|
print_buf(opaque, stream, "switch from write to read, not yet supported [%lld]\n", streamio->position);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (bytes_left_to_read > 0)
|
||||||
|
{
|
||||||
|
if ((streamio->readbuf_len == 0) || (streamio->readbuf_pos == streamio->readbuf_len))
|
||||||
|
{
|
||||||
|
if (streamio->readbuf_len == IOBUF_BUFFERSIZE)
|
||||||
|
{
|
||||||
|
streamio->readbuf_pos = 0;
|
||||||
|
streamio->readbuf_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes_to_read = IOBUF_BUFFERSIZE - (streamio->readbuf_len - streamio->readbuf_pos);
|
||||||
|
|
||||||
|
if (bufio->filefunc64.zread_file != NULL)
|
||||||
|
bytes_read = bufio->filefunc64.zread_file(bufio->filefunc64.opaque, streamio->stream, streamio->readbuf + streamio->readbuf_pos, bytes_to_read);
|
||||||
|
else
|
||||||
|
bytes_read = bufio->filefunc.zread_file(bufio->filefunc.opaque, streamio->stream, streamio->readbuf + streamio->readbuf_pos, bytes_to_read);
|
||||||
|
|
||||||
|
streamio->readbuf_misses += 1;
|
||||||
|
streamio->readbuf_len += bytes_read;
|
||||||
|
streamio->position += bytes_read;
|
||||||
|
|
||||||
|
print_buf(opaque, stream, "filled [read %d/%d buf %d:%d pos %lld]\n", bytes_read, bytes_to_read, streamio->readbuf_pos, streamio->readbuf_len, streamio->position);
|
||||||
|
|
||||||
|
if (bytes_read == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((streamio->readbuf_len - streamio->readbuf_pos) > 0)
|
||||||
|
{
|
||||||
|
bytes_to_copy = min(bytes_left_to_read, (uint32_t)(streamio->readbuf_len - streamio->readbuf_pos));
|
||||||
|
memcpy((char *)buf + buf_len, streamio->readbuf + streamio->readbuf_pos, bytes_to_copy);
|
||||||
|
|
||||||
|
buf_len += bytes_to_copy;
|
||||||
|
bytes_left_to_read -= bytes_to_copy;
|
||||||
|
|
||||||
|
streamio->readbuf_hits += 1;
|
||||||
|
streamio->readbuf_pos += bytes_to_copy;
|
||||||
|
|
||||||
|
print_buf(opaque, stream, "emptied [copied %d remaining %d buf %d:%d pos %lld]\n", bytes_to_copy, bytes_left_to_read, streamio->readbuf_pos, streamio->readbuf_len, streamio->position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return size - bytes_left_to_read;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ZCALLBACK fwrite_buf_func(voidpf opaque, voidpf stream, const void *buf, uint32_t size)
|
||||||
|
{
|
||||||
|
ourbuffer_t *bufio = (ourbuffer_t *)opaque;
|
||||||
|
ourstream_t *streamio = (ourstream_t *)stream;
|
||||||
|
uint32_t bytes_to_write = size;
|
||||||
|
uint32_t bytes_left_to_write = size;
|
||||||
|
uint32_t bytes_to_copy = 0;
|
||||||
|
int64_t ret = 0;
|
||||||
|
|
||||||
|
print_buf(opaque, stream, "write [size %ld len %d pos %lld]\n", size, streamio->writebuf_len, streamio->position);
|
||||||
|
|
||||||
|
if (streamio->readbuf_len > 0)
|
||||||
|
{
|
||||||
|
streamio->position -= streamio->readbuf_len;
|
||||||
|
streamio->position += streamio->readbuf_pos;
|
||||||
|
|
||||||
|
streamio->readbuf_len = 0;
|
||||||
|
streamio->readbuf_pos = 0;
|
||||||
|
|
||||||
|
print_buf(opaque, stream, "switch from read to write [%lld]\n", streamio->position);
|
||||||
|
|
||||||
|
if (bufio->filefunc64.zseek64_file != NULL)
|
||||||
|
ret = bufio->filefunc64.zseek64_file(bufio->filefunc64.opaque, streamio->stream, streamio->position, ZLIB_FILEFUNC_SEEK_SET);
|
||||||
|
else
|
||||||
|
ret = bufio->filefunc.zseek_file(bufio->filefunc.opaque, streamio->stream, (uint32_t)streamio->position, ZLIB_FILEFUNC_SEEK_SET);
|
||||||
|
|
||||||
|
if (ret != 0)
|
||||||
|
return (uint32_t)-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (bytes_left_to_write > 0)
|
||||||
|
{
|
||||||
|
bytes_to_copy = min(bytes_left_to_write, (uint32_t)(IOBUF_BUFFERSIZE - min(streamio->writebuf_len, streamio->writebuf_pos)));
|
||||||
|
|
||||||
|
if (bytes_to_copy == 0)
|
||||||
|
{
|
||||||
|
if (fflush_buf(opaque, stream) <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(streamio->writebuf + streamio->writebuf_pos, (char *)buf + (bytes_to_write - bytes_left_to_write), bytes_to_copy);
|
||||||
|
|
||||||
|
print_buf(opaque, stream, "write copy [remaining %d write %d:%d len %d]\n", bytes_to_copy, bytes_to_write, bytes_left_to_write, streamio->writebuf_len);
|
||||||
|
|
||||||
|
bytes_left_to_write -= bytes_to_copy;
|
||||||
|
|
||||||
|
streamio->writebuf_pos += bytes_to_copy;
|
||||||
|
streamio->writebuf_hits += 1;
|
||||||
|
if (streamio->writebuf_pos > streamio->writebuf_len)
|
||||||
|
streamio->writebuf_len += streamio->writebuf_pos - streamio->writebuf_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return size - bytes_left_to_write;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t ftell_buf_internal_func(ZIP_UNUSED voidpf opaque, voidpf stream, uint64_t position)
|
||||||
|
{
|
||||||
|
ourstream_t *streamio = (ourstream_t *)stream;
|
||||||
|
streamio->position = position;
|
||||||
|
print_buf(opaque, stream, "tell [pos %llu readpos %d writepos %d err %d]\n", streamio->position, streamio->readbuf_pos, streamio->writebuf_pos, errno);
|
||||||
|
if (streamio->readbuf_len > 0)
|
||||||
|
position -= (streamio->readbuf_len - streamio->readbuf_pos);
|
||||||
|
if (streamio->writebuf_len > 0)
|
||||||
|
position += streamio->writebuf_pos;
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
long ZCALLBACK ftell_buf_func(voidpf opaque, voidpf stream)
|
||||||
|
{
|
||||||
|
ourbuffer_t *bufio = (ourbuffer_t *)opaque;
|
||||||
|
ourstream_t *streamio = (ourstream_t *)stream;
|
||||||
|
uint64_t position = bufio->filefunc.ztell_file(bufio->filefunc.opaque, streamio->stream);
|
||||||
|
return (long)ftell_buf_internal_func(opaque, stream, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t ZCALLBACK ftell64_buf_func(voidpf opaque, voidpf stream)
|
||||||
|
{
|
||||||
|
ourbuffer_t *bufio = (ourbuffer_t *)opaque;
|
||||||
|
ourstream_t *streamio = (ourstream_t *)stream;
|
||||||
|
uint64_t position = bufio->filefunc64.ztell64_file(bufio->filefunc64.opaque, streamio->stream);
|
||||||
|
return ftell_buf_internal_func(opaque, stream, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
int fseek_buf_internal_func(voidpf opaque, voidpf stream, uint64_t offset, int origin)
|
||||||
|
{
|
||||||
|
ourstream_t *streamio = (ourstream_t *)stream;
|
||||||
|
|
||||||
|
print_buf(opaque, stream, "seek [origin %d offset %llu pos %lld]\n", origin, offset, streamio->position);
|
||||||
|
|
||||||
|
switch (origin)
|
||||||
|
{
|
||||||
|
case ZLIB_FILEFUNC_SEEK_SET:
|
||||||
|
|
||||||
|
if (streamio->writebuf_len > 0)
|
||||||
|
{
|
||||||
|
if ((offset >= streamio->position) && (offset <= streamio->position + streamio->writebuf_len))
|
||||||
|
{
|
||||||
|
streamio->writebuf_pos = (uint32_t)(offset - streamio->position);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((streamio->readbuf_len > 0) && (offset < streamio->position) && (offset >= streamio->position - streamio->readbuf_len))
|
||||||
|
{
|
||||||
|
streamio->readbuf_pos = (uint32_t)(offset - (streamio->position - streamio->readbuf_len));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (fflush_buf(opaque, stream) < 0)
|
||||||
|
return -1;
|
||||||
|
streamio->position = offset;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ZLIB_FILEFUNC_SEEK_CUR:
|
||||||
|
|
||||||
|
if (streamio->readbuf_len > 0)
|
||||||
|
{
|
||||||
|
if (offset <= (streamio->readbuf_len - streamio->readbuf_pos))
|
||||||
|
{
|
||||||
|
streamio->readbuf_pos += (uint32_t)offset;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
offset -= (streamio->readbuf_len - streamio->readbuf_pos);
|
||||||
|
streamio->position += offset;
|
||||||
|
}
|
||||||
|
if (streamio->writebuf_len > 0)
|
||||||
|
{
|
||||||
|
if (offset <= (streamio->writebuf_len - streamio->writebuf_pos))
|
||||||
|
{
|
||||||
|
streamio->writebuf_pos += (uint32_t)offset;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//offset -= (streamio->writebuf_len - streamio->writebuf_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fflush_buf(opaque, stream) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ZLIB_FILEFUNC_SEEK_END:
|
||||||
|
|
||||||
|
if (streamio->writebuf_len > 0)
|
||||||
|
{
|
||||||
|
streamio->writebuf_pos = streamio->writebuf_len;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
streamio->readbuf_len = 0;
|
||||||
|
streamio->readbuf_pos = 0;
|
||||||
|
streamio->writebuf_len = 0;
|
||||||
|
streamio->writebuf_pos = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
long ZCALLBACK fseek_buf_func(voidpf opaque, voidpf stream, uint32_t offset, int origin)
|
||||||
|
{
|
||||||
|
ourbuffer_t *bufio = (ourbuffer_t *)opaque;
|
||||||
|
ourstream_t *streamio = (ourstream_t *)stream;
|
||||||
|
long ret = -1;
|
||||||
|
if (bufio->filefunc.zseek_file == NULL)
|
||||||
|
return ret;
|
||||||
|
ret = fseek_buf_internal_func(opaque, stream, offset, origin);
|
||||||
|
if (ret == 1)
|
||||||
|
ret = bufio->filefunc.zseek_file(bufio->filefunc.opaque, streamio->stream, offset, origin);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
long ZCALLBACK fseek64_buf_func(voidpf opaque, voidpf stream, uint64_t offset, int origin)
|
||||||
|
{
|
||||||
|
ourbuffer_t *bufio = (ourbuffer_t *)opaque;
|
||||||
|
ourstream_t *streamio = (ourstream_t *)stream;
|
||||||
|
long ret = -1;
|
||||||
|
if (bufio->filefunc64.zseek64_file == NULL)
|
||||||
|
return ret;
|
||||||
|
ret = fseek_buf_internal_func(opaque, stream, offset, origin);
|
||||||
|
if (ret == 1)
|
||||||
|
ret = bufio->filefunc64.zseek64_file(bufio->filefunc64.opaque, streamio->stream, offset, origin);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ZCALLBACK fclose_buf_func(voidpf opaque, voidpf stream)
|
||||||
|
{
|
||||||
|
ourbuffer_t *bufio = (ourbuffer_t *)opaque;
|
||||||
|
ourstream_t *streamio = (ourstream_t *)stream;
|
||||||
|
int ret = 0;
|
||||||
|
fflush_buf(opaque, stream);
|
||||||
|
print_buf(opaque, stream, "close\n");
|
||||||
|
if (streamio->readbuf_hits + streamio->readbuf_misses > 0)
|
||||||
|
print_buf(opaque, stream, "read efficency %.02f%%\n", (streamio->readbuf_hits / ((float)streamio->readbuf_hits + streamio->readbuf_misses)) * 100);
|
||||||
|
if (streamio->writebuf_hits + streamio->writebuf_misses > 0)
|
||||||
|
print_buf(opaque, stream, "write efficency %.02f%%\n", (streamio->writebuf_hits / ((float)streamio->writebuf_hits + streamio->writebuf_misses)) * 100);
|
||||||
|
if (bufio->filefunc64.zclose_file != NULL)
|
||||||
|
ret = bufio->filefunc64.zclose_file(bufio->filefunc64.opaque, streamio->stream);
|
||||||
|
else
|
||||||
|
ret = bufio->filefunc.zclose_file(bufio->filefunc.opaque, streamio->stream);
|
||||||
|
free(streamio);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ZCALLBACK ferror_buf_func(voidpf opaque, voidpf stream)
|
||||||
|
{
|
||||||
|
ourbuffer_t *bufio = (ourbuffer_t *)opaque;
|
||||||
|
ourstream_t *streamio = (ourstream_t *)stream;
|
||||||
|
if (bufio->filefunc64.zerror_file != NULL)
|
||||||
|
return bufio->filefunc64.zerror_file(bufio->filefunc64.opaque, streamio->stream);
|
||||||
|
return bufio->filefunc.zerror_file(bufio->filefunc.opaque, streamio->stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fill_buffer_filefunc(zlib_filefunc_def *pzlib_filefunc_def, ourbuffer_t *ourbuf)
|
||||||
|
{
|
||||||
|
pzlib_filefunc_def->zopen_file = fopen_buf_func;
|
||||||
|
pzlib_filefunc_def->zopendisk_file = fopendisk_buf_func;
|
||||||
|
pzlib_filefunc_def->zread_file = fread_buf_func;
|
||||||
|
pzlib_filefunc_def->zwrite_file = fwrite_buf_func;
|
||||||
|
pzlib_filefunc_def->ztell_file = ftell_buf_func;
|
||||||
|
pzlib_filefunc_def->zseek_file = fseek_buf_func;
|
||||||
|
pzlib_filefunc_def->zclose_file = fclose_buf_func;
|
||||||
|
pzlib_filefunc_def->zerror_file = ferror_buf_func;
|
||||||
|
pzlib_filefunc_def->opaque = ourbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fill_buffer_filefunc64(zlib_filefunc64_def *pzlib_filefunc_def, ourbuffer_t *ourbuf)
|
||||||
|
{
|
||||||
|
pzlib_filefunc_def->zopen64_file = fopen64_buf_func;
|
||||||
|
pzlib_filefunc_def->zopendisk64_file = fopendisk64_buf_func;
|
||||||
|
pzlib_filefunc_def->zread_file = fread_buf_func;
|
||||||
|
pzlib_filefunc_def->zwrite_file = fwrite_buf_func;
|
||||||
|
pzlib_filefunc_def->ztell64_file = ftell64_buf_func;
|
||||||
|
pzlib_filefunc_def->zseek64_file = fseek64_buf_func;
|
||||||
|
pzlib_filefunc_def->zclose_file = fclose_buf_func;
|
||||||
|
pzlib_filefunc_def->zerror_file = ferror_buf_func;
|
||||||
|
pzlib_filefunc_def->opaque = ourbuf;
|
||||||
|
}
|
||||||
52
SSZipArchive/minizip/ioapi_buf.h
Normal file
52
SSZipArchive/minizip/ioapi_buf.h
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/* ioapi_buf.h -- IO base function header for compress/uncompress .zip
|
||||||
|
files using zlib + zip or unzip API
|
||||||
|
|
||||||
|
This version of ioapi is designed to buffer IO.
|
||||||
|
|
||||||
|
Copyright (C) 2012-2017 Nathan Moinvaziri
|
||||||
|
https://github.com/nmoinvaz/minizip
|
||||||
|
|
||||||
|
This program is distributed under the terms of the same license as zlib.
|
||||||
|
See the accompanying LICENSE file for the full text of the license.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _IOAPI_BUF_H
|
||||||
|
#define _IOAPI_BUF_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "zlib.h"
|
||||||
|
#include "ioapi.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
voidpf ZCALLBACK fopen_buf_func(voidpf opaque, const char* filename, int mode);
|
||||||
|
voidpf ZCALLBACK fopen64_buf_func(voidpf opaque, const void* filename, int mode);
|
||||||
|
voidpf ZCALLBACK fopendisk_buf_func(voidpf opaque, voidpf stream_cd, uint32_t number_disk, int mode);
|
||||||
|
voidpf ZCALLBACK fopendisk64_buf_func(voidpf opaque, voidpf stream_cd, uint32_t number_disk, int mode);
|
||||||
|
uint32_t ZCALLBACK fread_buf_func(voidpf opaque, voidpf stream, void* buf, uint32_t size);
|
||||||
|
uint32_t ZCALLBACK fwrite_buf_func(voidpf opaque, voidpf stream, const void* buf, uint32_t size);
|
||||||
|
long ZCALLBACK ftell_buf_func(voidpf opaque, voidpf stream);
|
||||||
|
uint64_t ZCALLBACK ftell64_buf_func(voidpf opaque, voidpf stream);
|
||||||
|
long ZCALLBACK fseek_buf_func(voidpf opaque, voidpf stream, uint32_t offset, int origin);
|
||||||
|
long ZCALLBACK fseek64_buf_func(voidpf opaque, voidpf stream, uint64_t offset, int origin);
|
||||||
|
int ZCALLBACK fclose_buf_func(voidpf opaque,voidpf stream);
|
||||||
|
int ZCALLBACK ferror_buf_func(voidpf opaque,voidpf stream);
|
||||||
|
|
||||||
|
typedef struct ourbuffer_s {
|
||||||
|
zlib_filefunc_def filefunc;
|
||||||
|
zlib_filefunc64_def filefunc64;
|
||||||
|
} ourbuffer_t;
|
||||||
|
|
||||||
|
void fill_buffer_filefunc(zlib_filefunc_def* pzlib_filefunc_def, ourbuffer_t *ourbuf);
|
||||||
|
void fill_buffer_filefunc64(zlib_filefunc64_def* pzlib_filefunc_def, ourbuffer_t *ourbuf);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
167
SSZipArchive/minizip/ioapi_mem.c
Normal file
167
SSZipArchive/minizip/ioapi_mem.c
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
/* ioapi_mem.c -- IO base function header for compress/uncompress .zip
|
||||||
|
files using zlib + zip or unzip API
|
||||||
|
|
||||||
|
This version of ioapi is designed to access memory rather than files.
|
||||||
|
We do use a region of memory to put data in to and take it out of. We do
|
||||||
|
not have auto-extending buffers and do not inform anyone else that the
|
||||||
|
data has been written. It is really intended for accessing a zip archive
|
||||||
|
embedded in an application such that I can write an installer with no
|
||||||
|
external files. Creation of archives has not been attempted, although
|
||||||
|
parts of the framework are present.
|
||||||
|
|
||||||
|
Based on Unzip ioapi.c version 0.22, May 19th, 2003
|
||||||
|
|
||||||
|
Copyright (C) 2012-2017 Nathan Moinvaziri
|
||||||
|
https://github.com/nmoinvaz/minizip
|
||||||
|
Copyright (C) 2003 Justin Fletcher
|
||||||
|
Copyright (C) 1998-2003 Gilles Vollant
|
||||||
|
http://www.winimage.com/zLibDll/minizip.html
|
||||||
|
|
||||||
|
This file is under the same license as the Unzip tool it is distributed
|
||||||
|
with.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "zlib.h"
|
||||||
|
#include "ioapi.h"
|
||||||
|
|
||||||
|
#include "ioapi_mem.h"
|
||||||
|
|
||||||
|
#ifndef IOMEM_BUFFERSIZE
|
||||||
|
# define IOMEM_BUFFERSIZE (UINT16_MAX)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
voidpf ZCALLBACK fopen_mem_func(voidpf opaque, ZIP_UNUSED const char *filename, int mode)
|
||||||
|
{
|
||||||
|
ourmemory_t *mem = (ourmemory_t *)opaque;
|
||||||
|
if (mem == NULL)
|
||||||
|
return NULL; /* Mem structure passed in was null */
|
||||||
|
|
||||||
|
if (mode & ZLIB_FILEFUNC_MODE_CREATE)
|
||||||
|
{
|
||||||
|
if (mem->grow)
|
||||||
|
{
|
||||||
|
mem->size = IOMEM_BUFFERSIZE;
|
||||||
|
mem->base = (char *)malloc(mem->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
mem->limit = 0; /* When writing we start with 0 bytes written */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mem->limit = mem->size;
|
||||||
|
|
||||||
|
mem->cur_offset = 0;
|
||||||
|
|
||||||
|
return mem;
|
||||||
|
}
|
||||||
|
|
||||||
|
voidpf ZCALLBACK fopendisk_mem_func(ZIP_UNUSED voidpf opaque, ZIP_UNUSED voidpf stream, ZIP_UNUSED uint32_t number_disk, ZIP_UNUSED int mode)
|
||||||
|
{
|
||||||
|
/* Not used */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ZCALLBACK fread_mem_func(ZIP_UNUSED voidpf opaque, voidpf stream, void *buf, uint32_t size)
|
||||||
|
{
|
||||||
|
ourmemory_t *mem = (ourmemory_t *)stream;
|
||||||
|
|
||||||
|
if (size > mem->size - mem->cur_offset)
|
||||||
|
size = mem->size - mem->cur_offset;
|
||||||
|
|
||||||
|
memcpy(buf, mem->base + mem->cur_offset, size);
|
||||||
|
mem->cur_offset += size;
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ZCALLBACK fwrite_mem_func(ZIP_UNUSED voidpf opaque, voidpf stream, const void *buf, uint32_t size)
|
||||||
|
{
|
||||||
|
ourmemory_t *mem = (ourmemory_t *)stream;
|
||||||
|
uint32_t newmemsize = 0;
|
||||||
|
char *newbase = NULL;
|
||||||
|
|
||||||
|
if (size > mem->size - mem->cur_offset)
|
||||||
|
{
|
||||||
|
if (mem->grow)
|
||||||
|
{
|
||||||
|
newmemsize = mem->size;
|
||||||
|
if (size < IOMEM_BUFFERSIZE)
|
||||||
|
newmemsize += IOMEM_BUFFERSIZE;
|
||||||
|
else
|
||||||
|
newmemsize += size;
|
||||||
|
newbase = (char *)malloc(newmemsize);
|
||||||
|
memcpy(newbase, mem->base, mem->size);
|
||||||
|
free(mem->base);
|
||||||
|
mem->base = newbase;
|
||||||
|
mem->size = newmemsize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
size = mem->size - mem->cur_offset;
|
||||||
|
}
|
||||||
|
memcpy(mem->base + mem->cur_offset, buf, size);
|
||||||
|
mem->cur_offset += size;
|
||||||
|
if (mem->cur_offset > mem->limit)
|
||||||
|
mem->limit = mem->cur_offset;
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
long ZCALLBACK ftell_mem_func(ZIP_UNUSED voidpf opaque, voidpf stream)
|
||||||
|
{
|
||||||
|
ourmemory_t *mem = (ourmemory_t *)stream;
|
||||||
|
return mem->cur_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
long ZCALLBACK fseek_mem_func(ZIP_UNUSED voidpf opaque, voidpf stream, uint32_t offset, int origin)
|
||||||
|
{
|
||||||
|
ourmemory_t *mem = (ourmemory_t *)stream;
|
||||||
|
uint32_t new_pos = 0;
|
||||||
|
switch (origin)
|
||||||
|
{
|
||||||
|
case ZLIB_FILEFUNC_SEEK_CUR:
|
||||||
|
new_pos = mem->cur_offset + offset;
|
||||||
|
break;
|
||||||
|
case ZLIB_FILEFUNC_SEEK_END:
|
||||||
|
new_pos = mem->limit + offset;
|
||||||
|
break;
|
||||||
|
case ZLIB_FILEFUNC_SEEK_SET:
|
||||||
|
new_pos = offset;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (new_pos > mem->size)
|
||||||
|
return 1; /* Failed to seek that far */
|
||||||
|
mem->cur_offset = new_pos;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ZCALLBACK fclose_mem_func(ZIP_UNUSED voidpf opaque, ZIP_UNUSED voidpf stream)
|
||||||
|
{
|
||||||
|
/* Even with grow = 1, caller must always free() memory */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ZCALLBACK ferror_mem_func(ZIP_UNUSED voidpf opaque, ZIP_UNUSED voidpf stream)
|
||||||
|
{
|
||||||
|
/* We never return errors */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fill_memory_filefunc(zlib_filefunc_def *pzlib_filefunc_def, ourmemory_t *ourmem)
|
||||||
|
{
|
||||||
|
pzlib_filefunc_def->zopen_file = fopen_mem_func;
|
||||||
|
pzlib_filefunc_def->zopendisk_file = fopendisk_mem_func;
|
||||||
|
pzlib_filefunc_def->zread_file = fread_mem_func;
|
||||||
|
pzlib_filefunc_def->zwrite_file = fwrite_mem_func;
|
||||||
|
pzlib_filefunc_def->ztell_file = ftell_mem_func;
|
||||||
|
pzlib_filefunc_def->zseek_file = fseek_mem_func;
|
||||||
|
pzlib_filefunc_def->zclose_file = fclose_mem_func;
|
||||||
|
pzlib_filefunc_def->zerror_file = ferror_mem_func;
|
||||||
|
pzlib_filefunc_def->opaque = ourmem;
|
||||||
|
}
|
||||||
52
SSZipArchive/minizip/ioapi_mem.h
Normal file
52
SSZipArchive/minizip/ioapi_mem.h
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/* ioapi_mem.h -- IO base function header for compress/uncompress .zip
|
||||||
|
files using zlib + zip or unzip API
|
||||||
|
|
||||||
|
This version of ioapi is designed to access memory rather than files.
|
||||||
|
We do use a region of memory to put data in to and take it out of.
|
||||||
|
|
||||||
|
Copyright (C) 2012-2017 Nathan Moinvaziri (https://github.com/nmoinvaz/minizip)
|
||||||
|
(C) 2003 Justin Fletcher
|
||||||
|
(C) 1998-2003 Gilles Vollant
|
||||||
|
|
||||||
|
This program is distributed under the terms of the same license as zlib.
|
||||||
|
See the accompanying LICENSE file for the full text of the license.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _IOAPI_MEM_H
|
||||||
|
#define _IOAPI_MEM_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "zlib.h"
|
||||||
|
#include "ioapi.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
voidpf ZCALLBACK fopen_mem_func(voidpf opaque, const char* filename, int mode);
|
||||||
|
voidpf ZCALLBACK fopendisk_mem_func(voidpf opaque, voidpf stream, uint32_t number_disk, int mode);
|
||||||
|
uint32_t ZCALLBACK fread_mem_func(voidpf opaque, voidpf stream, void* buf, uint32_t size);
|
||||||
|
uint32_t ZCALLBACK fwrite_mem_func(voidpf opaque, voidpf stream, const void* buf, uint32_t size);
|
||||||
|
long ZCALLBACK ftell_mem_func(voidpf opaque, voidpf stream);
|
||||||
|
long ZCALLBACK fseek_mem_func(voidpf opaque, voidpf stream, uint32_t offset, int origin);
|
||||||
|
int ZCALLBACK fclose_mem_func(voidpf opaque, voidpf stream);
|
||||||
|
int ZCALLBACK ferror_mem_func(voidpf opaque, voidpf stream);
|
||||||
|
|
||||||
|
typedef struct ourmemory_s {
|
||||||
|
char *base; /* Base of the region of memory we're using */
|
||||||
|
uint32_t size; /* Size of the region of memory we're using */
|
||||||
|
uint32_t limit; /* Furthest we've written */
|
||||||
|
uint32_t cur_offset; /* Current offset in the area */
|
||||||
|
int grow; /* Growable memory buffer */
|
||||||
|
} ourmemory_t;
|
||||||
|
|
||||||
|
void fill_memory_filefunc(zlib_filefunc_def* pzlib_filefunc_def, ourmemory_t *ourmem);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
292
SSZipArchive/minizip/minishared.c
Normal file
292
SSZipArchive/minizip/minishared.c
Normal file
@@ -0,0 +1,292 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include "zlib.h"
|
||||||
|
#include "ioapi.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
# include <direct.h>
|
||||||
|
# include <io.h>
|
||||||
|
#else
|
||||||
|
# include <unistd.h>
|
||||||
|
# include <utime.h>
|
||||||
|
# include <sys/types.h>
|
||||||
|
# include <sys/stat.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "minishared.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
# define USEWIN32IOAPI
|
||||||
|
# include "iowin32.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint32_t get_file_date(const char *path, uint32_t *dos_date)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
#ifdef _WIN32
|
||||||
|
FILETIME ftm_local;
|
||||||
|
HANDLE find = NULL;
|
||||||
|
WIN32_FIND_DATAA ff32;
|
||||||
|
|
||||||
|
find = FindFirstFileA(path, &ff32);
|
||||||
|
if (find != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
FileTimeToLocalFileTime(&(ff32.ftLastWriteTime), &ftm_local);
|
||||||
|
FileTimeToDosDateTime(&ftm_local, ((LPWORD)dos_date) + 1, ((LPWORD)dos_date) + 0);
|
||||||
|
FindClose(find);
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
struct stat s;
|
||||||
|
struct tm *filedate = NULL;
|
||||||
|
time_t tm_t = 0;
|
||||||
|
|
||||||
|
memset(&s, 0, sizeof(s));
|
||||||
|
|
||||||
|
if (strcmp(path, "-") != 0)
|
||||||
|
{
|
||||||
|
size_t len = strlen(path);
|
||||||
|
char *name = (char *)malloc(len + 1);
|
||||||
|
strncpy(name, path, len + 1);
|
||||||
|
name[len] = 0;
|
||||||
|
if (name[len - 1] == '/')
|
||||||
|
name[len - 1] = 0;
|
||||||
|
|
||||||
|
/* Not all systems allow stat'ing a file with / appended */
|
||||||
|
if (stat(name, &s) == 0)
|
||||||
|
{
|
||||||
|
tm_t = s.st_mtime;
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
free(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
filedate = localtime(&tm_t);
|
||||||
|
*dos_date = tm_to_dosdate(filedate);
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void change_file_date(const char *path, uint32_t dos_date)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
HANDLE handle = NULL;
|
||||||
|
FILETIME ftm, ftm_local, ftm_create, ftm_access, ftm_modified;
|
||||||
|
|
||||||
|
handle = CreateFileA(path, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
if (handle != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
GetFileTime(handle, &ftm_create, &ftm_access, &ftm_modified);
|
||||||
|
DosDateTimeToFileTime((WORD)(dos_date >> 16), (WORD)dos_date, &ftm_local);
|
||||||
|
LocalFileTimeToFileTime(&ftm_local, &ftm);
|
||||||
|
SetFileTime(handle, &ftm, &ftm_access, &ftm);
|
||||||
|
CloseHandle(handle);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
struct utimbuf ut;
|
||||||
|
ut.actime = ut.modtime = dosdate_to_time_t(dos_date);
|
||||||
|
utime(path, &ut);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int invalid_date(const struct tm *ptm)
|
||||||
|
{
|
||||||
|
#define datevalue_in_range(min, max, value) ((min) <= (value) && (value) <= (max))
|
||||||
|
return (!datevalue_in_range(0, 207, ptm->tm_year) ||
|
||||||
|
!datevalue_in_range(0, 11, ptm->tm_mon) ||
|
||||||
|
!datevalue_in_range(1, 31, ptm->tm_mday) ||
|
||||||
|
!datevalue_in_range(0, 23, ptm->tm_hour) ||
|
||||||
|
!datevalue_in_range(0, 59, ptm->tm_min) ||
|
||||||
|
!datevalue_in_range(0, 59, ptm->tm_sec));
|
||||||
|
#undef datevalue_in_range
|
||||||
|
}
|
||||||
|
|
||||||
|
// Conversion without validation
|
||||||
|
void dosdate_to_raw_tm(uint64_t dos_date, struct tm *ptm)
|
||||||
|
{
|
||||||
|
uint64_t date = (uint64_t)(dos_date >> 16);
|
||||||
|
|
||||||
|
ptm->tm_mday = (uint16_t)(date & 0x1f);
|
||||||
|
ptm->tm_mon = (uint16_t)(((date & 0x1E0) / 0x20) - 1);
|
||||||
|
ptm->tm_year = (uint16_t)(((date & 0x0FE00) / 0x0200) + 80);
|
||||||
|
ptm->tm_hour = (uint16_t)((dos_date & 0xF800) / 0x800);
|
||||||
|
ptm->tm_min = (uint16_t)((dos_date & 0x7E0) / 0x20);
|
||||||
|
ptm->tm_sec = (uint16_t)(2 * (dos_date & 0x1f));
|
||||||
|
ptm->tm_isdst = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dosdate_to_tm(uint64_t dos_date, struct tm *ptm)
|
||||||
|
{
|
||||||
|
dosdate_to_raw_tm(dos_date, ptm);
|
||||||
|
|
||||||
|
if (invalid_date(ptm))
|
||||||
|
{
|
||||||
|
// Invalid date stored, so don't return it.
|
||||||
|
memset(ptm, 0, sizeof(struct tm));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
time_t dosdate_to_time_t(uint64_t dos_date)
|
||||||
|
{
|
||||||
|
struct tm ptm;
|
||||||
|
dosdate_to_raw_tm(dos_date, &ptm);
|
||||||
|
return mktime(&ptm);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t tm_to_dosdate(const struct tm *ptm)
|
||||||
|
{
|
||||||
|
struct tm fixed_tm;
|
||||||
|
|
||||||
|
/* Years supported:
|
||||||
|
* [00, 79] (assumed to be between 2000 and 2079)
|
||||||
|
* [80, 207] (assumed to be between 1980 and 2107, typical output of old
|
||||||
|
software that does 'year-1900' to get a double digit year)
|
||||||
|
* [1980, 2107] (due to the date format limitations, only years between 1980 and 2107 can be stored.)
|
||||||
|
*/
|
||||||
|
|
||||||
|
memcpy(&fixed_tm, ptm, sizeof(struct tm));
|
||||||
|
if (fixed_tm.tm_year >= 1980) /* range [1980, 2107] */
|
||||||
|
fixed_tm.tm_year -= 1980;
|
||||||
|
else if (fixed_tm.tm_year >= 80) /* range [80, 99] */
|
||||||
|
fixed_tm.tm_year -= 80;
|
||||||
|
else /* range [00, 79] */
|
||||||
|
fixed_tm.tm_year += 20;
|
||||||
|
|
||||||
|
if (invalid_date(ptm))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return (uint32_t)(((fixed_tm.tm_mday) + (32 * (fixed_tm.tm_mon + 1)) + (512 * fixed_tm.tm_year)) << 16) |
|
||||||
|
((fixed_tm.tm_sec / 2) + (32 * fixed_tm.tm_min) + (2048 * (uint32_t)fixed_tm.tm_hour));
|
||||||
|
}
|
||||||
|
|
||||||
|
int makedir(const char *newdir)
|
||||||
|
{
|
||||||
|
char *buffer = NULL;
|
||||||
|
char *p = NULL;
|
||||||
|
int len = (int)strlen(newdir);
|
||||||
|
|
||||||
|
if (len <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
buffer = (char*)malloc(len + 1);
|
||||||
|
if (buffer == NULL)
|
||||||
|
{
|
||||||
|
printf("Error allocating memory\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(buffer, newdir);
|
||||||
|
|
||||||
|
if (buffer[len - 1] == '/')
|
||||||
|
buffer[len - 1] = 0;
|
||||||
|
|
||||||
|
if (MKDIR(buffer) == 0)
|
||||||
|
{
|
||||||
|
free(buffer);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = buffer + 1;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
char hold;
|
||||||
|
while (*p && *p != '\\' && *p != '/')
|
||||||
|
p++;
|
||||||
|
hold = *p;
|
||||||
|
*p = 0;
|
||||||
|
|
||||||
|
if ((MKDIR(buffer) == -1) && (errno == ENOENT))
|
||||||
|
{
|
||||||
|
printf("couldn't create directory %s (%d)\n", buffer, errno);
|
||||||
|
free(buffer);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hold == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
*p++ = hold;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(buffer);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *get_file_handle(const char *path)
|
||||||
|
{
|
||||||
|
FILE *handle = NULL;
|
||||||
|
#if defined(WIN32)
|
||||||
|
wchar_t *pathWide = NULL;
|
||||||
|
int pathLength = 0;
|
||||||
|
|
||||||
|
pathLength = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0) + 1;
|
||||||
|
pathWide = (wchar_t*)calloc(pathLength, sizeof(wchar_t));
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, path, -1, pathWide, pathLength);
|
||||||
|
handle = _wfopen((const wchar_t*)pathWide, L"rb");
|
||||||
|
free(pathWide);
|
||||||
|
#else
|
||||||
|
handle = fopen64(path, "rb");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
int check_file_exists(const char *path)
|
||||||
|
{
|
||||||
|
FILE *handle = get_file_handle(path);
|
||||||
|
if (handle == NULL)
|
||||||
|
return 0;
|
||||||
|
fclose(handle);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int is_large_file(const char *path)
|
||||||
|
{
|
||||||
|
FILE* handle = NULL;
|
||||||
|
uint64_t pos = 0;
|
||||||
|
|
||||||
|
handle = get_file_handle(path);
|
||||||
|
if (handle == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
fseeko64(handle, 0, SEEK_END);
|
||||||
|
pos = ftello64(handle);
|
||||||
|
fclose(handle);
|
||||||
|
|
||||||
|
printf("file : %s is %lld bytes\n", path, pos);
|
||||||
|
|
||||||
|
return (pos >= UINT32_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
void display_zpos64(uint64_t n, int size_char)
|
||||||
|
{
|
||||||
|
/* To avoid compatibility problem we do here the conversion */
|
||||||
|
char number[21] = { 0 };
|
||||||
|
int offset = 19;
|
||||||
|
int pos_string = 19;
|
||||||
|
int size_display_string = 19;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
number[offset] = (char)((n % 10) + '0');
|
||||||
|
if (number[offset] != '0')
|
||||||
|
pos_string = offset;
|
||||||
|
n /= 10;
|
||||||
|
if (offset == 0)
|
||||||
|
break;
|
||||||
|
offset--;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_display_string -= pos_string;
|
||||||
|
while (size_char-- > size_display_string)
|
||||||
|
printf(" ");
|
||||||
|
printf("%s", &number[pos_string]);
|
||||||
|
}
|
||||||
51
SSZipArchive/minizip/minishared.h
Normal file
51
SSZipArchive/minizip/minishared.h
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#ifndef _MINISHARED_H
|
||||||
|
#define _MINISHARED_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
# define MKDIR(d) _mkdir(d)
|
||||||
|
# define CHDIR(d) _chdir(d)
|
||||||
|
#else
|
||||||
|
# define MKDIR(d) mkdir(d, 0775)
|
||||||
|
# define CHDIR(d) chdir(d)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
|
/* Get a file's date and time in dos format */
|
||||||
|
uint32_t get_file_date(const char *path, uint32_t *dos_date);
|
||||||
|
|
||||||
|
/* Sets a file's date and time in dos format */
|
||||||
|
void change_file_date(const char *path, uint32_t dos_date);
|
||||||
|
|
||||||
|
/* Convert dos date/time format to struct tm */
|
||||||
|
int dosdate_to_tm(uint64_t dos_date, struct tm *ptm);
|
||||||
|
|
||||||
|
/* Convert dos date/time format to time_t */
|
||||||
|
time_t dosdate_to_time_t(uint64_t dos_date);
|
||||||
|
|
||||||
|
/* Convert struct tm to dos date/time format */
|
||||||
|
uint32_t tm_to_dosdate(const struct tm *ptm);
|
||||||
|
|
||||||
|
/* Create a directory and all subdirectories */
|
||||||
|
int makedir(const char *newdir);
|
||||||
|
|
||||||
|
/* Check to see if a file exists */
|
||||||
|
int check_file_exists(const char *path);
|
||||||
|
|
||||||
|
/* Check to see if a file is over 4GB and needs ZIP64 extension */
|
||||||
|
int is_large_file(const char *path);
|
||||||
|
|
||||||
|
/* Print a 64-bit number for compatibility */
|
||||||
|
void display_zpos64(uint64_t n, int size_char);
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _MINISHARED_H */
|
||||||
1999
SSZipArchive/minizip/unzip.c
Normal file
1999
SSZipArchive/minizip/unzip.c
Normal file
File diff suppressed because it is too large
Load Diff
254
SSZipArchive/minizip/unzip.h
Normal file
254
SSZipArchive/minizip/unzip.h
Normal file
@@ -0,0 +1,254 @@
|
|||||||
|
/* unzip.h -- IO for uncompress .zip files using zlib
|
||||||
|
Version 1.2.0, September 16th, 2017
|
||||||
|
part of the MiniZip project
|
||||||
|
|
||||||
|
Copyright (C) 2012-2017 Nathan Moinvaziri
|
||||||
|
https://github.com/nmoinvaz/minizip
|
||||||
|
Copyright (C) 2009-2010 Mathias Svensson
|
||||||
|
Modifications for Zip64 support on both zip and unzip
|
||||||
|
http://result42.com
|
||||||
|
Copyright (C) 2007-2008 Even Rouault
|
||||||
|
Modifications of Unzip for Zip64
|
||||||
|
Copyright (C) 1998-2010 Gilles Vollant
|
||||||
|
http://www.winimage.com/zLibDll/minizip.html
|
||||||
|
|
||||||
|
This program is distributed under the terms of the same license as zlib.
|
||||||
|
See the accompanying LICENSE file for the full text of the license.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _UNZ_H
|
||||||
|
#define _UNZ_H
|
||||||
|
|
||||||
|
#include "../SSZipCommon.h"
|
||||||
|
|
||||||
|
#define HAVE_AES
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _ZLIB_H
|
||||||
|
#include "zlib.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _ZLIBIOAPI_H
|
||||||
|
#include "ioapi.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_BZIP2
|
||||||
|
#include "bzlib.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define Z_BZIP2ED 12
|
||||||
|
|
||||||
|
#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
|
||||||
|
/* like the STRICT of WIN32, we define a pointer that cannot be converted
|
||||||
|
from (void*) without cast */
|
||||||
|
typedef struct TagunzFile__ { int unused; } unz_file__;
|
||||||
|
typedef unz_file__ *unzFile;
|
||||||
|
#else
|
||||||
|
typedef voidp unzFile;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define UNZ_OK (0)
|
||||||
|
#define UNZ_END_OF_LIST_OF_FILE (-100)
|
||||||
|
#define UNZ_ERRNO (Z_ERRNO)
|
||||||
|
#define UNZ_EOF (0)
|
||||||
|
#define UNZ_PARAMERROR (-102)
|
||||||
|
#define UNZ_BADZIPFILE (-103)
|
||||||
|
#define UNZ_INTERNALERROR (-104)
|
||||||
|
#define UNZ_CRCERROR (-105)
|
||||||
|
#define UNZ_BADPASSWORD (-106)
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* Opening and close a zip file */
|
||||||
|
|
||||||
|
extern unzFile ZEXPORT unzOpen(const char *path);
|
||||||
|
extern unzFile ZEXPORT unzOpen64(const void *path);
|
||||||
|
/* Open a Zip file.
|
||||||
|
|
||||||
|
path should contain the full path (by example, on a Windows XP computer
|
||||||
|
"c:\\zlib\\zlib113.zip" or on an Unix computer "zlib/zlib113.zip".
|
||||||
|
return NULL if zipfile cannot be opened or doesn't exist
|
||||||
|
return unzFile handle if no error
|
||||||
|
|
||||||
|
NOTE: The "64" function take a const void *pointer, because the path is just the value passed to the
|
||||||
|
open64_file_func callback. Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path
|
||||||
|
is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char *does not describe the reality */
|
||||||
|
|
||||||
|
extern unzFile ZEXPORT unzOpen2(const char *path, zlib_filefunc_def *pzlib_filefunc_def);
|
||||||
|
/* Open a Zip file, like unzOpen, but provide a set of file low level API for read/write operations */
|
||||||
|
extern unzFile ZEXPORT unzOpen2_64(const void *path, zlib_filefunc64_def *pzlib_filefunc_def);
|
||||||
|
/* Open a Zip file, like unz64Open, but provide a set of file low level API for read/write 64-bit operations */
|
||||||
|
|
||||||
|
extern int ZEXPORT unzClose(unzFile file);
|
||||||
|
/* Close a ZipFile opened with unzOpen. If there is files inside the .Zip opened with unzOpenCurrentFile,
|
||||||
|
these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
|
||||||
|
|
||||||
|
return UNZ_OK if there is no error */
|
||||||
|
|
||||||
|
extern int ZEXPORT unzGetGlobalInfo(unzFile file, unz_global_info *pglobal_info);
|
||||||
|
extern int ZEXPORT unzGetGlobalInfo64(unzFile file, unz_global_info64 *pglobal_info);
|
||||||
|
/* Write info about the ZipFile in the *pglobal_info structure.
|
||||||
|
|
||||||
|
return UNZ_OK if no error */
|
||||||
|
|
||||||
|
extern int ZEXPORT unzGetGlobalComment(unzFile file, char *comment, uint16_t comment_size);
|
||||||
|
/* Get the global comment string of the ZipFile, in the comment buffer.
|
||||||
|
|
||||||
|
uSizeBuf is the size of the szComment buffer.
|
||||||
|
return the number of byte copied or an error code <0 */
|
||||||
|
|
||||||
|
extern uint64_t ZEXPORT unzCountEntries(const unzFile file);
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* Reading the content of the current zipfile, you can open it, read data from it, and close it
|
||||||
|
(you can close it before reading all the file) */
|
||||||
|
|
||||||
|
extern int ZEXPORT unzOpenCurrentFile(unzFile file);
|
||||||
|
/* Open for reading data the current file in the zipfile.
|
||||||
|
|
||||||
|
return UNZ_OK if no error */
|
||||||
|
|
||||||
|
extern int ZEXPORT unzOpenCurrentFilePassword(unzFile file, const char *password);
|
||||||
|
/* Open for reading data the current file in the zipfile.
|
||||||
|
password is a crypting password
|
||||||
|
|
||||||
|
return UNZ_OK if no error */
|
||||||
|
|
||||||
|
extern int ZEXPORT unzOpenCurrentFile2(unzFile file, int *method, int *level, int raw);
|
||||||
|
/* Same as unzOpenCurrentFile, but open for read raw the file (not uncompress)
|
||||||
|
if raw==1 *method will receive method of compression, *level will receive level of compression
|
||||||
|
|
||||||
|
NOTE: you can set level parameter as NULL (if you did not want known level,
|
||||||
|
but you CANNOT set method parameter as NULL */
|
||||||
|
|
||||||
|
extern int ZEXPORT unzOpenCurrentFile3(unzFile file, int *method, int *level, int raw, const char *password);
|
||||||
|
/* Same as unzOpenCurrentFile, but takes extra parameter password for encrypted files */
|
||||||
|
|
||||||
|
extern int ZEXPORT unzReadCurrentFile(unzFile file, voidp buf, uint32_t len);
|
||||||
|
/* Read bytes from the current file (opened by unzOpenCurrentFile)
|
||||||
|
buf contain buffer where data must be copied
|
||||||
|
len the size of buf.
|
||||||
|
|
||||||
|
return the number of byte copied if somes bytes are copied
|
||||||
|
return 0 if the end of file was reached
|
||||||
|
return <0 with error code if there is an error (UNZ_ERRNO for IO error, or zLib error for uncompress error) */
|
||||||
|
|
||||||
|
extern int ZEXPORT unzGetCurrentFileInfo(unzFile file, unz_file_info *pfile_info, char *filename,
|
||||||
|
uint16_t filename_size, void *extrafield, uint16_t extrafield_size, char *comment, uint16_t comment_size);
|
||||||
|
extern int ZEXPORT unzGetCurrentFileInfo64(unzFile file, unz_file_info64 *pfile_info, char *filename,
|
||||||
|
uint16_t filename_size, void *extrafield, uint16_t extrafield_size, char *comment, uint16_t comment_size);
|
||||||
|
/* Get Info about the current file
|
||||||
|
|
||||||
|
pfile_info if != NULL, the *pfile_info structure will contain somes info about the current file
|
||||||
|
filename if != NULL, the file name string will be copied in filename
|
||||||
|
filename_size is the size of the filename buffer
|
||||||
|
extrafield if != NULL, the extra field information from the central header will be copied in to
|
||||||
|
extrafield_size is the size of the extraField buffer
|
||||||
|
comment if != NULL, the comment string of the file will be copied in to
|
||||||
|
comment_size is the size of the comment buffer */
|
||||||
|
|
||||||
|
extern int ZEXPORT unzGetLocalExtrafield(unzFile file, voidp buf, uint32_t len);
|
||||||
|
/* Read extra field from the current file (opened by unzOpenCurrentFile)
|
||||||
|
This is the local-header version of the extra field (sometimes, there is
|
||||||
|
more info in the local-header version than in the central-header)
|
||||||
|
|
||||||
|
if buf == NULL, it return the size of the local extra field
|
||||||
|
if buf != NULL, len is the size of the buffer, the extra header is copied in buf.
|
||||||
|
|
||||||
|
return number of bytes copied in buf, or (if <0) the error code */
|
||||||
|
|
||||||
|
extern int ZEXPORT unzCloseCurrentFile(unzFile file);
|
||||||
|
/* Close the file in zip opened with unzOpenCurrentFile
|
||||||
|
|
||||||
|
return UNZ_CRCERROR if all the file was read but the CRC is not good */
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* Browse the directory of the zipfile */
|
||||||
|
|
||||||
|
typedef int (*unzFileNameComparer)(unzFile file, const char *filename1, const char *filename2);
|
||||||
|
typedef int (*unzIteratorFunction)(unzFile file);
|
||||||
|
typedef int (*unzIteratorFunction2)(unzFile file, unz_file_info64 *pfile_info, char *filename,
|
||||||
|
uint16_t filename_size, void *extrafield, uint16_t extrafield_size, char *comment, uint16_t comment_size);
|
||||||
|
|
||||||
|
extern int ZEXPORT unzGoToFirstFile(unzFile file);
|
||||||
|
/* Set the current file of the zipfile to the first file.
|
||||||
|
|
||||||
|
return UNZ_OK if no error */
|
||||||
|
|
||||||
|
extern int ZEXPORT unzGoToFirstFile2(unzFile file, unz_file_info64 *pfile_info, char *filename,
|
||||||
|
uint16_t filename_size, void *extrafield, uint16_t extrafield_size, char *comment, uint16_t comment_size);
|
||||||
|
/* Set the current file of the zipfile to the first file and retrieves the current info on success.
|
||||||
|
Not as seek intensive as unzGoToFirstFile + unzGetCurrentFileInfo.
|
||||||
|
|
||||||
|
return UNZ_OK if no error */
|
||||||
|
|
||||||
|
extern int ZEXPORT unzGoToNextFile(unzFile file);
|
||||||
|
/* Set the current file of the zipfile to the next file.
|
||||||
|
|
||||||
|
return UNZ_OK if no error
|
||||||
|
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest */
|
||||||
|
|
||||||
|
extern int ZEXPORT unzGoToNextFile2(unzFile file, unz_file_info64 *pfile_info, char *filename,
|
||||||
|
uint16_t filename_size, void *extrafield, uint16_t extrafield_size, char *comment, uint16_t comment_size);
|
||||||
|
/* Set the current file of the zipfile to the next file and retrieves the current
|
||||||
|
info on success. Does less seeking around than unzGotoNextFile + unzGetCurrentFileInfo.
|
||||||
|
|
||||||
|
return UNZ_OK if no error
|
||||||
|
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest */
|
||||||
|
|
||||||
|
extern int ZEXPORT unzLocateFile(unzFile file, const char *filename, unzFileNameComparer filename_compare_func);
|
||||||
|
/* Try locate the file szFileName in the zipfile. For custom filename comparison pass in comparison function.
|
||||||
|
|
||||||
|
return UNZ_OK if the file is found (it becomes the current file)
|
||||||
|
return UNZ_END_OF_LIST_OF_FILE if the file is not found */
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* Raw access to zip file */
|
||||||
|
|
||||||
|
typedef struct unz_file_pos_s
|
||||||
|
{
|
||||||
|
uint32_t pos_in_zip_directory; /* offset in zip file directory */
|
||||||
|
uint32_t num_of_file; /* # of file */
|
||||||
|
} unz_file_pos;
|
||||||
|
|
||||||
|
extern int ZEXPORT unzGetFilePos(unzFile file, unz_file_pos *file_pos);
|
||||||
|
extern int ZEXPORT unzGoToFilePos(unzFile file, unz_file_pos *file_pos);
|
||||||
|
|
||||||
|
typedef struct unz64_file_pos_s
|
||||||
|
{
|
||||||
|
uint64_t pos_in_zip_directory; /* offset in zip file directory */
|
||||||
|
uint64_t num_of_file; /* # of file */
|
||||||
|
} unz64_file_pos;
|
||||||
|
|
||||||
|
extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos *file_pos);
|
||||||
|
extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos *file_pos);
|
||||||
|
|
||||||
|
extern int32_t ZEXPORT unzGetOffset(unzFile file);
|
||||||
|
extern int64_t ZEXPORT unzGetOffset64(unzFile file);
|
||||||
|
/* Get the current file offset */
|
||||||
|
|
||||||
|
extern int ZEXPORT unzSetOffset(unzFile file, uint32_t pos);
|
||||||
|
extern int ZEXPORT unzSetOffset64(unzFile file, uint64_t pos);
|
||||||
|
/* Set the current file offset */
|
||||||
|
|
||||||
|
extern int32_t ZEXPORT unzTell(unzFile file);
|
||||||
|
extern int64_t ZEXPORT unzTell64(unzFile file);
|
||||||
|
/* return current position in uncompressed data */
|
||||||
|
|
||||||
|
extern int ZEXPORT unzSeek(unzFile file, uint32_t offset, int origin);
|
||||||
|
extern int ZEXPORT unzSeek64(unzFile file, uint64_t offset, int origin);
|
||||||
|
/* Seek within the uncompressed data if compression method is storage */
|
||||||
|
|
||||||
|
extern int ZEXPORT unzEndOfFile(unzFile file);
|
||||||
|
/* return 1 if the end of file was reached, 0 elsewhere */
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _UNZ_H */
|
||||||
2009
SSZipArchive/minizip/zip.c
Normal file
2009
SSZipArchive/minizip/zip.c
Normal file
File diff suppressed because it is too large
Load Diff
215
SSZipArchive/minizip/zip.h
Normal file
215
SSZipArchive/minizip/zip.h
Normal file
@@ -0,0 +1,215 @@
|
|||||||
|
/* zip.h -- IO on .zip files using zlib
|
||||||
|
Version 1.2.0, September 16th, 2017
|
||||||
|
part of the MiniZip project
|
||||||
|
|
||||||
|
Copyright (C) 2012-2017 Nathan Moinvaziri
|
||||||
|
https://github.com/nmoinvaz/minizip
|
||||||
|
Copyright (C) 2009-2010 Mathias Svensson
|
||||||
|
Modifications for Zip64 support
|
||||||
|
http://result42.com
|
||||||
|
Copyright (C) 1998-2010 Gilles Vollant
|
||||||
|
http://www.winimage.com/zLibDll/minizip.html
|
||||||
|
|
||||||
|
This program is distributed under the terms of the same license as zlib.
|
||||||
|
See the accompanying LICENSE file for the full text of the license.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ZIP_H
|
||||||
|
#define _ZIP_H
|
||||||
|
|
||||||
|
#define HAVE_AES
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _ZLIB_H
|
||||||
|
# include "zlib.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _ZLIBIOAPI_H
|
||||||
|
# include "ioapi.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_BZIP2
|
||||||
|
# include "bzlib.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define Z_BZIP2ED 12
|
||||||
|
|
||||||
|
#if defined(STRICTZIP) || defined(STRICTZIPUNZIP)
|
||||||
|
/* like the STRICT of WIN32, we define a pointer that cannot be converted
|
||||||
|
from (void*) without cast */
|
||||||
|
typedef struct TagzipFile__ { int unused; } zip_file__;
|
||||||
|
typedef zip_file__ *zipFile;
|
||||||
|
#else
|
||||||
|
typedef voidp zipFile;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ZIP_OK (0)
|
||||||
|
#define ZIP_EOF (0)
|
||||||
|
#define ZIP_ERRNO (Z_ERRNO)
|
||||||
|
#define ZIP_PARAMERROR (-102)
|
||||||
|
#define ZIP_BADZIPFILE (-103)
|
||||||
|
#define ZIP_INTERNALERROR (-104)
|
||||||
|
|
||||||
|
#ifndef DEF_MEM_LEVEL
|
||||||
|
# if MAX_MEM_LEVEL >= 8
|
||||||
|
# define DEF_MEM_LEVEL 8
|
||||||
|
# else
|
||||||
|
# define DEF_MEM_LEVEL MAX_MEM_LEVEL
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t dos_date;
|
||||||
|
uint16_t internal_fa; /* internal file attributes 2 bytes */
|
||||||
|
uint32_t external_fa; /* external file attributes 4 bytes */
|
||||||
|
} zip_fileinfo;
|
||||||
|
|
||||||
|
#define APPEND_STATUS_CREATE (0)
|
||||||
|
#define APPEND_STATUS_CREATEAFTER (1)
|
||||||
|
#define APPEND_STATUS_ADDINZIP (2)
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* Writing a zip file */
|
||||||
|
|
||||||
|
extern zipFile ZEXPORT zipOpen(const char *path, int append);
|
||||||
|
extern zipFile ZEXPORT zipOpen64(const void *path, int append);
|
||||||
|
/* Create a zipfile.
|
||||||
|
|
||||||
|
path should contain the full path (by example, on a Windows XP computer
|
||||||
|
"c:\\zlib\\zlib113.zip" or on an Unix computer "zlib/zlib113.zip".
|
||||||
|
|
||||||
|
return NULL if zipfile cannot be opened
|
||||||
|
return zipFile handle if no error
|
||||||
|
|
||||||
|
If the file path exist and append == APPEND_STATUS_CREATEAFTER, the zip
|
||||||
|
will be created at the end of the file. (useful if the file contain a self extractor code)
|
||||||
|
If the file path exist and append == APPEND_STATUS_ADDINZIP, we will add files in existing
|
||||||
|
zip (be sure you don't add file that doesn't exist)
|
||||||
|
|
||||||
|
NOTE: There is no delete function into a zipfile. If you want delete file into a zipfile,
|
||||||
|
you must open a zipfile, and create another. Of course, you can use RAW reading and writing to copy
|
||||||
|
the file you did not want delete. */
|
||||||
|
|
||||||
|
extern zipFile ZEXPORT zipOpen2(const char *path, int append, const char **globalcomment,
|
||||||
|
zlib_filefunc_def *pzlib_filefunc_def);
|
||||||
|
|
||||||
|
extern zipFile ZEXPORT zipOpen2_64(const void *path, int append, const char **globalcomment,
|
||||||
|
zlib_filefunc64_def *pzlib_filefunc_def);
|
||||||
|
|
||||||
|
extern zipFile ZEXPORT zipOpen3(const char *path, int append, uint64_t disk_size,
|
||||||
|
const char **globalcomment, zlib_filefunc_def *pzlib_filefunc_def);
|
||||||
|
/* Same as zipOpen2 but allows specification of spanned zip size */
|
||||||
|
|
||||||
|
extern zipFile ZEXPORT zipOpen3_64(const void *path, int append, uint64_t disk_size,
|
||||||
|
const char **globalcomment, zlib_filefunc64_def *pzlib_filefunc_def);
|
||||||
|
|
||||||
|
extern int ZEXPORT zipOpenNewFileInZip(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
||||||
|
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
||||||
|
uint16_t size_extrafield_global, const char *comment, uint16_t method, int level);
|
||||||
|
/* Open a file in the ZIP for writing.
|
||||||
|
|
||||||
|
filename : the filename in zip (if NULL, '-' without quote will be used
|
||||||
|
*zipfi contain supplemental information
|
||||||
|
extrafield_local buffer to store the local header extra field data, can be NULL
|
||||||
|
size_extrafield_local size of extrafield_local buffer
|
||||||
|
extrafield_global buffer to store the global header extra field data, can be NULL
|
||||||
|
size_extrafield_global size of extrafield_local buffer
|
||||||
|
comment buffer for comment string
|
||||||
|
method contain the compression method (0 for store, Z_DEFLATED for deflate)
|
||||||
|
level contain the level of compression (can be Z_DEFAULT_COMPRESSION)
|
||||||
|
zip64 is set to 1 if a zip64 extended information block should be added to the local file header.
|
||||||
|
this MUST be '1' if the uncompressed size is >= 0xffffffff. */
|
||||||
|
|
||||||
|
extern int ZEXPORT zipOpenNewFileInZip64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
||||||
|
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
||||||
|
uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int zip64);
|
||||||
|
/* Same as zipOpenNewFileInZip with zip64 support */
|
||||||
|
|
||||||
|
extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
||||||
|
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
||||||
|
uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int raw);
|
||||||
|
/* Same as zipOpenNewFileInZip, except if raw=1, we write raw file */
|
||||||
|
|
||||||
|
extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
||||||
|
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
||||||
|
uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int raw, int zip64);
|
||||||
|
/* Same as zipOpenNewFileInZip3 with zip64 support */
|
||||||
|
|
||||||
|
extern int ZEXPORT zipOpenNewFileInZip3(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
||||||
|
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
||||||
|
uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int raw, int windowBits, int memLevel,
|
||||||
|
int strategy, const char *password, ZIP_UNUSED uint32_t crc_for_crypting);
|
||||||
|
/* Same as zipOpenNewFileInZip2, except
|
||||||
|
windowBits, memLevel, strategy : see parameter strategy in deflateInit2
|
||||||
|
password : crypting password (NULL for no crypting)
|
||||||
|
crc_for_crypting : crc of file to compress (needed for crypting) */
|
||||||
|
|
||||||
|
extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
||||||
|
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
||||||
|
uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int raw, int windowBits, int memLevel,
|
||||||
|
int strategy, const char *password, ZIP_UNUSED uint32_t crc_for_crypting, int zip64);
|
||||||
|
/* Same as zipOpenNewFileInZip3 with zip64 support */
|
||||||
|
|
||||||
|
extern int ZEXPORT zipOpenNewFileInZip4(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
||||||
|
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
||||||
|
uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int raw, int windowBits, int memLevel,
|
||||||
|
int strategy, const char *password, ZIP_UNUSED uint32_t crc_for_crypting, uint16_t version_madeby, uint16_t flag_base);
|
||||||
|
/* Same as zipOpenNewFileInZip3 except versionMadeBy & flag fields */
|
||||||
|
|
||||||
|
extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
||||||
|
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
||||||
|
uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int raw, int windowBits, int memLevel,
|
||||||
|
int strategy, const char *password, ZIP_UNUSED uint32_t crc_for_crypting, uint16_t version_madeby, uint16_t flag_base, int zip64);
|
||||||
|
/* Same as zipOpenNewFileInZip4 with zip64 support */
|
||||||
|
|
||||||
|
extern int ZEXPORT zipOpenNewFileInZip5(zipFile file,
|
||||||
|
const char *filename,
|
||||||
|
const zip_fileinfo *zipfi,
|
||||||
|
const void *extrafield_local,
|
||||||
|
uint16_t size_extrafield_local,
|
||||||
|
const void *extrafield_global,
|
||||||
|
uint16_t size_extrafield_global,
|
||||||
|
const char *comment,
|
||||||
|
uint16_t flag_base,
|
||||||
|
int zip64,
|
||||||
|
uint16_t method,
|
||||||
|
int level,
|
||||||
|
int raw,
|
||||||
|
int windowBits,
|
||||||
|
int memLevel,
|
||||||
|
int strategy,
|
||||||
|
const char *password,
|
||||||
|
int aes,
|
||||||
|
uint16_t version_madeby);
|
||||||
|
/* Allowing optional aes */
|
||||||
|
|
||||||
|
extern int ZEXPORT zipWriteInFileInZip(zipFile file, const void *buf, uint32_t len);
|
||||||
|
/* Write data in the zipfile */
|
||||||
|
|
||||||
|
extern int ZEXPORT zipCloseFileInZip(zipFile file);
|
||||||
|
/* Close the current file in the zipfile */
|
||||||
|
|
||||||
|
extern int ZEXPORT zipCloseFileInZipRaw(zipFile file, uint32_t uncompressed_size, uint32_t crc32);
|
||||||
|
extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, uint64_t uncompressed_size, uint32_t crc32);
|
||||||
|
/* Close the current file in the zipfile, for file opened with parameter raw=1 in zipOpenNewFileInZip2
|
||||||
|
where raw is compressed data. Parameters uncompressed_size and crc32 are value for the uncompressed data. */
|
||||||
|
|
||||||
|
extern int ZEXPORT zipClose(zipFile file, const char *global_comment);
|
||||||
|
/* Close the zipfile */
|
||||||
|
|
||||||
|
extern int ZEXPORT zipClose_64(zipFile file, const char *global_comment);
|
||||||
|
|
||||||
|
extern int ZEXPORT zipClose2_64(zipFile file, const char *global_comment, uint16_t version_madeby);
|
||||||
|
/* Same as zipClose_64 except version_madeby field */
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _ZIP_H */
|
||||||
8
TDAppDelegate.h
Normal file
8
TDAppDelegate.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
@interface TDAppDelegate : UIResponder <UIApplicationDelegate>
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UIWindow *window;
|
||||||
|
@property (nonatomic, strong) UINavigationController *rootViewController;
|
||||||
|
|
||||||
|
@end
|
||||||
14
TDAppDelegate.m
Normal file
14
TDAppDelegate.m
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#import "TDAppDelegate.h"
|
||||||
|
#import "TDRootViewController.h"
|
||||||
|
|
||||||
|
@implementation TDAppDelegate
|
||||||
|
|
||||||
|
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||||
|
_window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||||
|
_rootViewController = [[UINavigationController alloc] initWithRootViewController:[[TDRootViewController alloc] init]];
|
||||||
|
_window.rootViewController = _rootViewController;
|
||||||
|
[_window makeKeyAndVisible];
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
17
TDDumpDecrypted.h
Normal file
17
TDDumpDecrypted.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
@interface DumpDecrypted : NSObject {
|
||||||
|
char decryptedAppPathStr[PATH_MAX];
|
||||||
|
char *filename;
|
||||||
|
char *appDirName;
|
||||||
|
char *appDirPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
@property (assign) NSString *appPath;
|
||||||
|
@property (assign) NSString *docPath;
|
||||||
|
@property (assign) NSString *appName;
|
||||||
|
@property (assign) NSString *appVersion;
|
||||||
|
|
||||||
|
- (id)initWithPathToBinary:(NSString *)pathToBinary appName:(NSString *)appName appVersion:(NSString *)appVersion;
|
||||||
|
- (void)createIPAFile:(pid_t)pid;
|
||||||
|
- (BOOL)dumpDecryptedImage:(const struct mach_header *)image_mh fileName:(const char *)encryptedImageFilenameStr image:(int)imageNum task:(vm_map_t)targetTask;
|
||||||
|
- (NSString *)IPAPath;
|
||||||
|
@end
|
||||||
615
TDDumpDecrypted.m
Normal file
615
TDDumpDecrypted.m
Normal file
@@ -0,0 +1,615 @@
|
|||||||
|
/*
|
||||||
|
bfinject - Inject shared libraries into running App Store apps on iOS 11.x < 11.2
|
||||||
|
https://github.com/BishopFox/bfinject
|
||||||
|
|
||||||
|
Carl Livitt @ Bishop Fox
|
||||||
|
|
||||||
|
Based on code originally by 10n1c: https://github.com/stefanesser/dumpdecrypted/blob/master/dumpdecrypted.c
|
||||||
|
Now with the following enhancements:
|
||||||
|
- Dump ALL encrypted images in the target application: the app itself, its frameworks, etc.
|
||||||
|
- Create a valid .ipa containing the decrypted binaries. Save it in ~/Documents/decrypted-app.ipa
|
||||||
|
- The .ipa can be modified and re-signed with a developer cert for redeployment to non-jailbroken devices
|
||||||
|
- Auto detection of all the necessary sandbox paths
|
||||||
|
- Converted into an Objective-C class for ease of use.
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <mach-o/fat.h>
|
||||||
|
#include <mach-o/loader.h>
|
||||||
|
#include <mach-o/dyld.h>
|
||||||
|
#include <objc/runtime.h>
|
||||||
|
#include <mach/mach.h>
|
||||||
|
#include <err.h>
|
||||||
|
#include <mach-o/ldsyms.h>
|
||||||
|
#include <libkern/OSCacheControl.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <ifaddrs.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#import "SSZipArchive/SSZipArchive.h"
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
#include <mach/vm_map.h>
|
||||||
|
#include <mach-o/dyld_images.h>
|
||||||
|
#include <mach/task_info.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <mach/machine.h>
|
||||||
|
|
||||||
|
#include "TDDumpDecrypted.h"
|
||||||
|
#import "TDUtils.h"
|
||||||
|
|
||||||
|
kern_return_t
|
||||||
|
mach_vm_read_overwrite(vm_map_t, mach_vm_address_t, mach_vm_size_t, mach_vm_address_t, mach_vm_size_t *);
|
||||||
|
// kern_return_t mach_vm_read(vm_map_t target_task, mach_vm_address_t address, mach_vm_size_t size, vm_offset_t *data, mach_msg_type_number_t *dataCnt);
|
||||||
|
kern_return_t
|
||||||
|
mach_vm_region(vm_map_read_t target_task, mach_vm_address_t *address, mach_vm_size_t *size, vm_region_flavor_t flavor, vm_region_info_t info, mach_msg_type_number_t *infoCnt, mach_port_t *object_name);
|
||||||
|
|
||||||
|
|
||||||
|
//#define DEBUG(...) NSLog(__VA_ARGS__);
|
||||||
|
// #define DEBUG(...) {}
|
||||||
|
|
||||||
|
#define swap32(value) (((value & 0xFF000000) >> 24) | ((value & 0x00FF0000) >> 8) | ((value & 0x0000FF00) << 8) | ((value & 0x000000FF) << 24) )
|
||||||
|
|
||||||
|
unsigned char *readProcessMemory (mach_port_t proc, mach_vm_address_t addr, mach_msg_type_number_t* size) {
|
||||||
|
mach_msg_type_number_t dataCnt = (mach_msg_type_number_t) *size;
|
||||||
|
vm_offset_t readMem;
|
||||||
|
|
||||||
|
kern_return_t kr = vm_read(proc, addr, *size, &readMem, &dataCnt);
|
||||||
|
|
||||||
|
if (kr) {
|
||||||
|
//fprintf (stderr, "Unable to read target task's memory @%p - kr 0x%x\n", (void *) addr, kr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ((unsigned char *) readMem);
|
||||||
|
}
|
||||||
|
|
||||||
|
static kern_return_t
|
||||||
|
readmem(mach_vm_offset_t *buffer, mach_vm_address_t address, mach_vm_size_t size, vm_map_t targetTask, vm_region_basic_info_data_64_t *info)
|
||||||
|
{
|
||||||
|
// get task for pid
|
||||||
|
vm_map_t port = targetTask;
|
||||||
|
|
||||||
|
kern_return_t kr;
|
||||||
|
mach_msg_type_number_t info_cnt = sizeof (vm_region_basic_info_data_64_t);
|
||||||
|
mach_port_t object_name;
|
||||||
|
mach_vm_size_t size_info;
|
||||||
|
mach_vm_address_t address_info = address;
|
||||||
|
kr = mach_vm_region(port, &address_info, &size_info, VM_REGION_BASIC_INFO_64, (vm_region_info_t)info, &info_cnt, &object_name);
|
||||||
|
if (kr)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "[ERROR] mach_vm_region failed with error %d\n", (int)kr);
|
||||||
|
return KERN_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read memory - vm_read_overwrite because we supply the buffer */
|
||||||
|
mach_vm_size_t nread;
|
||||||
|
kr = mach_vm_read_overwrite(port, address, size, (mach_vm_address_t)buffer, &nread);
|
||||||
|
if (kr)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "[ERROR] vm_read failed! %d\n", kr);
|
||||||
|
return KERN_FAILURE;
|
||||||
|
}
|
||||||
|
else if (nread != size)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "[ERROR] vm_read failed! requested size: 0x%llx read: 0x%llx\n", size, nread);
|
||||||
|
return KERN_FAILURE;
|
||||||
|
}
|
||||||
|
return KERN_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t
|
||||||
|
get_image_size(mach_vm_address_t address, vm_map_t targetTask, uint64_t *vmaddr_slide)
|
||||||
|
{
|
||||||
|
vm_region_basic_info_data_64_t region_info = {0};
|
||||||
|
// allocate a buffer to read the header info
|
||||||
|
// NOTE: this is not exactly correct since the 64bit version has an extra 4 bytes
|
||||||
|
// but this will work for this purpose so no need for more complexity!
|
||||||
|
struct mach_header header = {0};
|
||||||
|
if (readmem((mach_vm_offset_t*)&header, address, sizeof(struct mach_header), targetTask, ®ion_info))
|
||||||
|
{
|
||||||
|
printf("Can't read header!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (header.magic != MH_MAGIC && header.magic != MH_MAGIC_64)
|
||||||
|
{
|
||||||
|
printf("[ERROR] Target is not a mach-o binary!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t imagefilesize = -1;
|
||||||
|
/* read the load commands */
|
||||||
|
uint8_t *loadcmds = (uint8_t*)malloc(header.sizeofcmds);
|
||||||
|
uint16_t mach_header_size = sizeof(struct mach_header);
|
||||||
|
if (header.magic == MH_MAGIC_64)
|
||||||
|
{
|
||||||
|
mach_header_size = sizeof(struct mach_header_64);
|
||||||
|
}
|
||||||
|
if (readmem((mach_vm_offset_t*)loadcmds, address+mach_header_size, header.sizeofcmds, targetTask, ®ion_info))
|
||||||
|
{
|
||||||
|
printf("Can't read load commands\n");
|
||||||
|
free(loadcmds);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* process and retrieve address and size of linkedit */
|
||||||
|
uint8_t *loadCmdAddress = 0;
|
||||||
|
loadCmdAddress = (uint8_t*)loadcmds;
|
||||||
|
struct load_command *loadCommand = NULL;
|
||||||
|
struct segment_command *segCmd = NULL;
|
||||||
|
struct segment_command_64 *segCmd64 = NULL;
|
||||||
|
for (uint32_t i = 0; i < header.ncmds; i++)
|
||||||
|
{
|
||||||
|
loadCommand = (struct load_command*)loadCmdAddress;
|
||||||
|
if (loadCommand->cmd == LC_SEGMENT)
|
||||||
|
{
|
||||||
|
segCmd = (struct segment_command*)loadCmdAddress;
|
||||||
|
if (strncmp(segCmd->segname, "__PAGEZERO", 16) != 0)
|
||||||
|
{
|
||||||
|
if (strncmp(segCmd->segname, "__TEXT", 16) == 0)
|
||||||
|
{
|
||||||
|
*vmaddr_slide = address - segCmd->vmaddr;
|
||||||
|
}
|
||||||
|
imagefilesize += segCmd->filesize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (loadCommand->cmd == LC_SEGMENT_64)
|
||||||
|
{
|
||||||
|
segCmd64 = (struct segment_command_64*)loadCmdAddress;
|
||||||
|
if (strncmp(segCmd64->segname, "__PAGEZERO", 16) != 0)
|
||||||
|
{
|
||||||
|
if (strncmp(segCmd64->segname, "__TEXT", 16) == 0)
|
||||||
|
{
|
||||||
|
*vmaddr_slide = address - segCmd64->vmaddr;
|
||||||
|
}
|
||||||
|
imagefilesize += segCmd64->filesize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// advance to next command
|
||||||
|
loadCmdAddress += loadCommand->cmdsize;
|
||||||
|
}
|
||||||
|
free(loadcmds);
|
||||||
|
return imagefilesize;
|
||||||
|
}
|
||||||
|
|
||||||
|
int find_off_cryptid(const char *filePath) {
|
||||||
|
NSLog(@"[trolldecrypt] %s filePath: %s", __FUNCTION__, filePath);
|
||||||
|
int off_cryptid = 0;
|
||||||
|
FILE* file = fopen(filePath, "rb");
|
||||||
|
if (!file) return 1;
|
||||||
|
|
||||||
|
fseek(file, 0, SEEK_END);
|
||||||
|
long fileSize = ftell(file);
|
||||||
|
fseek(file, 0, SEEK_SET);
|
||||||
|
|
||||||
|
char* buffer = malloc(fileSize);//new char[fileSize];
|
||||||
|
fread(buffer, 1, fileSize, file);
|
||||||
|
|
||||||
|
struct mach_header_64* header = (struct mach_header_64*)buffer;
|
||||||
|
if (header->magic != MH_MAGIC_64) {
|
||||||
|
printf("[-] error: not a valid macho file\n");
|
||||||
|
free(buffer);
|
||||||
|
fclose(file);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct load_command* lc = (struct load_command*)((mach_vm_address_t)header + sizeof(struct mach_header_64));
|
||||||
|
for (uint32_t i = 0; i < header->ncmds; i++) {
|
||||||
|
if (lc->cmd == LC_ENCRYPTION_INFO || lc->cmd == LC_ENCRYPTION_INFO_64) {
|
||||||
|
struct encryption_info_command *encryption_info = (struct encryption_info_command*) lc;
|
||||||
|
|
||||||
|
|
||||||
|
NSLog(@"[trolldecrypt] cryptid: %d\n", encryption_info->cryptid);
|
||||||
|
NSLog(@"[trolldecrypt] Found cryptid at offset: 0x%llx\n", (mach_vm_address_t)lc + offsetof(struct encryption_info_command, cryptid) - (mach_vm_address_t)header);
|
||||||
|
|
||||||
|
off_cryptid = (mach_vm_address_t)lc + offsetof(struct encryption_info_command, cryptid) - (mach_vm_address_t)header;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lc = (struct load_command*)((mach_vm_address_t)lc + lc->cmdsize);
|
||||||
|
}
|
||||||
|
free(buffer);
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
return off_cryptid;
|
||||||
|
}
|
||||||
|
|
||||||
|
@implementation DumpDecrypted
|
||||||
|
|
||||||
|
-(id) initWithPathToBinary:(NSString *)pathToBinary appName:(NSString *)appName appVersion:(NSString *)appVersion {
|
||||||
|
if(!self) {
|
||||||
|
self = [super init];
|
||||||
|
}
|
||||||
|
|
||||||
|
self.appName = appName;
|
||||||
|
self.appVersion = appVersion;
|
||||||
|
|
||||||
|
[self setAppPath:[pathToBinary stringByDeletingLastPathComponent]];
|
||||||
|
[self setDocPath:[NSString stringWithFormat:@"%@/Documents", NSHomeDirectory()]];
|
||||||
|
|
||||||
|
char *lastPartOfAppPath = strdup([[self appPath] UTF8String]);
|
||||||
|
lastPartOfAppPath = strrchr(lastPartOfAppPath, '/') + 1;
|
||||||
|
NSLog(@"[trolldecrypt] init: appDirName: %s", lastPartOfAppPath);
|
||||||
|
self->appDirName = strdup(lastPartOfAppPath);
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
-(void) makeDirectories:(const char *)encryptedImageFilenameStr {
|
||||||
|
char *appPath = (char *)[[self appPath] UTF8String];
|
||||||
|
char *docPath = (char *)[[self docPath] UTF8String];
|
||||||
|
char *savePtr;
|
||||||
|
char *encryptedImagePathStr = savePtr = strdup(encryptedImageFilenameStr);
|
||||||
|
self->filename = strdup(strrchr(encryptedImagePathStr, '/') + 1);
|
||||||
|
|
||||||
|
// Normalize the filenames
|
||||||
|
if(strstr(encryptedImagePathStr, "/private") == encryptedImagePathStr)
|
||||||
|
encryptedImagePathStr += 8;
|
||||||
|
if(strstr(appPath, "/private") == appPath)
|
||||||
|
appPath += 8;
|
||||||
|
|
||||||
|
// Find start of image path, relative to the base of the app sandbox (ie. /var/mobile/.../FooBar.app/THIS_PART_HERE)
|
||||||
|
encryptedImagePathStr += strlen(appPath) + 1; // skip over the app path
|
||||||
|
char *p = strrchr(encryptedImagePathStr, '/');
|
||||||
|
if(p)
|
||||||
|
*p = '\0';
|
||||||
|
|
||||||
|
NSLog(@"[trolldecrypt] encryptedImagePathStr: %s", encryptedImagePathStr);
|
||||||
|
|
||||||
|
NSFileManager *fm = [[NSFileManager alloc] init];
|
||||||
|
NSError *err;
|
||||||
|
char *lastPartOfAppPath = strdup(appPath); // Must free()
|
||||||
|
lastPartOfAppPath = strrchr(lastPartOfAppPath, '/');
|
||||||
|
lastPartOfAppPath++;
|
||||||
|
NSString *path = [NSString stringWithFormat:@"%s/ipa/Payload/%s", docPath, lastPartOfAppPath];
|
||||||
|
self->appDirPath = strdup([path UTF8String]);
|
||||||
|
if(p)
|
||||||
|
path = [NSString stringWithFormat:@"%@/%s", path, encryptedImagePathStr];
|
||||||
|
|
||||||
|
NSLog(@"[trolldecrypt] make_directories making dir: %@", path);
|
||||||
|
if(! [fm createDirectoryAtPath:path withIntermediateDirectories:true attributes:nil error:&err]) {
|
||||||
|
NSLog(@"[trolldecrypt] WARNING: make_directories failed to make directory %@. Error: %@", path, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(savePtr);
|
||||||
|
|
||||||
|
snprintf(self->decryptedAppPathStr, PATH_MAX, "%s/%s", [path UTF8String], self->filename);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
-(BOOL) dumpDecryptedImage:(vm_address_t)imageAddress fileName:(const char *)encryptedImageFilenameStr image:(int)imageNum task:(vm_map_t)targetTask{
|
||||||
|
// struct load_command *lc;
|
||||||
|
struct encryption_info_command *eic;
|
||||||
|
struct fat_header *fh;
|
||||||
|
struct fat_arch *arch;
|
||||||
|
// struct mach_header *mh;
|
||||||
|
char buffer[1024];
|
||||||
|
unsigned int fileoffs = 0, off_cryptid = 0, restsize;
|
||||||
|
int i, fd, outfd, r, n;
|
||||||
|
|
||||||
|
struct mach_header header = {0};
|
||||||
|
vm_region_basic_info_data_64_t region_info = {0};
|
||||||
|
if (readmem((mach_vm_offset_t*)&header, imageAddress, sizeof(struct mach_header), targetTask, ®ion_info))
|
||||||
|
{
|
||||||
|
NSLog(@"[trolldecrypt] Can't read header!");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
//XXX: change all image_mh -> header NOW
|
||||||
|
|
||||||
|
struct load_command *lc = (struct load_command*)malloc(header.sizeofcmds);
|
||||||
|
|
||||||
|
/* detect if this is a arm64 binary */
|
||||||
|
if (header.magic == MH_MAGIC_64) {
|
||||||
|
// lc = (struct load_command *)((unsigned char *)header + sizeof(struct mach_header_64));
|
||||||
|
readmem((mach_vm_offset_t*)lc, imageAddress+sizeof(struct mach_header_64), header.sizeofcmds, targetTask, ®ion_info);
|
||||||
|
NSLog(@"[trolldecrypt] detected 64bit ARM binary in memory.\n");
|
||||||
|
} else if(header.magic == MH_MAGIC) { /* we might want to check for other errors here, too */
|
||||||
|
// lc = (struct load_command *)((unsigned char *)header + sizeof(struct mach_header));
|
||||||
|
readmem((mach_vm_offset_t*)lc, imageAddress+sizeof(struct mach_header), header.sizeofcmds, targetTask, ®ion_info);
|
||||||
|
NSLog(@"[trolldecrypt] detected 32bit ARM binary in memory.\n");
|
||||||
|
} else {
|
||||||
|
NSLog(@"[trolldecrypt] No valid header found!!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// sleep(1);exit(1);
|
||||||
|
const struct mach_header *image_mh = &header;
|
||||||
|
|
||||||
|
/* searching all load commands for an LC_ENCRYPTION_INFO load command */
|
||||||
|
for (i=0; i<image_mh->ncmds; i++) {
|
||||||
|
if (lc->cmd == LC_ENCRYPTION_INFO || lc->cmd == LC_ENCRYPTION_INFO_64) {
|
||||||
|
eic = (struct encryption_info_command *)lc;
|
||||||
|
// struct encryption_info_command *eic = (uint8_t*)malloc(sizeof(struct encryption_info_command););
|
||||||
|
// readmem((mach_vm_offset_t*)eic, imageAddress+sizeof(struct mach_header_64), header.sizeofcmds, targetTask, ®ion_info);
|
||||||
|
|
||||||
|
const char *appFilename = strrchr(encryptedImageFilenameStr, '/');
|
||||||
|
if(appFilename == NULL) {
|
||||||
|
NSLog(@"[trolldecrypt] There are no / in the filename. This is an error.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
appFilename++;
|
||||||
|
|
||||||
|
/* If this load command is present, but data is not crypted then exit */
|
||||||
|
if (eic->cryptid == 0) {
|
||||||
|
NSLog(@"[trolldecrypt] CryptID = 0!! ");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a dir structure in ~ just like in /path/to/FooApp.app/Whatever
|
||||||
|
[self makeDirectories:encryptedImageFilenameStr];
|
||||||
|
|
||||||
|
//0x1518
|
||||||
|
uint32_t aslr_slide = 0;
|
||||||
|
get_image_size(imageAddress, targetTask, &aslr_slide);
|
||||||
|
NSLog(@"[trolldecrypt] aslr_slide= 0x%x", aslr_slide);
|
||||||
|
|
||||||
|
off_cryptid=find_off_cryptid(encryptedImageFilenameStr);
|
||||||
|
|
||||||
|
NSLog(@"[trolldecrypt] offset to cryptid (%d) found in memory @ %p (from %p). off_cryptid = %u (0x%x)\n", eic->cryptid, &eic->cryptid, image_mh, off_cryptid, off_cryptid);
|
||||||
|
//NSLog(@"[trolldecrypt] Found encrypted data at offset %u 0x%08x. image_mh @ %p. cryptedData @ 0x%x. cryptsize = %u (0x%x) bytes.\n", eic->cryptoff, eic->cryptoff, image_mh, (unsigned int)image_mh + eic->cryptoff, eic->cryptsize, eic->cryptsize);
|
||||||
|
|
||||||
|
NSLog(@"[trolldecrypt] Dumping: %s", encryptedImageFilenameStr);
|
||||||
|
NSLog(@"[trolldecrypt] Into: %s", self->decryptedAppPathStr);
|
||||||
|
fd = open(encryptedImageFilenameStr, O_RDONLY);
|
||||||
|
if (fd == -1) {
|
||||||
|
NSLog(@"[trolldecrypt] Failed to open %s", encryptedImageFilenameStr);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSLog(@"[trolldecrypt] Reading header");
|
||||||
|
n = read(fd, (void *)buffer, sizeof(buffer));
|
||||||
|
if (n != sizeof(buffer)) {
|
||||||
|
NSLog(@"[trolldecrypt] Warning read only %d of %lu bytes from encrypted file.\n", n, sizeof(buffer));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSLog(@"[trolldecrypt] Detecting header type\n");
|
||||||
|
fh = (struct fat_header *)buffer;
|
||||||
|
|
||||||
|
/* Is this a FAT file - we assume the right endianess */
|
||||||
|
if (fh->magic == FAT_CIGAM) {
|
||||||
|
NSLog(@"[trolldecrypt] Executable is a FAT image - searching for right architecture\n");
|
||||||
|
arch = (struct fat_arch *)&fh[1];
|
||||||
|
for (i=0; i<swap32(fh->nfat_arch); i++) {
|
||||||
|
if ((image_mh->cputype == swap32(arch->cputype)) && (image_mh->cpusubtype == swap32(arch->cpusubtype))) {
|
||||||
|
fileoffs = swap32(arch->offset);
|
||||||
|
NSLog(@"[trolldecrypt] Correct arch is at offset 0x%x in the file.\n", fileoffs);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
arch++;
|
||||||
|
}
|
||||||
|
if (fileoffs == 0) {
|
||||||
|
NSLog(@"[trolldecrypt] Could not find correct arch in FAT image\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (fh->magic == MH_MAGIC || fh->magic == MH_MAGIC_64) {
|
||||||
|
NSLog(@"[trolldecrypt] Executable is a plain MACH-O image, fileoffs = 0\n");
|
||||||
|
} else {
|
||||||
|
NSLog(@"[trolldecrypt] Executable is of unknown type, fileoffs = 0\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSLog(@"[trolldecrypt] Opening %s for writing.\n", decryptedAppPathStr);
|
||||||
|
outfd = open(decryptedAppPathStr, O_RDWR|O_CREAT|O_TRUNC, 0644);
|
||||||
|
if (outfd == -1) {
|
||||||
|
NSLog(@"[trolldecrypt] Failed opening: ");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate address of beginning of crypted data */
|
||||||
|
n = fileoffs + eic->cryptoff;
|
||||||
|
|
||||||
|
restsize = lseek(fd, 0, SEEK_END) - n - eic->cryptsize;
|
||||||
|
//NSLog(@"[trolldecrypt] restsize = %u, n = %u, cryptsize = %u, total = %u", restsize, n, eic->cryptsize, n + eic->cryptsize + restsize);
|
||||||
|
lseek(fd, 0, SEEK_SET);
|
||||||
|
|
||||||
|
NSLog(@"[trolldecrypt] Copying the not encrypted start of the file (%u bytes)\n", n);
|
||||||
|
|
||||||
|
/* first copy all the data before the encrypted data */
|
||||||
|
char *buf = (char *)malloc((size_t)n);
|
||||||
|
r = read(fd, buf, n);
|
||||||
|
if(r != n) {
|
||||||
|
NSLog(@"[trolldecrypt] Error reading start of file\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
r = write(outfd, buf, n);
|
||||||
|
if(r != n) {
|
||||||
|
NSLog(@"[trolldecrypt] Error writing start of file\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
free(buf);
|
||||||
|
|
||||||
|
/* now write the previously encrypted data */
|
||||||
|
|
||||||
|
NSLog(@"[trolldecrypt] Dumping the decrypted data into the file (%u bytes)\n", eic->cryptsize);
|
||||||
|
buf = (char *)malloc((size_t)eic->cryptsize);
|
||||||
|
readmem((mach_vm_offset_t*)buf, imageAddress+eic->cryptoff, eic->cryptsize, targetTask, ®ion_info);
|
||||||
|
// r = write(outfd, (unsigned char *)image_mh + eic->cryptoff, eic->cryptsize);
|
||||||
|
r = write(outfd, buf, eic->cryptsize);
|
||||||
|
if (r != eic->cryptsize) {
|
||||||
|
NSLog(@"[trolldecrypt] Error writing encrypted part of file\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
free(buf);
|
||||||
|
|
||||||
|
|
||||||
|
/* and finish with the remainder of the file */
|
||||||
|
NSLog(@"[trolldecrypt] Copying the not encrypted remainder of the file (%u bytes)\n", restsize);
|
||||||
|
lseek(fd, eic->cryptsize, SEEK_CUR);
|
||||||
|
buf = (char *)malloc((size_t)restsize);
|
||||||
|
r = read(fd, buf, restsize);
|
||||||
|
if (r != restsize) {
|
||||||
|
NSLog(@"[trolldecrypt] Error reading rest of file, got %u bytes\n", r);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
r = write(outfd, buf, restsize);
|
||||||
|
if (r != restsize) {
|
||||||
|
NSLog(@"[trolldecrypt] Error writing rest of file\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
free(buf);
|
||||||
|
|
||||||
|
|
||||||
|
if (off_cryptid) {
|
||||||
|
uint32_t zero=0;
|
||||||
|
NSLog(@"[trolldecrypt] Setting the LC_ENCRYPTION_INFO->cryptid to 0 at offset 0x%x into file\n", off_cryptid);
|
||||||
|
if (lseek(outfd, off_cryptid, SEEK_SET) == off_cryptid) {
|
||||||
|
if(write(outfd, &zero, 4) != 4) {
|
||||||
|
NSLog(@"[trolldecrypt] Error writing cryptid value!!\n");
|
||||||
|
// Not a fatal error, just warn
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
NSLog(@"[trolldecrypt] Failed to seek to cryptid offset!!");
|
||||||
|
// this error is not treated as fatal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
close(outfd);
|
||||||
|
sync();
|
||||||
|
// exit(1);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
lc = (struct load_command *)((unsigned char *)lc+lc->cmdsize);
|
||||||
|
// readmem((mach_vm_offset_t*)lc, lc+lc->cmdsize, header.sizeofcmds, targetTask, ®ion_info);
|
||||||
|
}
|
||||||
|
// DEBUG(@"[!] This mach-o file is not encrypted. Nothing was decrypted.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
-(void) dumpDecrypted:(pid_t)pid {
|
||||||
|
|
||||||
|
vm_map_t targetTask = 0;
|
||||||
|
if (task_for_pid(mach_task_self(), pid, &targetTask))
|
||||||
|
{
|
||||||
|
NSLog(@"[trolldecrypt] Can't execute task_for_pid! Do you have the right permissions/entitlements?\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//numberOfImages
|
||||||
|
struct task_dyld_info dyld_info;
|
||||||
|
mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
|
||||||
|
|
||||||
|
if(task_info(targetTask, TASK_DYLD_INFO, (task_info_t)&dyld_info, &count) != KERN_SUCCESS) exit(1);
|
||||||
|
|
||||||
|
mach_msg_type_number_t size = sizeof(struct dyld_all_image_infos);
|
||||||
|
uint8_t* data = readProcessMemory(targetTask, dyld_info.all_image_info_addr, &size);
|
||||||
|
struct dyld_all_image_infos* infos = (struct dyld_all_image_infos *) data;
|
||||||
|
|
||||||
|
mach_msg_type_number_t size2 = sizeof(struct dyld_image_info) * infos->infoArrayCount;
|
||||||
|
uint8_t* info_addr = readProcessMemory(targetTask, (mach_vm_address_t) infos->infoArray, &size2);
|
||||||
|
struct dyld_image_info* info = (struct dyld_image_info*) info_addr;
|
||||||
|
|
||||||
|
uint32_t numberOfImages = infos->infoArrayCount;
|
||||||
|
mach_vm_address_t imageAddress = 0;
|
||||||
|
const char *appPath = [[self appPath] UTF8String];
|
||||||
|
|
||||||
|
NSLog(@"[trolldecrypt] There are %d images mapped.", numberOfImages);
|
||||||
|
|
||||||
|
for (int i = 0; i < numberOfImages; i++) {
|
||||||
|
NSLog(@"[trolldecrypt] image %d", i);
|
||||||
|
mach_msg_type_number_t size3 = PATH_MAX;
|
||||||
|
uint8_t *fpath_addr = readProcessMemory(targetTask, (mach_vm_address_t) info[i].imageFilePath, &size3);
|
||||||
|
|
||||||
|
imageAddress = (struct mach_header *)info[i].imageLoadAddress;
|
||||||
|
const char *imageName = fpath_addr;
|
||||||
|
|
||||||
|
if(!imageName || !imageAddress)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
NSLog(@"[trolldecrypt] Comparing %s to %s", imageName, appPath);
|
||||||
|
|
||||||
|
if(strstr(imageName, appPath) != NULL) {
|
||||||
|
NSLog(@"[trolldecrypt] Dumping image %d: %s", i, imageName);
|
||||||
|
[self dumpDecryptedImage:imageAddress fileName:imageName image:i task: targetTask];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
-(BOOL)fileManager:(NSFileManager *)f shouldProceedAfterError:(BOOL)proceed copyingItemAtPath:(NSString *)path toPath:(NSString *)dest {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(NSString *)IPAPath {
|
||||||
|
return [NSString stringWithFormat:@"%@/%@_%@_decrypted.ipa", [self docPath], self.appName, self.appVersion];
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void) createIPAFile:(pid_t)pid {
|
||||||
|
NSString *IPAFile = [self IPAPath];
|
||||||
|
NSString *appDir = [self appPath];
|
||||||
|
NSString *appCopyDir = [NSString stringWithFormat:@"%@/ipa/Payload/%s", [self docPath], self->appDirName];
|
||||||
|
NSString *zipDir = [NSString stringWithFormat:@"%@/ipa", [self docPath]];
|
||||||
|
NSFileManager *fm = [[NSFileManager alloc] init];
|
||||||
|
NSError *err;
|
||||||
|
|
||||||
|
[fm removeItemAtPath:IPAFile error:nil];
|
||||||
|
[fm removeItemAtPath:appCopyDir error:nil];
|
||||||
|
[fm createDirectoryAtPath:appCopyDir withIntermediateDirectories:true attributes:nil error:nil];
|
||||||
|
|
||||||
|
[fm setDelegate:(id<NSFileManagerDelegate>)self];
|
||||||
|
|
||||||
|
NSLog(@"[trolldecrypt] ======== START FILE COPY - IGNORE ANY SANDBOX WARNINGS ========");
|
||||||
|
NSLog(@"[trolldecrypt] IPAFile: %@", IPAFile);
|
||||||
|
NSLog(@"[trolldecrypt] appDir: %@", appDir);
|
||||||
|
NSLog(@"[trolldecrypt] appCopyDir: %@", appCopyDir);
|
||||||
|
NSLog(@"[trolldecrypt] zipDir: %@", zipDir);
|
||||||
|
|
||||||
|
[fm copyItemAtPath:appDir toPath:appCopyDir error:&err];
|
||||||
|
NSLog(@"[trolldecrypt] ======== END OF FILE COPY ========");
|
||||||
|
// sleep(1);
|
||||||
|
// exit(1);
|
||||||
|
// Replace encrypted binaries with decrypted versions
|
||||||
|
NSLog(@"[trolldecrypt] ======== START DECRYPTION PROCESS ========");
|
||||||
|
[self dumpDecrypted:pid];
|
||||||
|
NSLog(@"[trolldecrypt] ======== DECRYPTION COMPLETE ========");
|
||||||
|
|
||||||
|
// ZIP it up
|
||||||
|
NSLog(@"[trolldecrypt] ======== STARTING ZIP ========");
|
||||||
|
NSLog(@"[trolldecrypt] IPA file: %@", IPAFile);
|
||||||
|
NSLog(@"[trolldecrypt] ZIP dir: %@", zipDir);
|
||||||
|
unlink([IPAFile UTF8String]);
|
||||||
|
@try {
|
||||||
|
BOOL success = [SSZipArchive createZipFileAtPath:IPAFile
|
||||||
|
withContentsOfDirectory:zipDir
|
||||||
|
keepParentDirectory:NO
|
||||||
|
compressionLevel:1
|
||||||
|
password:nil
|
||||||
|
AES:NO
|
||||||
|
progressHandler:nil
|
||||||
|
];
|
||||||
|
NSLog(@"[trolldecrypt] ======== ZIP operation complete: %s ========", (success)?"success":"failed");
|
||||||
|
}
|
||||||
|
@catch(NSException *e) {
|
||||||
|
NSLog(@"[trolldecrypt] BAAAAAAAARF during ZIP operation!!! , %@", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Clean up. Leave only the .ipa file.
|
||||||
|
[fm removeItemAtPath:zipDir error:nil];
|
||||||
|
|
||||||
|
NSLog(@"[trolldecrypt] ======== Wrote %@ ========", [self IPAPath]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
7
TDFileManagerViewController.h
Normal file
7
TDFileManagerViewController.h
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
@interface TDFileManagerViewController : UITableViewController
|
||||||
|
|
||||||
|
@property (nonatomic, strong) NSArray *fileList;
|
||||||
|
|
||||||
|
@end
|
||||||
97
TDFileManagerViewController.m
Normal file
97
TDFileManagerViewController.m
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
#import "TDFileManagerViewController.h"
|
||||||
|
#import "TDUtils.h"
|
||||||
|
|
||||||
|
@implementation TDFileManagerViewController
|
||||||
|
|
||||||
|
- (void)loadView {
|
||||||
|
[super loadView];
|
||||||
|
|
||||||
|
self.title = @"Decrypted IPAs";
|
||||||
|
self.fileList = decryptedFileList();
|
||||||
|
|
||||||
|
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(done)];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)refresh {
|
||||||
|
self.fileList = decryptedFileList();
|
||||||
|
[self.tableView reloadData];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)done {
|
||||||
|
[self dismissViewControllerAnimated:YES completion:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSInteger)numberOfSelectionsInTableView:(UITableView *)tableView {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||||
|
return self.fileList.count;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||||
|
static NSString *cellIdentifier = @"FileCell";
|
||||||
|
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
|
||||||
|
|
||||||
|
if (!cell) {
|
||||||
|
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
|
||||||
|
}
|
||||||
|
|
||||||
|
NSString *path = [docPath() stringByAppendingPathComponent:self.fileList[indexPath.row]];
|
||||||
|
NSDictionary *attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil];
|
||||||
|
NSDate *date = attributes[NSFileModificationDate];
|
||||||
|
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
|
||||||
|
[dateFormatter setDateFormat:@"MMM d, yyyy h:mm a"];
|
||||||
|
|
||||||
|
NSNumber *fileSize = attributes[NSFileSize];
|
||||||
|
|
||||||
|
|
||||||
|
cell.textLabel.text = self.fileList[indexPath.row];
|
||||||
|
cell.detailTextLabel.text = [dateFormatter stringFromDate:date];
|
||||||
|
cell.detailTextLabel.textColor = [UIColor systemGray2Color];
|
||||||
|
cell.imageView.image = [UIImage systemImageNamed:@"doc.fill"];
|
||||||
|
|
||||||
|
UILabel *label = [[UILabel alloc] init];
|
||||||
|
label.text = [NSString stringWithFormat:@"%.2f MB", [fileSize doubleValue] / 1000000.0f];
|
||||||
|
label.textColor = [UIColor systemGray2Color];
|
||||||
|
label.font = [UIFont systemFontOfSize:12.0f];
|
||||||
|
[label sizeToFit];
|
||||||
|
label.textAlignment = NSTextAlignmentCenter;
|
||||||
|
cell.accessoryView = label;
|
||||||
|
|
||||||
|
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||||
|
return 65.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (bool)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||||
|
UIContextualAction *deleteAction = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleDestructive title:@"Delete" handler:^(UIContextualAction *action, UIView *sourceView, void (^completionHandler)(BOOL)) {
|
||||||
|
NSString *file = self.fileList[indexPath.row];
|
||||||
|
NSString *path = [docPath() stringByAppendingPathComponent:file];
|
||||||
|
[[NSFileManager defaultManager] removeItemAtPath:path error:nil];
|
||||||
|
[self refresh];
|
||||||
|
}];
|
||||||
|
|
||||||
|
UISwipeActionsConfiguration *swipeActions = [UISwipeActionsConfiguration configurationWithActions:@[deleteAction]];
|
||||||
|
return swipeActions;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||||
|
NSString *file = self.fileList[indexPath.row];
|
||||||
|
NSString *path = [docPath() stringByAppendingPathComponent:file];
|
||||||
|
NSURL *url = [NSURL fileURLWithPath:path];
|
||||||
|
|
||||||
|
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:@[url] applicationActivities:nil];
|
||||||
|
[self presentViewController:activityViewController animated:YES completion:nil];
|
||||||
|
|
||||||
|
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
7
TDRootViewController.h
Normal file
7
TDRootViewController.h
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
@interface TDRootViewController : UITableViewController
|
||||||
|
|
||||||
|
@property (nonatomic, strong) NSArray *apps;
|
||||||
|
|
||||||
|
@end
|
||||||
109
TDRootViewController.m
Normal file
109
TDRootViewController.m
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
#import "TDRootViewController.h"
|
||||||
|
#import "TDFileManagerViewController.h"
|
||||||
|
#import "TDUtils.h"
|
||||||
|
|
||||||
|
@implementation TDRootViewController
|
||||||
|
|
||||||
|
- (void)loadView {
|
||||||
|
[super loadView];
|
||||||
|
|
||||||
|
self.apps = appList();
|
||||||
|
self.title = @"TrollDecrypt";
|
||||||
|
self.navigationController.navigationBar.prefersLargeTitles = YES;
|
||||||
|
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage systemImageNamed:@"info.circle"] style:UIBarButtonItemStylePlain target:self action:@selector(about:)];
|
||||||
|
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage systemImageNamed:@"folder"] style:UIBarButtonItemStylePlain target:self action:@selector(openDocs:)];
|
||||||
|
|
||||||
|
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
|
||||||
|
[refreshControl addTarget:self action:@selector(refreshApps:) forControlEvents:UIControlEventValueChanged];
|
||||||
|
self.refreshControl = refreshControl;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)openDocs:(id)sender {
|
||||||
|
TDFileManagerViewController *fmVC = [[TDFileManagerViewController alloc] init];
|
||||||
|
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:fmVC];
|
||||||
|
[self presentViewController:navController animated:YES completion:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)about:(id)sender {
|
||||||
|
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"TrollDecrypt" message:@"by fiore\nIcon by @super.user\nbfdecrypt by @bishopfox\ndumpdecrypted by @i0n1c\nUpdated for TrollStore by @wh1te4ever" preferredStyle:UIAlertControllerStyleAlert];
|
||||||
|
[alert addAction:[UIAlertAction actionWithTitle:@"Dismiss" style:UIAlertActionStyleCancel handler:nil]];
|
||||||
|
[self presentViewController:alert animated:YES completion:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)refreshApps:(UIRefreshControl *)refreshControl {
|
||||||
|
self.apps = appList();
|
||||||
|
[self.tableView reloadData];
|
||||||
|
[refreshControl endRefreshing];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||||
|
return self.apps.count;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||||
|
static NSString *cellIdentifier = @"AppCell";
|
||||||
|
UITableViewCell *cell;
|
||||||
|
if (([self.apps count] - 1) != indexPath.row) {
|
||||||
|
cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
|
||||||
|
if (cell == nil) cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
|
||||||
|
|
||||||
|
NSDictionary *app = self.apps[indexPath.row];
|
||||||
|
|
||||||
|
cell.textLabel.text = app[@"name"];
|
||||||
|
cell.detailTextLabel.text = [NSString stringWithFormat:@"%@ • %@", app[@"version"], app[@"bundleID"]];
|
||||||
|
cell.imageView.image = [UIImage _applicationIconImageForBundleIdentifier:app[@"bundleID"] format:iconFormat() scale:[UIScreen mainScreen].scale];
|
||||||
|
} else {
|
||||||
|
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:nil];
|
||||||
|
|
||||||
|
cell.textLabel.text = @"Advanced";
|
||||||
|
cell.detailTextLabel.text = @"Decrypt app from a specified PID";
|
||||||
|
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||||
|
return 80.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||||
|
UIAlertController *alert;
|
||||||
|
|
||||||
|
if (([self.apps count] - 1) != indexPath.row) {
|
||||||
|
NSDictionary *app = self.apps[indexPath.row];
|
||||||
|
|
||||||
|
alert = [UIAlertController alertControllerWithTitle:@"Decrypt" message:[NSString stringWithFormat:@"Decrypt %@?", app[@"name"]] preferredStyle:UIAlertControllerStyleAlert];
|
||||||
|
UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil];
|
||||||
|
UIAlertAction *decrypt = [UIAlertAction actionWithTitle:@"Yes" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
|
||||||
|
decryptApp(app);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[alert addAction:decrypt];
|
||||||
|
[alert addAction:cancel];
|
||||||
|
} else {
|
||||||
|
alert = [UIAlertController alertControllerWithTitle:@"Decrypt" message:@"Enter PID to decrypt" preferredStyle:UIAlertControllerStyleAlert];
|
||||||
|
[alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
|
||||||
|
textField.placeholder = @"PID";
|
||||||
|
textField.keyboardType = UIKeyboardTypeNumberPad;
|
||||||
|
}];
|
||||||
|
|
||||||
|
UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil];
|
||||||
|
UIAlertAction *decrypt = [UIAlertAction actionWithTitle:@"Decrypt" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
|
||||||
|
NSString *pid = alert.textFields.firstObject.text;
|
||||||
|
decryptAppWithPID([pid intValue]);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[alert addAction:decrypt];
|
||||||
|
[alert addAction:cancel];
|
||||||
|
}
|
||||||
|
|
||||||
|
[self presentViewController:alert animated:YES completion:nil];
|
||||||
|
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
58
TDUtils.h
Normal file
58
TDUtils.h
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <mach/mach.h>
|
||||||
|
#include <mach/vm_map.h>
|
||||||
|
#include <mach-o/loader.h>
|
||||||
|
#include <mach-o/dyld_images.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <mach/task_info.h>
|
||||||
|
|
||||||
|
#import <sys/sysctl.h>
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
@interface UIApplication (tweakName)
|
||||||
|
+ (id)sharedApplication;
|
||||||
|
- (BOOL)launchApplicationWithIdentifier:(id)arg1 suspended:(BOOL)arg2;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface LSApplicationProxy : NSObject
|
||||||
|
@property (readonly, nonatomic) NSString *bundleIdentifier; // ivar: _bundleIdentifier
|
||||||
|
@property (readonly) NSString *shortVersionString;
|
||||||
|
@property (readonly, nonatomic) NSString *canonicalExecutablePath;
|
||||||
|
@property (getter=isLaunchProhibited) BOOL launchProhibited;
|
||||||
|
@property (readonly, nonatomic) NSArray *appTags;
|
||||||
|
@property(readonly) NSString * applicationType;
|
||||||
|
- (NSString *)localizedName;
|
||||||
|
+ (instancetype)applicationProxyForIdentifier:(NSString*)identifier;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface LSApplicationWorkspace : NSObject
|
||||||
|
+ (instancetype)defaultWorkspace;
|
||||||
|
- (NSMutableArray<LSApplicationProxy *> *)allApplications;
|
||||||
|
- (NSArray<LSApplicationProxy *> *)allInstalledApplications;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface UIImage (Private)
|
||||||
|
+ (UIImage *)_applicationIconImageForBundleIdentifier:(NSString *)bundleIdentifier format:(NSUInteger)format scale:(CGFloat)scale;
|
||||||
|
@end
|
||||||
|
|
||||||
|
#define PROC_PIDPATHINFO 11
|
||||||
|
#define PROC_PIDPATHINFO_SIZE (MAXPATHLEN)
|
||||||
|
#define PROC_PIDPATHINFO_MAXSIZE (4 * MAXPATHLEN)
|
||||||
|
#define PROC_ALL_PIDS 1
|
||||||
|
#ifndef DEBUG
|
||||||
|
# define NSLog(...) (void)0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int proc_pidpath(int pid, void *buffer, uint32_t buffersize);
|
||||||
|
int proc_listpids(uint32_t type, uint32_t typeinfo, void *buffer, int buffersize);
|
||||||
|
NSArray *appList(void);
|
||||||
|
NSUInteger iconFormat(void);
|
||||||
|
NSArray *sysctl_ps(void);
|
||||||
|
void decryptApp(NSDictionary *app);
|
||||||
|
void decryptAppWithPID(pid_t pid);
|
||||||
|
void bfinject_rocknroll(pid_t pid, NSString *appName, NSString *version);
|
||||||
|
NSArray *decryptedFileList(void);
|
||||||
|
NSString *docPath(void);
|
||||||
372
TDUtils.m
Normal file
372
TDUtils.m
Normal file
@@ -0,0 +1,372 @@
|
|||||||
|
#import "TDUtils.h"
|
||||||
|
#import "TDDumpDecrypted.h"
|
||||||
|
|
||||||
|
UIWindow *alertWindow = NULL;
|
||||||
|
UIWindow *kw = NULL;
|
||||||
|
UIViewController *root = NULL;
|
||||||
|
UIAlertController *alertController = NULL;
|
||||||
|
UIAlertController *doneController = NULL;
|
||||||
|
UIAlertController *errorController = NULL;
|
||||||
|
|
||||||
|
NSArray *appList(void) {
|
||||||
|
NSMutableArray *apps = [NSMutableArray array];
|
||||||
|
|
||||||
|
for (LSApplicationProxy *app in [[LSApplicationWorkspace defaultWorkspace] allInstalledApplications]) {
|
||||||
|
if (![[app applicationType] isEqualToString:@"User"]) continue;
|
||||||
|
|
||||||
|
NSString *bundleID = app.bundleIdentifier;
|
||||||
|
NSString *name = [app localizedName];
|
||||||
|
NSString *version = app.shortVersionString;
|
||||||
|
NSString *executable = [app canonicalExecutablePath];
|
||||||
|
|
||||||
|
NSDictionary *item = @{
|
||||||
|
@"bundleID":bundleID,
|
||||||
|
@"name":name,
|
||||||
|
@"version":version,
|
||||||
|
@"executable":executable
|
||||||
|
};
|
||||||
|
|
||||||
|
[apps addObject:item];
|
||||||
|
}
|
||||||
|
|
||||||
|
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
|
||||||
|
[apps sortUsingDescriptors:@[descriptor]];
|
||||||
|
|
||||||
|
[apps addObject:@{@"bundleID":@"", @"name":@"", @"version":@"", @"executable":@""}];
|
||||||
|
|
||||||
|
return [apps copy];
|
||||||
|
}
|
||||||
|
|
||||||
|
NSUInteger iconFormat(void) {
|
||||||
|
return (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad) ? 8 : 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSArray *sysctl_ps(void) {
|
||||||
|
// int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0};
|
||||||
|
// size_t miblen = 4;
|
||||||
|
// size_t size;
|
||||||
|
// int st = sysctl(mib, miblen, NULL, &size, NULL, 0);
|
||||||
|
// struct kinfo_proc * process = NULL;
|
||||||
|
// struct kinfo_proc * newprocess = NULL;
|
||||||
|
|
||||||
|
// do {
|
||||||
|
// size += size / 10;
|
||||||
|
// newprocess = realloc(process, size);
|
||||||
|
// if (!newprocess){
|
||||||
|
// if (process){
|
||||||
|
// free(process);
|
||||||
|
// }
|
||||||
|
// return nil;
|
||||||
|
// }
|
||||||
|
// process = newprocess;
|
||||||
|
// st = sysctl(mib, miblen, process, &size, NULL, 0);
|
||||||
|
// } while (st == -1 && errno == ENOMEM);
|
||||||
|
|
||||||
|
// if (st == 0) {
|
||||||
|
// if (size % sizeof(struct kinfo_proc) == 0){
|
||||||
|
// int nprocess = size / sizeof(struct kinfo_proc);
|
||||||
|
// if (nprocess){
|
||||||
|
// NSMutableArray * array = [[NSMutableArray alloc] init];
|
||||||
|
// for (int i = nprocess - 1; i >= 0; i--){
|
||||||
|
// NSString *processID = [[NSString alloc] initWithFormat:@"%d", process[i].kp_proc.p_pid];
|
||||||
|
// NSString *processName = [[NSString alloc] initWithFormat:@"%s", process[i].kp_proc.p_comm];
|
||||||
|
// NSDictionary *dict = [[NSDictionary alloc] initWithObjects:[NSArray arrayWithObjects:processID, processName, nil] forKeys:[NSArray arrayWithObjects:@"pid", @"proc_name", nil]];
|
||||||
|
// [array addObject:dict];
|
||||||
|
// }
|
||||||
|
// free(process);
|
||||||
|
// return array;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
NSMutableArray *array = [[NSMutableArray alloc] init];
|
||||||
|
|
||||||
|
int numberOfProcesses = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0);
|
||||||
|
pid_t pids[numberOfProcesses];
|
||||||
|
bzero(pids, sizeof(pids));
|
||||||
|
proc_listpids(PROC_ALL_PIDS, 0, pids, sizeof(pids));
|
||||||
|
for (int i = 0; i < numberOfProcesses; ++i) {
|
||||||
|
if (pids[i] == 0) { continue; }
|
||||||
|
char pathBuffer[PROC_PIDPATHINFO_MAXSIZE];
|
||||||
|
bzero(pathBuffer, PROC_PIDPATHINFO_MAXSIZE);
|
||||||
|
proc_pidpath(pids[i], pathBuffer, sizeof(pathBuffer));
|
||||||
|
|
||||||
|
if (strlen(pathBuffer) > 0) {
|
||||||
|
NSString *processID = [[NSString alloc] initWithFormat:@"%d", pids[i]];
|
||||||
|
NSString *processName = [[NSString stringWithUTF8String:pathBuffer] lastPathComponent];
|
||||||
|
NSDictionary *dict = [[NSDictionary alloc] initWithObjects:[NSArray arrayWithObjects:processID, processName, nil] forKeys:[NSArray arrayWithObjects:@"pid", @"proc_name", nil]];
|
||||||
|
|
||||||
|
[array addObject:dict];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [array copy];
|
||||||
|
}
|
||||||
|
|
||||||
|
void decryptApp(NSDictionary *app) {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
alertWindow = [[UIWindow alloc] initWithFrame: [UIScreen mainScreen].bounds];
|
||||||
|
alertWindow.rootViewController = [UIViewController new];
|
||||||
|
alertWindow.windowLevel = UIWindowLevelAlert + 1;
|
||||||
|
[alertWindow makeKeyAndVisible];
|
||||||
|
|
||||||
|
// Show a "Decrypting!" alert on the device and block the UI
|
||||||
|
|
||||||
|
kw = alertWindow;
|
||||||
|
if([kw respondsToSelector:@selector(topmostPresentedViewController)])
|
||||||
|
root = [kw performSelector:@selector(topmostPresentedViewController)];
|
||||||
|
else
|
||||||
|
root = [kw rootViewController];
|
||||||
|
root.modalPresentationStyle = UIModalPresentationFullScreen;
|
||||||
|
});
|
||||||
|
|
||||||
|
NSLog(@"[trolldecrypt] spawning thread to do decryption in background...");
|
||||||
|
|
||||||
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
|
NSLog(@"[trolldecrypt] inside decryption thread.");
|
||||||
|
|
||||||
|
NSString *bundleID = app[@"bundleID"];
|
||||||
|
NSString *name = app[@"name"];
|
||||||
|
NSString *version = app[@"version"];
|
||||||
|
NSString *executable = app[@"executable"];
|
||||||
|
NSString *binaryName = [executable lastPathComponent];
|
||||||
|
|
||||||
|
NSLog(@"[trolldecrypt] bundleID: %@", bundleID);
|
||||||
|
NSLog(@"[trolldecrypt] name: %@", name);
|
||||||
|
NSLog(@"[trolldecrypt] version: %@", version);
|
||||||
|
NSLog(@"[trolldecrypt] executable: %@", executable);
|
||||||
|
NSLog(@"[trolldecrypt] binaryName: %@", binaryName);
|
||||||
|
|
||||||
|
[[UIApplication sharedApplication] launchApplicationWithIdentifier:bundleID suspended:YES];
|
||||||
|
sleep(1);
|
||||||
|
|
||||||
|
pid_t pid = -1;
|
||||||
|
NSArray *processes = sysctl_ps();
|
||||||
|
for (NSDictionary *process in processes) {
|
||||||
|
NSString *proc_name = process[@"proc_name"];
|
||||||
|
if ([proc_name isEqualToString:binaryName]) {
|
||||||
|
pid = [process[@"pid"] intValue];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pid == -1) {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
[alertController dismissViewControllerAnimated:NO completion:nil];
|
||||||
|
NSLog(@"[trolldecrypt] failed to get pid for binary name: %@", binaryName);
|
||||||
|
|
||||||
|
errorController = [UIAlertController alertControllerWithTitle:@"Error: -1" message:[NSString stringWithFormat:@"Failed to get PID for binary name: %@", binaryName] preferredStyle:UIAlertControllerStyleAlert];
|
||||||
|
UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Ok", @"Ok") style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
|
||||||
|
NSLog(@"[trolldecrypt] Ok action");
|
||||||
|
[errorController dismissViewControllerAnimated:NO completion:nil];
|
||||||
|
[kw removeFromSuperview];
|
||||||
|
kw.hidden = YES;
|
||||||
|
}];
|
||||||
|
|
||||||
|
[errorController addAction:okAction];
|
||||||
|
[root presentViewController:errorController animated:YES completion:nil];
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSLog(@"[trolldecrypt] pid: %d", pid);
|
||||||
|
|
||||||
|
bfinject_rocknroll(pid, name, version);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void bfinject_rocknroll(pid_t pid, NSString *appName, NSString *version) {
|
||||||
|
NSLog(@"[trolldecrypt] Spawning thread to do decryption in the background...");
|
||||||
|
|
||||||
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
|
NSLog(@"[trolldecrypt] Inside decryption thread");
|
||||||
|
|
||||||
|
char pathbuf[PROC_PIDPATHINFO_MAXSIZE];
|
||||||
|
// int proc_pidpath(pid, pathbuf, sizeof(pathbuf));
|
||||||
|
proc_pidpath(pid, pathbuf, sizeof(pathbuf));
|
||||||
|
const char *fullPathStr = pathbuf;
|
||||||
|
|
||||||
|
|
||||||
|
NSLog(@"[trolldecrypt] fullPathStr: %s", fullPathStr);
|
||||||
|
DumpDecrypted *dd = [[DumpDecrypted alloc] initWithPathToBinary:[NSString stringWithUTF8String:fullPathStr] appName:appName appVersion:version];
|
||||||
|
if(!dd) {
|
||||||
|
NSLog(@"[trolldecrypt] ERROR: failed to get DumpDecrypted instance");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSLog(@"[trolldecrypt] Full path to app: %s /// IPA File: %@", fullPathStr, [dd IPAPath]);
|
||||||
|
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
alertWindow = [[UIWindow alloc] initWithFrame: [UIScreen mainScreen].bounds];
|
||||||
|
alertWindow.rootViewController = [UIViewController new];
|
||||||
|
alertWindow.windowLevel = UIWindowLevelAlert + 1;
|
||||||
|
[alertWindow makeKeyAndVisible];
|
||||||
|
|
||||||
|
// Show a "Decrypting!" alert on the device and block the UI
|
||||||
|
alertController = [UIAlertController
|
||||||
|
alertControllerWithTitle:@"Decrypting"
|
||||||
|
message:@"Please wait, this will take a few seconds..."
|
||||||
|
preferredStyle:UIAlertControllerStyleAlert];
|
||||||
|
|
||||||
|
kw = alertWindow;
|
||||||
|
if([kw respondsToSelector:@selector(topmostPresentedViewController)])
|
||||||
|
root = [kw performSelector:@selector(topmostPresentedViewController)];
|
||||||
|
else
|
||||||
|
root = [kw rootViewController];
|
||||||
|
root.modalPresentationStyle = UIModalPresentationFullScreen;
|
||||||
|
[root presentViewController:alertController animated:YES completion:nil];
|
||||||
|
});
|
||||||
|
|
||||||
|
// Do the decryption
|
||||||
|
[dd createIPAFile:pid];
|
||||||
|
|
||||||
|
// Dismiss the alert box
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
[alertController dismissViewControllerAnimated:NO completion:nil];
|
||||||
|
|
||||||
|
doneController = [UIAlertController alertControllerWithTitle:@"Decryption Complete!" message:[NSString stringWithFormat:@"IPA file saved to:\n%@", [dd IPAPath]] preferredStyle:UIAlertControllerStyleAlert];
|
||||||
|
UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Ok", @"Ok") style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
|
||||||
|
NSLog(@"[trolldecrypt] Ok action");
|
||||||
|
[doneController dismissViewControllerAnimated:NO completion:nil];
|
||||||
|
[kw removeFromSuperview];
|
||||||
|
kw.hidden = YES;
|
||||||
|
}];
|
||||||
|
|
||||||
|
[doneController addAction:okAction];
|
||||||
|
[root presentViewController:doneController animated:YES completion:nil];
|
||||||
|
}); // dispatch on main
|
||||||
|
|
||||||
|
NSLog(@"[trolldecrypt] Over and out.");
|
||||||
|
while(1)
|
||||||
|
sleep(9999999);
|
||||||
|
}); // dispatch in background
|
||||||
|
|
||||||
|
NSLog(@"[trolldecrypt] All done, exiting constructor.");
|
||||||
|
}
|
||||||
|
|
||||||
|
NSArray *decryptedFileList(void) {
|
||||||
|
NSMutableArray *files = [NSMutableArray array];
|
||||||
|
|
||||||
|
// iterate through all files in the Documents directory
|
||||||
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||||
|
NSDirectoryEnumerator *directoryEnumerator = [fileManager enumeratorAtPath:docPath()];
|
||||||
|
|
||||||
|
NSString *file;
|
||||||
|
while (file = [directoryEnumerator nextObject]) {
|
||||||
|
if ([[file pathExtension] isEqualToString:@"ipa"]) {
|
||||||
|
NSString *filePath = [[docPath() stringByAppendingPathComponent:file] stringByStandardizingPath];
|
||||||
|
|
||||||
|
NSDictionary *fileAttributes = [fileManager attributesOfItemAtPath:filePath error:nil];
|
||||||
|
NSDate *modificationDate = [fileAttributes fileModificationDate];
|
||||||
|
|
||||||
|
NSDictionary *fileInfo = @{@"fileName": file, @"modificationDate": modificationDate};
|
||||||
|
[files addObject:fileInfo];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort the array based on modification date
|
||||||
|
NSArray *sortedFiles = [files sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
|
||||||
|
NSDate *date1 = [obj1 objectForKey:@"modificationDate"];
|
||||||
|
NSDate *date2 = [obj2 objectForKey:@"modificationDate"];
|
||||||
|
return [date2 compare:date1];
|
||||||
|
}];
|
||||||
|
|
||||||
|
return [sortedFiles valueForKey:@"fileName"];
|
||||||
|
}
|
||||||
|
|
||||||
|
NSString *docPath(void) {
|
||||||
|
return [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
|
||||||
|
}
|
||||||
|
|
||||||
|
void decryptAppWithPID(pid_t pid) {
|
||||||
|
// generate App NSDictionary object to pass into decryptApp()
|
||||||
|
// proc_pidpath(self.pid, buffer, sizeof(buffer));
|
||||||
|
NSString *message = nil;
|
||||||
|
NSString *error = nil;
|
||||||
|
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
alertWindow = [[UIWindow alloc] initWithFrame: [UIScreen mainScreen].bounds];
|
||||||
|
alertWindow.rootViewController = [UIViewController new];
|
||||||
|
alertWindow.windowLevel = UIWindowLevelAlert + 1;
|
||||||
|
[alertWindow makeKeyAndVisible];
|
||||||
|
|
||||||
|
// Show a "Decrypting!" alert on the device and block the UI
|
||||||
|
|
||||||
|
kw = alertWindow;
|
||||||
|
if([kw respondsToSelector:@selector(topmostPresentedViewController)])
|
||||||
|
root = [kw performSelector:@selector(topmostPresentedViewController)];
|
||||||
|
else
|
||||||
|
root = [kw rootViewController];
|
||||||
|
root.modalPresentationStyle = UIModalPresentationFullScreen;
|
||||||
|
});
|
||||||
|
|
||||||
|
NSLog(@"[trolldecrypt] pid: %d", pid);
|
||||||
|
|
||||||
|
char pathbuf[PROC_PIDPATHINFO_MAXSIZE];
|
||||||
|
proc_pidpath(pid, pathbuf, sizeof(pathbuf));
|
||||||
|
|
||||||
|
NSString *executable = [NSString stringWithUTF8String:pathbuf];
|
||||||
|
NSString *path = [executable stringByDeletingLastPathComponent];
|
||||||
|
NSDictionary *infoPlist = [NSDictionary dictionaryWithContentsOfFile:[path stringByAppendingPathComponent:@"Info.plist"]];
|
||||||
|
NSString *bundleID = infoPlist[@"CFBundleIdentifier"];
|
||||||
|
|
||||||
|
if (!bundleID) {
|
||||||
|
error = @"Error: -2";
|
||||||
|
message = [NSString stringWithFormat:@"Failed to get bundle id for pid: %d", pid];
|
||||||
|
}
|
||||||
|
|
||||||
|
LSApplicationProxy *app = [LSApplicationProxy applicationProxyForIdentifier:bundleID];
|
||||||
|
if (!app) {
|
||||||
|
error = @"Error: -3";
|
||||||
|
message = [NSString stringWithFormat:@"Failed to get LSApplicationProxy for bundle id: %@", bundleID];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message) {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
[alertController dismissViewControllerAnimated:NO completion:nil];
|
||||||
|
NSLog(@"[trolldecrypt] failed to get bundleid for pid: %d", pid);
|
||||||
|
|
||||||
|
errorController = [UIAlertController alertControllerWithTitle:error message:message preferredStyle:UIAlertControllerStyleAlert];
|
||||||
|
UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Ok", @"Ok") style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
|
||||||
|
NSLog(@"[trolldecrypt] Ok action");
|
||||||
|
[errorController dismissViewControllerAnimated:NO completion:nil];
|
||||||
|
[kw removeFromSuperview];
|
||||||
|
kw.hidden = YES;
|
||||||
|
}];
|
||||||
|
|
||||||
|
[errorController addAction:okAction];
|
||||||
|
[root presentViewController:errorController animated:YES completion:nil];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
NSLog(@"[trolldecrypt] app: %@", app);
|
||||||
|
|
||||||
|
NSString *name = [app localizedName];
|
||||||
|
NSString *version = app.shortVersionString;
|
||||||
|
if (!version) version = @"1.0";
|
||||||
|
|
||||||
|
NSString *exec = [app canonicalExecutablePath];
|
||||||
|
|
||||||
|
NSDictionary *appInfo = @{
|
||||||
|
@"bundleID":bundleID,
|
||||||
|
@"name":name,
|
||||||
|
@"version":version,
|
||||||
|
@"executable":exec
|
||||||
|
};
|
||||||
|
|
||||||
|
NSLog(@"[trolldecrypt] appInfo: %@", appInfo);
|
||||||
|
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
[alertController dismissViewControllerAnimated:NO completion:nil];
|
||||||
|
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Decrypt" message:[NSString stringWithFormat:@"Decrypt %@?", appInfo[@"name"]] preferredStyle:UIAlertControllerStyleAlert];
|
||||||
|
UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil];
|
||||||
|
UIAlertAction *decrypt = [UIAlertAction actionWithTitle:@"Yes" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
|
||||||
|
decryptApp(appInfo);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[alert addAction:decrypt];
|
||||||
|
[alert addAction:cancel];
|
||||||
|
|
||||||
|
[root presentViewController:alert animated:YES completion:nil];
|
||||||
|
});
|
||||||
|
}
|
||||||
8
control
Normal file
8
control
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Package: com.fiore.trolldecrypt
|
||||||
|
Name: TrollDecrypt
|
||||||
|
Version: 0.0.1
|
||||||
|
Architecture: iphoneos-arm
|
||||||
|
Description: An awesome application!
|
||||||
|
Maintainer: fiore
|
||||||
|
Author: fiore
|
||||||
|
Section: Utilities
|
||||||
38
entitlements.plist
Normal file
38
entitlements.plist
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>platform-application</key>
|
||||||
|
<true/>
|
||||||
|
<key>application-identifier</key>
|
||||||
|
<string>com.fiore.trolldecrypt</string>
|
||||||
|
<key>com.apple.security.exception.files.absolute-path.read-write</key>
|
||||||
|
<array>
|
||||||
|
<string>/</string>
|
||||||
|
</array>
|
||||||
|
<key>com.apple.private.security.no-sandbox</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.private.persona-mgmt</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.private.MobileContainerManager.allowed</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.private.security.container-manager</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.private.security.storage.AppBundles</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.private.security.storage.AppDataContainers</key>
|
||||||
|
<true/>
|
||||||
|
<key>task_for_pid-allow</key>
|
||||||
|
<true/>
|
||||||
|
<key>get-task-allow</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.get-task-allow</key>
|
||||||
|
<true/>
|
||||||
|
<key>proc_info-allow</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.system-task-ports</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.springboard.launchapplications</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
Reference in New Issue
Block a user