diff options
| author | John Hurst <jhurst@cinecert.com> | 2021-02-12 08:24:11 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-02-12 08:24:11 -0800 |
| commit | fc2f92cb883da9f5bd94a50033c2e99e141653a1 (patch) | |
| tree | 32592b449be218bbf41efbc1afbd82a8f6cae3d7 /src | |
| parent | 15d1d022d02d8782379dafac81fb51a9e6f5a157 (diff) | |
| parent | b5e47e45509ce3a1a696ef06583ef86a5e1e8223 (diff) | |
Merge pull request #70 from cinecert/sha1_builtin
Sha1 builtin
Diffstat (limited to 'src')
| -rw-r--r-- | src/AS_02_ACES.cpp | 5 | ||||
| -rw-r--r-- | src/CMakeLists.txt | 82 | ||||
| -rw-r--r-- | src/KM_aes.cpp | 416 | ||||
| -rw-r--r-- | src/KM_aes.h | 57 | ||||
| -rwxr-xr-x | src/KM_prng.cpp | 32 | ||||
| -rw-r--r-- | src/KM_sha1.cpp | 253 | ||||
| -rw-r--r-- | src/KM_sha1.h | 55 | ||||
| -rw-r--r-- | src/Makefile.am | 15 | ||||
| -rw-r--r-- | src/ST2052_TextParser.cpp | 4 | ||||
| -rwxr-xr-x | src/as-02-unwrap.cpp | 8 | ||||
| -rwxr-xr-x | src/as-02-wrap.cpp | 37 | ||||
| -rwxr-xr-x | src/asdcp-test.cpp | 45 | ||||
| -rwxr-xr-x | src/asdcp-unwrap.cpp | 12 | ||||
| -rwxr-xr-x | src/asdcp-util.cpp | 18 | ||||
| -rwxr-xr-x | src/asdcp-wrap.cpp | 35 | ||||
| -rwxr-xr-x | src/fips-186-rng-test.cpp | 1 | ||||
| -rwxr-xr-x | src/kmfilegen.cpp | 35 | ||||
| -rwxr-xr-x | src/phdr-unwrap.cpp | 2 | ||||
| -rwxr-xr-x | src/phdr-wrap.cpp | 7 |
19 files changed, 1014 insertions, 105 deletions
diff --git a/src/AS_02_ACES.cpp b/src/AS_02_ACES.cpp index 876af18..c8eeca3 100644 --- a/src/AS_02_ACES.cpp +++ b/src/AS_02_ACES.cpp @@ -28,12 +28,11 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <KM_sha1.h> #include "AS_02_ACES.h" -//#include "info.h" #include "AS_02_internal.h" #include <limits> #include <iostream> -#include <openssl/sha.h> #ifdef min #undef min @@ -256,7 +255,7 @@ AS_02::ACES::CreateTargetFrameAssetId(Kumu::UUID& rID, const std::string& target static Kumu::UUID AS_02::ACES::create_4122_type5_id(const byte_t* subject_name, Kumu::fsize_t size, const byte_t* ns_id) { - SHA_CTX ctx; + SHA1_CTX ctx; SHA1_Init(&ctx); SHA1_Update(&ctx, ns_id, NS_ID_LENGTH); SHA1_Update(&ctx, subject_name, size); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2787e46..e40f7b1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,10 +1,34 @@ -find_library(OpenSSLLib_PATH NAMES libeay32 crypto PATHS "${PROJECT_SOURCE_DIR}/../openssl" "${PROJECT_SOURCE_DIR}/../lib/openssl" "$ENV{CMAKE_HINT}/openssl" ENV CMAKE_HINT PATH_SUFFIXES "lib" "openssl" "lib/openssl")
-find_path(OpenSSLLib_include_DIR NAMES openssl/rand.h PATHS "${PROJECT_SOURCE_DIR}/../openssl" "${PROJECT_SOURCE_DIR}/../lib/openssl" "$ENV{CMAKE_HINT}/openssl" ENV CMAKE_HINT PATH_SUFFIXES "include" "inc32")
-find_library(XercescppLib_PATH NAMES xerces-c xerces-c_3 PATHS "${PROJECT_SOURCE_DIR}/../xercescpp" "${PROJECT_SOURCE_DIR}/../lib/xercescpp" "$ENV{CMAKE_HINT}/xercescpp" ENV CMAKE_HINT PATH_SUFFIXES "lib")
-find_library(XercescppLib_Debug_PATH NAMES xerces-cD xerces-c_3D xerces-c PATHS "${PROJECT_SOURCE_DIR}/../xercescpp" "${PROJECT_SOURCE_DIR}/../lib/xercescpp" "$ENV{CMAKE_HINT}/xercescpp" ENV CMAKE_HINT PATH_SUFFIXES "lib")
-find_path(XercescppLib_include_DIR NAMES xercesc/dom/DOM.hpp PATHS "${PROJECT_SOURCE_DIR}/../xercescpp" "${PROJECT_SOURCE_DIR}/../lib/xercescpp" "$ENV{CMAKE_HINT}/xercescpp" ENV CMAKE_HINT PATH_SUFFIXES "include")
+option(WITHOUT_SSL "Build without encryption support?" OFF)
+if (NOT WITHOUT_SSL)
+ find_library(OpenSSLLib_PATH NAMES libeay32 crypto PATHS "${PROJECT_SOURCE_DIR}/../openssl" "${PROJECT_SOURCE_DIR}/../lib/openssl" "$ENV{CMAKE_HINT}/openssl" ENV CMAKE_HINT PATH_SUFFIXES "lib" "openssl" "lib/openssl")
+ find_path(OpenSSLLib_include_DIR NAMES openssl/rand.h PATHS "${PROJECT_SOURCE_DIR}/../openssl" "${PROJECT_SOURCE_DIR}/../lib/openssl" "$ENV{CMAKE_HINT}/openssl" ENV CMAKE_HINT PATH_SUFFIXES "include" "inc32")
+endif (NOT WITHOUT_SSL)
+
+option(WITHOUT_XML "Build without XML support?" OFF)
+if (NOT WITHOUT_XML)
+ find_library(XercescppLib_PATH NAMES xerces-c xerces-c_3 PATHS "${PROJECT_SOURCE_DIR}/../xercescpp" "${PROJECT_SOURCE_DIR}/../lib/xercescpp" "$ENV{CMAKE_HINT}/xercescpp" ENV CMAKE_HINT PATH_SUFFIXES "lib")
+ find_library(XercescppLib_Debug_PATH NAMES xerces-c xerces-c_3D PATHS "${PROJECT_SOURCE_DIR}/../xercescpp" "${PROJECT_SOURCE_DIR}/../lib/xercescpp" "$ENV{CMAKE_HINT}/xercescpp" ENV CMAKE_HINT PATH_SUFFIXES "lib")
+ find_path(XercescppLib_include_DIR NAMES xercesc/dom/DOM.hpp PATHS "${PROJECT_SOURCE_DIR}/../xercescpp" "${PROJECT_SOURCE_DIR}/../lib/xercescpp" "$ENV{CMAKE_HINT}/xercescpp" ENV CMAKE_HINT PATH_SUFFIXES "include")
+endif (NOT WITHOUT_XML)
+
set(UseRandomUUID OFF CACHE BOOL "")
+if (OpenSSLLib_PATH AND OpenSSLLib_include_DIR)
+ set (HAVE_OPENSSL 1)
+ message(STATUS "Building with encryption support")
+ add_definitions(/DHAVE_OPENSSL=1)
+else()
+ message(STATUS "Building without encryption support")
+endif()
+
+if (XercescppLib_PATH AND XercescppLib_Debug_PATH AND XercescppLib_include_DIR)
+ set (HAVE_XERCES_C 1)
+ message(STATUS "Building with XML parse support")
+ add_definitions(/DHAVE_XERCES_C=1)
+else()
+ message(STATUS "Building without XML parse support")
+endif()
+
# This lib. doesn't export from dll with __declspec(dllexport). So this lib. must be built statically on Windows.
if(NOT WIN32)
set(BUILD_SHARED_LIBS true CACHE BOOL "Build shared or static libs?" FORCE)
@@ -12,20 +36,24 @@ endif(NOT WIN32) # ----------libkumu----------
# source
-set(kumu_src KM_fileio.cpp KM_log.cpp KM_prng.cpp KM_util.cpp KM_xml.cpp KM_tai.cpp)
+set(kumu_src KM_fileio.cpp KM_log.cpp KM_util.cpp KM_tai.cpp KM_prng.cpp KM_aes.cpp KM_xml.cpp KM_sha1.cpp)
# header
-set(kumu_src ${kumu_src} KM_fileio.h KM_log.h KM_prng.h KM_util.h KM_xml.h KM_tai.h KM_error.h KM_memio.h KM_mutex.h KM_platform.h dirent_win.h)
+set(kumu_src ${kumu_src} KM_fileio.h KM_log.h KM_prng.h KM_util.h KM_tai.h KM_error.h KM_memio.h KM_mutex.h KM_platform.h dirent_win.h KM_aes.h KM_xml.h KM_sha1.h)
# ----------libasdcp----------
# source
-set(asdcp_src MPEG2_Parser.cpp MPEG.cpp JP2K_Codestream_Parser.cpp JP2K_Sequence_Parser.cpp JP2K.cpp PCM_Parser.cpp Wav.cpp
- TimedText_Parser.cpp KLV.cpp Dict.cpp MXFTypes.cpp MXF.cpp Index.cpp Metadata.cpp AS_DCP.cpp AS_DCP_MXF.cpp AS_DCP_AES.cpp
+set(asdcp_src MPEG2_Parser.cpp MPEG.cpp JP2K_Codestream_Parser.cpp JP2K_Sequence_Parser.cpp JP2K.cpp PCM_Parser.cpp Wav.cpp
+ KLV.cpp Dict.cpp MXFTypes.cpp MXF.cpp Index.cpp Metadata.cpp AS_DCP.cpp AS_DCP_MXF.cpp TimedText_Parser.cpp
h__Reader.cpp h__Writer.cpp AS_DCP_MPEG2.cpp AS_DCP_JP2K.cpp AS_DCP_PCM.cpp AS_DCP_TimedText.cpp PCMParserList.cpp MDD.cpp
AS_DCP_ATMOS.cpp AS_DCP_DCData.cpp DCData_ByteStream_Parser.cpp DCData_Sequence_Parser.cpp AtmosSyncChannel_Generator.cpp
AtmosSyncChannel_Mixer.cpp PCMDataProviders.cpp SyncEncoder.c CRC16.c UUIDInformation.c
)
+if (HAVE_OPENSSL)
+ list(APPEND asdcp_src AS_DCP_AES.cpp)
+endif()
+
# header for deployment (install target)
set(asdcp_deploy_header AS_DCP.h PCMParserList.h AS_DCP_internal.h KM_error.h KM_fileio.h KM_util.h KM_memio.h KM_tai.h KM_platform.h KM_log.h KM_mutex.h dirent_win.h)
@@ -37,7 +65,7 @@ set(asdcp_src ${asdcp_src} Wav.h WavFileWriter.h MXF.h Metadata.h JP2K.h AS_DCP. # ----------as02----------
# source
-set(as02_src h__02_Reader.cpp h__02_Writer.cpp AS_02_ISXD.cpp AS_02_JP2K.cpp AS_02_PCM.cpp ST2052_TextParser.cpp AS_02_TimedText.cpp AS_02_ACES.cpp ACES_Codestream_Parser.cpp ACES_Sequence_Parser.cpp ACES.cpp AS_02_IAB.cpp)
+set(as02_src h__02_Reader.cpp h__02_Writer.cpp AS_02_ISXD.cpp AS_02_JP2K.cpp AS_02_PCM.cpp ST2052_TextParser.cpp AS_02_TimedText.cpp AS_02_ACES.cpp ACES_Codestream_Parser.cpp ACES_Sequence_Parser.cpp ACES.cpp AS_02_IAB.cpp ST2052_TextParser.cpp)
# header for deployment (install target)
set(as02_deploy_header AS_02.h Metadata.h MXF.h MXFTypes.h KLV.h MDD.h AS_02_ACES.h ACES.h AS_02_IAB.h AS_02_internal.h)
@@ -46,9 +74,18 @@ set(as02_deploy_header AS_02.h Metadata.h MXF.h MXFTypes.h KLV.h MDD.h AS_02_ACE set(as02_src ${as02_src} AS_02.h AS_02_internal.h AS_02_ACES.h ACES.h AS_02_IAB.h)
-include_directories("${PROJECT_SOURCE_DIR}/src" "${OpenSSLLib_include_DIR}" "${XercescppLib_include_DIR}")
+include_directories("${CMAKE_CURRENT_SOURCE_DIR}")
+include_directories("${CMAKE_CURRENT_BINARY_DIR}")
-add_definitions(/DPACKAGE_VERSION=\"${VERSION_STRING}\" /DHAVE_XERCES_C=1)
+if (HAVE_OPENSSL)
+ include_directories("${OpenSSLLib_include_DIR}")
+endif()
+if (WITH_XERCES)
+ include_directories("${XercescppLib_include_DIR}")
+ add_definitions(/DHAVE_XERCES_C=1)
+endif()
+
+add_definitions(/DPACKAGE_VERSION=\"${VERSION_STRING}\")
if(WIN32)
add_definitions(/DKM_WIN32 /D_CONSOLE /DASDCP_PLATFORM=\"win32\" /D_CRT_SECURE_NO_WARNINGS /D_CRT_NONSTDC_NO_WARNINGS)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO")
@@ -63,7 +100,15 @@ endif(UseRandomUUID) set(CMAKE_DEBUG_POSTFIX _d) # Append "_d" if debug lib.
add_library(libkumu ${kumu_src})
-target_link_libraries(libkumu general "${OpenSSLLib_PATH}" debug "${XercescppLib_Debug_PATH}" optimized "${XercescppLib_PATH}")
+
+if (HAVE_OPENSSL)
+ target_link_libraries(libkumu general "${OpenSSLLib_PATH}")
+endif()
+
+if (HAVE_XERCES_C)
+ target_link_libraries(libkumu debug "${XercescppLib_Debug_PATH}" optimized "${XercescppLib_PATH}")
+endif()
+
set_target_properties(libkumu PROPERTIES PREFIX "" VERSION ${VERSION_STRING} SOVERSION ${VERSION_MAJOR})
add_library(libasdcp ${asdcp_src})
@@ -89,19 +134,19 @@ endif(WIN32) add_executable(kmuuidgen "kmuuidgen.cpp")
target_link_libraries(kmuuidgen general libkumu)
if(WIN32)
- target_link_libraries(kmuuidgen general Advapi32.lib)
+ target_link_libraries(kmuuidgen general Advapi32.lib)
endif(WIN32)
add_executable(kmrandgen "kmrandgen.cpp")
target_link_libraries(kmrandgen general libkumu)
if(WIN32)
- target_link_libraries(kmrandgen general Advapi32.lib)
+ target_link_libraries(kmrandgen general Advapi32.lib)
endif(WIN32)
add_executable(kmfilegen "kmfilegen.cpp")
target_link_libraries(kmfilegen general libkumu)
if(WIN32)
- target_link_libraries(kmfilegen general Advapi32.lib)
+ target_link_libraries(kmfilegen general Advapi32.lib)
endif(WIN32)
add_executable(klvwalk "klvwalk.cpp")
@@ -166,6 +211,9 @@ endif(WIN32) # add the install target
install(TARGETS libkumu libasdcp libas02 EXPORT asdcplibtargets RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib INCLUDES DESTINATION "${OpenSSLLib_include_DIR}" "${XercescppLib_include_DIR}")
-install(TARGETS blackwave wavesplit kmuuidgen kmrandgen kmfilegen klvwalk asdcp-test asdcp-wrap asdcp-unwrap asdcp-info asdcp-util j2c-test as-02-wrap as-02-unwrap as-02-info RUNTIME DESTINATION bin)
+
+set(install_targets blackwave wavesplit klvwalk asdcp-test asdcp-wrap asdcp-unwrap asdcp-info asdcp-util j2c-test as-02-wrap as-02-unwrap as-02-info kmfilegen kmuuidgen kmrandgen)
+
+install(TARGETS ${install_targets} RUNTIME DESTINATION bin)
install(FILES ${as02_deploy_header} ${asdcp_deploy_header} DESTINATION include)
install(EXPORT asdcplibtargets DESTINATION targets)
diff --git a/src/KM_aes.cpp b/src/KM_aes.cpp new file mode 100644 index 0000000..53b3913 --- /dev/null +++ b/src/KM_aes.cpp @@ -0,0 +1,416 @@ +/* +public domain code distributed with asdcplib + +copied from https://github.com/kokke/tiny-AES-c at 2020-07-15T23:38:12+00:00 + +ORIGINAL NOTICE: +"All material in this repository is in the public domain." + +Modified aggressively to remove unused features. +*/ + +/*****************************************************************************/ +/* Includes: */ +/*****************************************************************************/ +#include <string.h> // CBC mode, for memset +#include "KM_aes.h" +using namespace Kumu; + +/*****************************************************************************/ +/* Defines: */ +/*****************************************************************************/ +// The number of columns comprising a state in AES. This is a constant in AES. Value=4 +#define Nb 4 +#define Nk 4 // The number of 32 bit words in a key. +#define Nr 10 // The number of rounds in AES Cipher. + +/*****************************************************************************/ +/* Private variables: */ +/*****************************************************************************/ +// state - array holding the intermediate results during decryption. +typedef ui8_t state_t[4][4]; + +// The lookup-tables are marked const so they can be placed in read-only storage instead of RAM +// The numbers below can be computed dynamically trading ROM for RAM - +// This can be useful in (embedded) bootloader applications, where ROM is often limited. +static const ui8_t sbox[256] = { + //0 1 2 3 4 5 6 7 8 9 A B C D E F + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; + +static const ui8_t rsbox[256] = { + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, + 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, + 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, + 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, + 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, + 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, + 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, + 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, + 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, + 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d }; + +// The round constant word array, Rcon[i], contains the values given by +// x to the power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8) +static const ui8_t Rcon[11] = { + 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 }; + +/* + * Jordan Goulder points out in PR #12 (https://github.com/kokke/tiny-AES-C/pull/12), + * that you can remove most of the elements in the Rcon array, because they are unused. + * + * From Wikipedia's article on the Rijndael key schedule @ https://en.wikipedia.org/wiki/Rijndael_key_schedule#Rcon + * + * "Only the first some of these constants are actually used – up to rcon[10] for AES-128 (as 11 round keys are needed), + * up to rcon[8] for AES-192, up to rcon[7] for AES-256. rcon[0] is not used in AES algorithm." + */ + + +/*****************************************************************************/ +/* Private functions: */ +/*****************************************************************************/ +/* +static ui8_t getSBoxValue(ui8_t num) +{ + return sbox[num]; +} +*/ +#define getSBoxValue(num) (sbox[(num)]) +/* +static ui8_t getSBoxInvert(ui8_t num) +{ + return rsbox[num]; +} +*/ +#define getSBoxInvert(num) (rsbox[(num)]) + +// This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states. +static void +KeyExpansion(ui8_t* RoundKey, const ui8_t* Key) +{ + unsigned i, j, k; + ui8_t tempa[4]; // Used for the column/row operations + + // The first round key is the key itself. + for (i = 0; i < Nk; ++i) + { + RoundKey[(i * 4) + 0] = Key[(i * 4) + 0]; + RoundKey[(i * 4) + 1] = Key[(i * 4) + 1]; + RoundKey[(i * 4) + 2] = Key[(i * 4) + 2]; + RoundKey[(i * 4) + 3] = Key[(i * 4) + 3]; + } + + // All other round keys are found from the previous round keys. + for (i = Nk; i < Nb * (Nr + 1); ++i) + { + { + k = (i - 1) * 4; + tempa[0]=RoundKey[k + 0]; + tempa[1]=RoundKey[k + 1]; + tempa[2]=RoundKey[k + 2]; + tempa[3]=RoundKey[k + 3]; + + } + + if (i % Nk == 0) + { + // This function shifts the 4 bytes in a word to the left once. + // [a0,a1,a2,a3] becomes [a1,a2,a3,a0] + + // Function RotWord() + { + const ui8_t u8tmp = tempa[0]; + tempa[0] = tempa[1]; + tempa[1] = tempa[2]; + tempa[2] = tempa[3]; + tempa[3] = u8tmp; + } + + // SubWord() is a function that takes a four-byte input word and + // applies the S-box to each of the four bytes to produce an output word. + + // Function Subword() + { + tempa[0] = getSBoxValue(tempa[0]); + tempa[1] = getSBoxValue(tempa[1]); + tempa[2] = getSBoxValue(tempa[2]); + tempa[3] = getSBoxValue(tempa[3]); + } + + tempa[0] = tempa[0] ^ Rcon[i/Nk]; + } + + j = i * 4; k=(i - Nk) * 4; + RoundKey[j + 0] = RoundKey[k + 0] ^ tempa[0]; + RoundKey[j + 1] = RoundKey[k + 1] ^ tempa[1]; + RoundKey[j + 2] = RoundKey[k + 2] ^ tempa[2]; + RoundKey[j + 3] = RoundKey[k + 3] ^ tempa[3]; + } +} + +// +void +Kumu::AES_init_ctx(struct AES_ctx* ctx, const ui8_t* key) +{ + KeyExpansion(ctx->RoundKey, key); +} + +// This function adds the round key to state. +// The round key is added to the state by an XOR function. +static void +AddRoundKey(ui8_t round, state_t* state, const ui8_t* RoundKey) +{ + ui8_t i,j; + for (i = 0; i < 4; ++i) + { + for (j = 0; j < 4; ++j) + { + (*state)[i][j] ^= RoundKey[(round * Nb * 4) + (i * Nb) + j]; + } + } +} + +// The SubBytes Function Substitutes the values in the +// state matrix with values in an S-box. +static void +SubBytes(state_t* state) +{ + ui8_t i, j; + for (i = 0; i < 4; ++i) + { + for (j = 0; j < 4; ++j) + { + (*state)[j][i] = getSBoxValue((*state)[j][i]); + } + } +} + +// The ShiftRows() function shifts the rows in the state to the left. +// Each row is shifted with different offset. +// Offset = Row number. So the first row is not shifted. +static void +ShiftRows(state_t* state) +{ + ui8_t temp; + + // Rotate first row 1 columns to left + temp = (*state)[0][1]; + (*state)[0][1] = (*state)[1][1]; + (*state)[1][1] = (*state)[2][1]; + (*state)[2][1] = (*state)[3][1]; + (*state)[3][1] = temp; + + // Rotate second row 2 columns to left + temp = (*state)[0][2]; + (*state)[0][2] = (*state)[2][2]; + (*state)[2][2] = temp; + + temp = (*state)[1][2]; + (*state)[1][2] = (*state)[3][2]; + (*state)[3][2] = temp; + + // Rotate third row 3 columns to left + temp = (*state)[0][3]; + (*state)[0][3] = (*state)[3][3]; + (*state)[3][3] = (*state)[2][3]; + (*state)[2][3] = (*state)[1][3]; + (*state)[1][3] = temp; +} + +static ui8_t +xtime(ui8_t x) +{ + return ((x<<1) ^ (((x>>7) & 1) * 0x1b)); +} + +// MixColumns function mixes the columns of the state matrix +static void +MixColumns(state_t* state) +{ + ui8_t i; + ui8_t Tmp, Tm, t; + for (i = 0; i < 4; ++i) + { + t = (*state)[i][0]; + Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3] ; + Tm = (*state)[i][0] ^ (*state)[i][1] ; Tm = xtime(Tm); (*state)[i][0] ^= Tm ^ Tmp ; + Tm = (*state)[i][1] ^ (*state)[i][2] ; Tm = xtime(Tm); (*state)[i][1] ^= Tm ^ Tmp ; + Tm = (*state)[i][2] ^ (*state)[i][3] ; Tm = xtime(Tm); (*state)[i][2] ^= Tm ^ Tmp ; + Tm = (*state)[i][3] ^ t ; Tm = xtime(Tm); (*state)[i][3] ^= Tm ^ Tmp ; + } +} + +// Multiply is used to multiply numbers in the field GF(2^8) +// Note: The last call to xtime() is unneeded, but often ends up generating a smaller binary +// The compiler seems to be able to vectorize the operation better this way. +// See https://github.com/kokke/tiny-AES-c/pull/34 +#define Multiply(x, y) \ + ( ((y & 1) * x) ^ \ + ((y>>1 & 1) * xtime(x)) ^ \ + ((y>>2 & 1) * xtime(xtime(x))) ^ \ + ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ \ + ((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))) \ + +// MixColumns function mixes the columns of the state matrix. +// The method used to multiply may be difficult to understand for the inexperienced. +// Please use the references to gain more information. +static void +InvMixColumns(state_t* state) +{ + int i; + ui8_t a, b, c, d; + for (i = 0; i < 4; ++i) + { + a = (*state)[i][0]; + b = (*state)[i][1]; + c = (*state)[i][2]; + d = (*state)[i][3]; + + (*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09); + (*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d); + (*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b); + (*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e); + } +} + + +// The SubBytes Function Substitutes the values in the +// state matrix with values in an S-box. +static void +InvSubBytes(state_t* state) +{ + ui8_t i, j; + for (i = 0; i < 4; ++i) + { + for (j = 0; j < 4; ++j) + { + (*state)[j][i] = getSBoxInvert((*state)[j][i]); + } + } +} + +static void +InvShiftRows(state_t* state) +{ + ui8_t temp; + + // Rotate first row 1 columns to right + temp = (*state)[3][1]; + (*state)[3][1] = (*state)[2][1]; + (*state)[2][1] = (*state)[1][1]; + (*state)[1][1] = (*state)[0][1]; + (*state)[0][1] = temp; + + // Rotate second row 2 columns to right + temp = (*state)[0][2]; + (*state)[0][2] = (*state)[2][2]; + (*state)[2][2] = temp; + + temp = (*state)[1][2]; + (*state)[1][2] = (*state)[3][2]; + (*state)[3][2] = temp; + + // Rotate third row 3 columns to right + temp = (*state)[0][3]; + (*state)[0][3] = (*state)[1][3]; + (*state)[1][3] = (*state)[2][3]; + (*state)[2][3] = (*state)[3][3]; + (*state)[3][3] = temp; +} + + +// Cipher is the main function that encrypts the PlainText. +static void +Cipher(state_t* state, const ui8_t* RoundKey) +{ + ui8_t round = 0; + + // Add the First round key to the state before starting the rounds. + AddRoundKey(0, state, RoundKey); + + // There will be Nr rounds. + // The first Nr-1 rounds are identical. + // These Nr rounds are executed in the loop below. + // Last one without MixColumns() + for (round = 1; ; ++round) + { + SubBytes(state); + ShiftRows(state); + if (round == Nr) { + break; + } + MixColumns(state); + AddRoundKey(round, state, RoundKey); + } + // Add round key to last round + AddRoundKey(Nr, state, RoundKey); +} + +static void +InvCipher(state_t* state, const ui8_t* RoundKey) +{ + ui8_t round = 0; + + // Add the First round key to the state before starting the rounds. + AddRoundKey(Nr, state, RoundKey); + + // There will be Nr rounds. + // The first Nr-1 rounds are identical. + // These Nr rounds are executed in the loop below. + // Last one without InvMixColumn() + for (round = (Nr - 1); ; --round) + { + InvShiftRows(state); + InvSubBytes(state); + AddRoundKey(round, state, RoundKey); + if (round == 0) { + break; + } + InvMixColumns(state); + } + +} + + +/*****************************************************************************/ +/* Public functions: */ +/*****************************************************************************/ + +void +Kumu::AES_encrypt(const struct Kumu::AES_ctx* ctx, ui8_t* buf) +{ + // The next function call encrypts the PlainText with the Key using AES algorithm. + Cipher((state_t*)buf, ctx->RoundKey); +} + +void +Kumu::AES_decrypt(const struct Kumu::AES_ctx* ctx, ui8_t* buf) +{ + // The next function call decrypts the PlainText with the Key using AES algorithm. + InvCipher((state_t*)buf, ctx->RoundKey); +} + + +// +// end KM_aes.cpp +// diff --git a/src/KM_aes.h b/src/KM_aes.h new file mode 100644 index 0000000..0f958cc --- /dev/null +++ b/src/KM_aes.h @@ -0,0 +1,57 @@ +/* +Copyright (c) 2020, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + /*! \file KM_aes.h + \version $Id$ + \brief AES (Rijndael) encryption + */ + +#ifndef _KM_AES_H_ +#define _KM_AES_H_ + +#include <KM_platform.h> + +#define AES_BLOCKLEN 16 // Block length in bytes - AES is 128b block only +#define AES_KEYLEN 16 // Key length in bytes +#define AES_keyExpSize 176 + +namespace Kumu { + struct AES_ctx + { + ui8_t RoundKey[AES_keyExpSize]; + }; + + void AES_init_ctx(struct AES_ctx* ctx, const ui8_t* key); + void AES_encrypt(const struct AES_ctx* ctx, ui8_t* buf); + void AES_decrypt(const struct AES_ctx* ctx, ui8_t* buf); + +}; // end namespace + +#endif // _KM_AES_H_ + +// +// end KM_aes.h +// diff --git a/src/KM_prng.cpp b/src/KM_prng.cpp index d11a330..f40d846 100755 --- a/src/KM_prng.cpp +++ b/src/KM_prng.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2006-2009, John Hurst +Copyright (c) 2006-2021, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -31,12 +31,17 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <KM_prng.h> #include <KM_log.h> +#include <KM_aes.h> +#include <KM_sha1.h> #include <KM_mutex.h> #include <string.h> #include <assert.h> -#include <openssl/aes.h> -#include <openssl/sha.h> -#include <openssl/bn.h> + +#ifdef HAVE_OPENSSL +# define ENABLE_FIPS_186 +# include <openssl/sha.h> +# include <openssl/bn.h> +#endif // HAVE_OPENSSL using namespace Kumu; @@ -51,7 +56,7 @@ const char* DEV_URANDOM = "/dev/urandom"; const ui32_t RNG_KEY_SIZE = 512UL; const ui32_t RNG_KEY_SIZE_BITS = 256UL; -const ui32_t RNG_BLOCK_SIZE = 16UL; +const ui32_t RNG_BLOCK_SIZE = AES_BLOCKLEN; const ui32_t MAX_SEQUENCE_LEN = 0x00040000UL; @@ -61,7 +66,7 @@ class h__RNG KM_NO_COPY_CONSTRUCT(h__RNG); public: - AES_KEY m_Context; + AES_ctx m_Context; byte_t m_ctr_buf[RNG_BLOCK_SIZE]; Mutex m_Lock; @@ -105,7 +110,7 @@ public: { assert(key_fodder); byte_t sha_buf[20]; - SHA_CTX SHA; + SHA1_CTX SHA; SHA1_Init(&SHA); SHA1_Update(&SHA, (byte_t*)&m_Context, sizeof(m_Context)); @@ -113,7 +118,7 @@ public: SHA1_Final(sha_buf, &SHA); AutoMutex Lock(m_Lock); - AES_set_encrypt_key(sha_buf, RNG_KEY_SIZE_BITS, &m_Context); + AES_init_ctx(&m_Context, sha_buf); *(ui32_t*)(m_ctr_buf + 12) = 1; } @@ -127,7 +132,8 @@ public: while ( gen_count + RNG_BLOCK_SIZE <= len ) { - AES_encrypt(m_ctr_buf, buf + gen_count, &m_Context); + memcpy(buf + gen_count, m_ctr_buf, RNG_BLOCK_SIZE); + AES_encrypt(&m_Context, buf + gen_count); *(ui32_t*)(m_ctr_buf + 12) += 1; gen_count += RNG_BLOCK_SIZE; } @@ -135,7 +141,8 @@ public: if ( len != gen_count ) // partial count needed? { byte_t tmp[RNG_BLOCK_SIZE]; - AES_encrypt(m_ctr_buf, tmp, &m_Context); + memcpy(tmp, m_ctr_buf, RNG_BLOCK_SIZE); + AES_encrypt(&m_Context, tmp); memcpy(buf + gen_count, tmp, len - gen_count); } } @@ -192,8 +199,11 @@ Kumu::FortunaRNG::FillRandom(Kumu::ByteString& Buffer) return Buffer.Data(); } + //------------------------------------------------------------------------------------------ +#ifdef ENABLE_FIPS_186 + // // FIPS 186-2 Sec. 3.1 as modified by Change 1, section entitled "General Purpose Random Number Generation" void @@ -278,6 +288,8 @@ Kumu::Gen_FIPS_186_Value(const byte_t* key, ui32_t key_size, byte_t* out_buf, ui BN_CTX_free(ctx1); } +#endif // ENABLE_FIPS_186 + // // end KM_prng.cpp // diff --git a/src/KM_sha1.cpp b/src/KM_sha1.cpp new file mode 100644 index 0000000..2b7fdb9 --- /dev/null +++ b/src/KM_sha1.cpp @@ -0,0 +1,253 @@ +/* +public domain code distributed with asdcplib + +SHA-1 in C +By Steve Reid <email redacted> +100% Public Domain + +Test Vectors (from FIPS PUB 180-1) +"abc" + A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D +"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 +A million repetitions of "a" + 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F +*/ + +#include <KM_sha1.h> +#include <string.h> + +using namespace Kumu; + +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +/* blk0() and blk() perform the initial expand. */ +/* I got the idea of expanding during the round function from SSLeay */ +#ifndef KM_BIG_ENDIAN +#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ + |(rol(block->l[i],8)&0x00FF00FF)) +#else +#define blk0(i) block->l[i] +#endif +#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ + ^block->l[(i+2)&15]^block->l[i&15],1)) + +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ +#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); +#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); +#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); + + +/* Hash a single 512-bit block. This is the core of the algorithm. */ + +static void +SHA1Transform( + ui32_t state[5], + const byte_t buffer[64]) +{ + typedef union + { + byte_t c[64]; + ui32_t l[16]; + ui64_t q[8]; + } CHAR64LONG16; + + ui32_t a, b, c, d, e; + size_t i; + CHAR64LONG16 block[1]; /* use array to appear as a pointer */ + + block[0].q[0] = reinterpret_cast<const CHAR64LONG16*>(buffer)->q[0]; + block[0].q[1] = reinterpret_cast<const CHAR64LONG16*>(buffer)->q[1]; + block[0].q[2] = reinterpret_cast<const CHAR64LONG16*>(buffer)->q[2]; + block[0].q[3] = reinterpret_cast<const CHAR64LONG16*>(buffer)->q[3]; + block[0].q[4] = reinterpret_cast<const CHAR64LONG16*>(buffer)->q[4]; + block[0].q[5] = reinterpret_cast<const CHAR64LONG16*>(buffer)->q[5]; + block[0].q[6] = reinterpret_cast<const CHAR64LONG16*>(buffer)->q[6]; + block[0].q[7] = reinterpret_cast<const CHAR64LONG16*>(buffer)->q[7]; + + /* Copy context->state[] to working vars */ + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + /* 4 rounds of 20 operations each. Loop unrolled. */ + R0(a, b, c, d, e, 0); + R0(e, a, b, c, d, 1); + R0(d, e, a, b, c, 2); + R0(c, d, e, a, b, 3); + R0(b, c, d, e, a, 4); + R0(a, b, c, d, e, 5); + R0(e, a, b, c, d, 6); + R0(d, e, a, b, c, 7); + R0(c, d, e, a, b, 8); + R0(b, c, d, e, a, 9); + R0(a, b, c, d, e, 10); + R0(e, a, b, c, d, 11); + R0(d, e, a, b, c, 12); + R0(c, d, e, a, b, 13); + R0(b, c, d, e, a, 14); + R0(a, b, c, d, e, 15); + R1(e, a, b, c, d, 16); + R1(d, e, a, b, c, 17); + R1(c, d, e, a, b, 18); + R1(b, c, d, e, a, 19); + R2(a, b, c, d, e, 20); + R2(e, a, b, c, d, 21); + R2(d, e, a, b, c, 22); + R2(c, d, e, a, b, 23); + R2(b, c, d, e, a, 24); + R2(a, b, c, d, e, 25); + R2(e, a, b, c, d, 26); + R2(d, e, a, b, c, 27); + R2(c, d, e, a, b, 28); + R2(b, c, d, e, a, 29); + R2(a, b, c, d, e, 30); + R2(e, a, b, c, d, 31); + R2(d, e, a, b, c, 32); + R2(c, d, e, a, b, 33); + R2(b, c, d, e, a, 34); + R2(a, b, c, d, e, 35); + R2(e, a, b, c, d, 36); + R2(d, e, a, b, c, 37); + R2(c, d, e, a, b, 38); + R2(b, c, d, e, a, 39); + R3(a, b, c, d, e, 40); + R3(e, a, b, c, d, 41); + R3(d, e, a, b, c, 42); + R3(c, d, e, a, b, 43); + R3(b, c, d, e, a, 44); + R3(a, b, c, d, e, 45); + R3(e, a, b, c, d, 46); + R3(d, e, a, b, c, 47); + R3(c, d, e, a, b, 48); + R3(b, c, d, e, a, 49); + R3(a, b, c, d, e, 50); + R3(e, a, b, c, d, 51); + R3(d, e, a, b, c, 52); + R3(c, d, e, a, b, 53); + R3(b, c, d, e, a, 54); + R3(a, b, c, d, e, 55); + R3(e, a, b, c, d, 56); + R3(d, e, a, b, c, 57); + R3(c, d, e, a, b, 58); + R3(b, c, d, e, a, 59); + R4(a, b, c, d, e, 60); + R4(e, a, b, c, d, 61); + R4(d, e, a, b, c, 62); + R4(c, d, e, a, b, 63); + R4(b, c, d, e, a, 64); + R4(a, b, c, d, e, 65); + R4(e, a, b, c, d, 66); + R4(d, e, a, b, c, 67); + R4(c, d, e, a, b, 68); + R4(b, c, d, e, a, 69); + R4(a, b, c, d, e, 70); + R4(e, a, b, c, d, 71); + R4(d, e, a, b, c, 72); + R4(c, d, e, a, b, 73); + R4(b, c, d, e, a, 74); + R4(a, b, c, d, e, 75); + R4(e, a, b, c, d, 76); + R4(d, e, a, b, c, 77); + R4(c, d, e, a, b, 78); + R4(b, c, d, e, a, 79); + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + /* Wipe variables */ + a = b = c = d = e = 0; + // memset(buffer, 0, 64); +} + + +/* SHA1Init - Initialize new context */ + +void +Kumu::SHA1_Init( + SHA1_CTX * context +) +{ + /* SHA1 initialization constants */ + context->state[0] = 0x67452301; + context->state[1] = 0xEFCDAB89; + context->state[2] = 0x98BADCFE; + context->state[3] = 0x10325476; + context->state[4] = 0xC3D2E1F0; + context->count[0] = context->count[1] = 0; +} + + +/* Run your data through this. */ + +void +Kumu::SHA1_Update( + SHA1_CTX * context, + const byte_t *data, + ui32_t len +) +{ + ui32_t i, j; + + j = context->count[0]; + if ((context->count[0] += len << 3) < j) + context->count[1]++; + context->count[1] += (len >> 29); + j = (j >> 3) & 63; + if ((j + len) > 63) + { + memcpy(&context->buffer[j], data, (i = 64 - j)); + SHA1Transform(context->state, context->buffer); + for (; i + 63 < len; i += 64) + { + SHA1Transform(context->state, &data[i]); + } + j = 0; + } + else + { + i = 0; + } + + memcpy(&context->buffer[j], &data[i], len - i); +} + + +/* Add padding and return the message digest. */ + +void +Kumu::SHA1_Final( + byte_t digest[20], + SHA1_CTX * context) +{ + size_t i; + byte_t finalcount[8]; + byte_t c; + + for (i = 0; i < 8; i++) + { + finalcount[i] = (byte_t) ((context->count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8)) & 255); /* Endian independent */ + } + + c = 0200; + SHA1_Update(context, &c, 1); + while ((context->count[0] & 504) != 448) + { + c = 0000; + SHA1_Update(context, &c, 1); + } + SHA1_Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ + for (i = 0; i < 20; i++) + { + digest[i] = (byte_t)((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255); + } +} + +// +// KM_sha1.cpp +// diff --git a/src/KM_sha1.h b/src/KM_sha1.h new file mode 100644 index 0000000..ea232e2 --- /dev/null +++ b/src/KM_sha1.h @@ -0,0 +1,55 @@ +/* +Copyright (c) 2020, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + /*! \file KM_sha1.h + \version $Id$ + \brief SHA-1 message digest + */ + +#ifndef _KM_SHA1_H_ +#define _KM_SHA1_H_ + +#include <KM_platform.h> + +namespace Kumu { + int const SHA1_DIGEST_LENGTH = 20; + + typedef struct { + ui32_t state[5]; + ui32_t count[2]; + byte_t buffer[64]; + } SHA1_CTX; + + void SHA1_Init(SHA1_CTX* context); + void SHA1_Update(SHA1_CTX* context, const byte_t* data, unsigned int len); + void SHA1_Final(byte_t digest[20], SHA1_CTX* context); +} + +#endif // _KM_SHA1_H_ + +// +// end KM_sha1.h +// diff --git a/src/Makefile.am b/src/Makefile.am index 7768b39..dc1cf86 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -50,6 +50,8 @@ include_HEADERS = \ KM_mutex.h \ KM_platform.h \ KM_prng.h \ + KM_sha1.h \ + KM_aes.h \ KM_util.h \ KM_tai.h \ KM_xml.h \ @@ -102,7 +104,8 @@ endif # sources for kumu library libkumu_la_SOURCES = KM_error.h KM_fileio.cpp KM_fileio.h KM_log.cpp KM_log.h \ KM_memio.h KM_mutex.h KM_platform.h KM_prng.cpp KM_prng.h KM_util.cpp \ - KM_util.h KM_xml.cpp KM_xml.h KM_tai.h KM_tai.cpp + KM_util.h KM_tai.h KM_tai.cpp KM_xml.cpp KM_xml.h \ + KM_sha1.cpp KM_sha1.h KM_aes.h KM_aes.cpp # linker flags (*not* including libraries to link against) for a library libkumu_la_LDFLAGS = -release @VERSION@ @@ -111,11 +114,12 @@ libkumu_la_LDFLAGS = -release @VERSION@ # sources for asdcp library that don't get added to a distribution nodist_libasdcp_la_SOURCES = Metadata_h.tt2 Metadata_cpp.tt2 \ mxfgen.pl MXF_def.pl ullist.pl ULList.xml dict.xml DMS_Crypto.xml + # sources for asdcp library libasdcp_la_SOURCES = MPEG2_Parser.cpp MPEG.cpp JP2K_Codestream_Parser.cpp \ JP2K_Sequence_Parser.cpp JP2K.cpp PCM_Parser.cpp Wav.cpp \ TimedText_Parser.cpp KLV.cpp Dict.cpp MXFTypes.cpp MXF.cpp \ - Index.cpp Metadata.cpp AS_DCP.cpp AS_DCP_MXF.cpp AS_DCP_AES.cpp \ + Index.cpp Metadata.cpp AS_DCP.cpp AS_DCP_MXF.cpp \ h__Reader.cpp h__Writer.cpp AS_DCP_MPEG2.cpp AS_DCP_JP2K.cpp \ AS_DCP_PCM.cpp AS_DCP_TimedText.cpp PCMParserList.cpp \ Wav.h WavFileWriter.h MXF.h Metadata.h \ @@ -130,6 +134,9 @@ libasdcp_la_SOURCES = MPEG2_Parser.cpp MPEG.cpp JP2K_Codestream_Parser.cpp \ UUIDInformation.c UUIDInformation.h \ ST2095_PinkNoise.cpp +if HAVE_OPENSSL +libasdcp_la_SOURCES += AS_DCP_AES.cpp +endif libasdcp_la_LDFLAGS = -release @VERSION@ # additional libraries to link against for a library @@ -143,7 +150,7 @@ libas02_la_SOURCES = \ AS_02_internal.h \ ACES.h \ AS_02_ACES.h \ - AS_02_IAB.h \ + AS_02_IAB.h \ h__02_Reader.cpp \ h__02_Writer.cpp \ AS_02_JP2K.cpp \ @@ -152,7 +159,7 @@ libas02_la_SOURCES = \ ST2052_TextParser.cpp \ AS_02_TimedText.cpp \ ACES.cpp \ - AS_02_IAB.cpp \ + AS_02_IAB.cpp \ ACES_Codestream_Parser.cpp \ ACES_Sequence_Parser.cpp \ AS_02_ACES.cpp diff --git a/src/ST2052_TextParser.cpp b/src/ST2052_TextParser.cpp index 305f46f..75c0e86 100644 --- a/src/ST2052_TextParser.cpp +++ b/src/ST2052_TextParser.cpp @@ -31,7 +31,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "AS_02_internal.h" #include "KM_xml.h" -#include <openssl/sha.h> +#include "KM_sha1.h" using namespace Kumu; using namespace ASDCP; @@ -66,7 +66,7 @@ static byte_t s_font_id_prefix[NS_ID_LENGTH] = { static Kumu::UUID create_4122_type5_id(const std::string& subject_name, const byte_t* ns_id) { - SHA_CTX ctx; + SHA1_CTX ctx; SHA1_Init(&ctx); SHA1_Update(&ctx, ns_id, NS_ID_LENGTH); SHA1_Update(&ctx, (byte_t*)subject_name.c_str(), subject_name.size()); diff --git a/src/as-02-unwrap.cpp b/src/as-02-unwrap.cpp index 8625012..64a399a 100755 --- a/src/as-02-unwrap.cpp +++ b/src/as-02-unwrap.cpp @@ -360,6 +360,7 @@ read_JP2K_file(CommandOptions& Options) } } +#ifdef HAVE_OPENSSL if ( ASDCP_SUCCESS(result) && Options.key_flag ) { Context = new AESDecContext; @@ -381,6 +382,7 @@ read_JP2K_file(CommandOptions& Options) } } } +#endif // HAVE_OPENSSL ui32_t last_frame = Options.start_frame + ( Options.duration ? Options.duration : frame_count); if ( last_frame > frame_count ) @@ -485,6 +487,7 @@ read_ACES_file(CommandOptions& Options) } } +#ifdef HAVE_OPENSSL if (ASDCP_SUCCESS(result) && Options.key_flag) { Context = new AESDecContext; @@ -506,6 +509,7 @@ read_ACES_file(CommandOptions& Options) } } } +#endif ui32_t last_frame = Options.start_frame + (Options.duration ? Options.duration : frame_count); if (last_frame > frame_count) @@ -736,6 +740,7 @@ read_PCM_file(CommandOptions& Options) } } +#ifdef HAVE_OPENSSL if ( ASDCP_SUCCESS(result) && Options.key_flag ) { Context = new AESDecContext; @@ -757,6 +762,7 @@ read_PCM_file(CommandOptions& Options) } } } +#endif // HAVE_OPENSSL for ( ui32_t i = Options.start_frame; ASDCP_SUCCESS(result) && i < last_frame; i++ ) { @@ -898,6 +904,7 @@ read_isxd_file(CommandOptions& Options) } } +#ifdef HAVE_OPENSSL if ( ASDCP_SUCCESS(result) && Options.key_flag ) { Context = new AESDecContext; @@ -919,6 +926,7 @@ read_isxd_file(CommandOptions& Options) } } } +#endif // HAVE_OPENSSL ui32_t last_frame = Options.start_frame + ( Options.duration ? Options.duration : frame_count); if ( last_frame > frame_count ) diff --git a/src/as-02-wrap.cpp b/src/as-02-wrap.cpp index db76e19..713bcdb 100755 --- a/src/as-02-wrap.cpp +++ b/src/as-02-wrap.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2011-2018, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, +Copyright (c) 2011-2020, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst, Wolfgang Ruppel All rights reserved. @@ -35,10 +35,9 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. For more information about AS-02, please refer to the header file AS_02.h For more information about asdcplib, please refer to the header file AS_DCP.h */ - #include <KM_fileio.h> -#include <KM_prng.h> #include <KM_xml.h> +#include <KM_prng.h> #include <AS_02.h> #include "AS_02_ACES.h" #include <PCMParserList.h> @@ -987,8 +986,6 @@ write_JP2K_file(CommandOptions& Options) AS_02::JP2K::MXFWriter Writer; JP2K::FrameBuffer FrameBuffer(Options.fb_size); JP2K::SequenceParser Parser; - byte_t IV_buf[CBC_BLOCK_SIZE]; - Kumu::FortunaRNG RNG; ASDCP::MXF::FileDescriptor *essence_descriptor = 0; ASDCP::MXF::InterchangeObject_list_t essence_sub_descriptors; @@ -1098,9 +1095,12 @@ write_JP2K_file(CommandOptions& Options) else Kumu::GenRandomUUID(Info.AssetUUID); +#ifdef HAVE_OPENSSL // configure encryption if( Options.key_flag ) { + byte_t IV_buf[CBC_BLOCK_SIZE]; + Kumu::FortunaRNG RNG; Kumu::GenRandomUUID(Info.ContextID); Info.EncryptedEssence = true; @@ -1126,6 +1126,7 @@ write_JP2K_file(CommandOptions& Options) result = HMAC->InitKey(Options.key_value, Info.LabelSetType); } } +#endif // HAVE_OPENSSL if ( ASDCP_SUCCESS(result) ) { @@ -1191,8 +1192,6 @@ write_ACES_file(CommandOptions& Options) AS_02::ACES::MXFWriter Writer; AS_02::ACES::FrameBuffer FrameBuffer(Options.fb_size); AS_02::ACES::SequenceParser Parser; - byte_t IV_buf[CBC_BLOCK_SIZE]; - Kumu::FortunaRNG RNG; ASDCP::MXF::FileDescriptor *essence_descriptor = 0; ASDCP::MXF::InterchangeObject_list_t essence_sub_descriptors; AS_02::ACES::PictureDescriptor PDesc; @@ -1314,6 +1313,10 @@ write_ACES_file(CommandOptions& Options) else Kumu::GenRandomUUID(Info.AssetUUID); +#ifdef HAVE_OPENSSL + byte_t IV_buf[CBC_BLOCK_SIZE]; + Kumu::FortunaRNG RNG; + // configure encryption if (Options.key_flag) { @@ -1342,6 +1345,7 @@ write_ACES_file(CommandOptions& Options) result = HMAC->InitKey(Options.key_value, Info.LabelSetType); } } +#endif if (ASDCP_SUCCESS(result)) { @@ -1435,8 +1439,6 @@ write_PCM_file(CommandOptions& Options) PCMParserList Parser; AS_02::PCM::MXFWriter Writer; PCM::FrameBuffer FrameBuffer; - byte_t IV_buf[CBC_BLOCK_SIZE]; - Kumu::FortunaRNG RNG; ASDCP::MXF::WaveAudioDescriptor *essence_descriptor = 0; // set up essence parser @@ -1511,9 +1513,12 @@ write_PCM_file(CommandOptions& Options) else Kumu::GenRandomUUID(Info.AssetUUID); +#ifdef HAVE_OPENSSL // configure encryption if( Options.key_flag ) { + byte_t IV_buf[CBC_BLOCK_SIZE]; + Kumu::FortunaRNG RNG; Kumu::GenRandomUUID(Info.ContextID); Info.EncryptedEssence = true; @@ -1539,6 +1544,7 @@ write_PCM_file(CommandOptions& Options) result = HMAC->InitKey(Options.key_value, Info.LabelSetType); } } +#endif // HAVE_OPENSSL if ( ASDCP_SUCCESS(result) ) { @@ -1586,8 +1592,6 @@ write_PCM_file(CommandOptions& Options) } - - //------------------------------------------------------------------------------------------ // TimedText essence @@ -1605,7 +1609,6 @@ write_timed_text_file(CommandOptions& Options) TimedText::FrameBuffer FrameBuffer; TimedText::TimedTextDescriptor TDesc; byte_t IV_buf[CBC_BLOCK_SIZE]; - Kumu::FortunaRNG RNG; // set up essence parser Result_t result = Parser.OpenRead(Options.filenames.front()); @@ -1640,9 +1643,11 @@ write_timed_text_file(CommandOptions& Options) else Kumu::GenRandomUUID(Info.AssetUUID); +#ifdef HAVE_OPENSSL // configure encryption if( Options.key_flag ) { + Kumu::FortunaRNG RNG; Kumu::GenRandomUUID(Info.ContextID); Info.EncryptedEssence = true; @@ -1668,6 +1673,7 @@ write_timed_text_file(CommandOptions& Options) result = HMAC->InitKey(Options.key_value, Info.LabelSetType); } } +#endif // HAVE_OPENSSL if ( ASDCP_SUCCESS(result) ) result = Writer.OpenWrite(Options.out_file.c_str(), Info, TDesc); @@ -1745,8 +1751,6 @@ write_isxd_file(CommandOptions& Options) AS_02::ISXD::MXFWriter Writer; DCData::FrameBuffer FrameBuffer(Options.fb_size); DCData::SequenceParser Parser; - byte_t IV_buf[CBC_BLOCK_SIZE]; - Kumu::FortunaRNG RNG; // set up essence parser Result_t result = Parser.OpenRead(Options.filenames.front()); @@ -1772,9 +1776,12 @@ write_isxd_file(CommandOptions& Options) Info.LabelSetType = LS_MXF_SMPTE; +#ifdef HAVE_OPENSSL // configure encryption if( Options.key_flag ) { + byte_t IV_buf[CBC_BLOCK_SIZE]; + Kumu::FortunaRNG RNG; Kumu::GenRandomUUID(Info.ContextID); Info.EncryptedEssence = true; @@ -1800,6 +1807,7 @@ write_isxd_file(CommandOptions& Options) result = HMAC->InitKey(Options.key_value, Info.LabelSetType); } } +#endif // HAVE_OPENSSL if ( ASDCP_SUCCESS(result) ) { @@ -1897,7 +1905,6 @@ write_isxd_file(CommandOptions& Options) return RESULT_READFAIL; global_metadata.Size(read_count); - std::string ns_prefix, type_name; Kumu::AttributeList doc_attr_list; result = GetXMLDocType(global_metadata.RoData(), global_metadata.Size(), ns_prefix, type_name, diff --git a/src/asdcp-test.cpp b/src/asdcp-test.cpp index df108c3..ecf6f21 100755 --- a/src/asdcp-test.cpp +++ b/src/asdcp-test.cpp @@ -49,11 +49,11 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <KM_fileio.h> #include <KM_prng.h> +#include <KM_sha1.h> #include <PCMParserList.h> #include <WavFileWriter.h> #include <MXF.h> #include <Metadata.h> -#include <openssl/sha.h> #include <iostream> #include <assert.h> @@ -555,7 +555,6 @@ write_MPEG2_file(CommandOptions& Options) MPEG2::MXFWriter Writer; MPEG2::VideoDescriptor VDesc; byte_t IV_buf[CBC_BLOCK_SIZE]; - Kumu::FortunaRNG RNG; // set up essence parser Result_t result = Parser.OpenRead(Options.filenames[0]); @@ -588,9 +587,12 @@ write_MPEG2_file(CommandOptions& Options) fprintf(stderr, "ATTENTION! Writing SMPTE Universal Labels\n"); } +#ifdef HAVE_OPENSSL // configure encryption if( Options.key_flag ) { + Kumu::FortunaRNG RNG; + Kumu::GenRandomUUID(Info.ContextID); Info.EncryptedEssence = true; @@ -612,6 +614,7 @@ write_MPEG2_file(CommandOptions& Options) result = HMAC->InitKey(Options.key_value, Info.LabelSetType); } } +#endif // HAVE_OPENSSL if ( ASDCP_SUCCESS(result) ) result = Writer.OpenWrite(Options.out_file, Info, VDesc); @@ -698,6 +701,7 @@ read_MPEG2_file(CommandOptions& Options) result = OutFile.OpenWrite(filename); } +#ifdef HAVE_OPENSSL if ( ASDCP_SUCCESS(result) && Options.key_flag ) { Context = new AESDecContext; @@ -719,6 +723,7 @@ read_MPEG2_file(CommandOptions& Options) } } } +#endif // HAVE_OPENSSL ui32_t last_frame = Options.start_frame + ( Options.duration ? Options.duration : frame_count); if ( last_frame > frame_count ) @@ -806,7 +811,6 @@ write_JP2K_S_file(CommandOptions& Options) JP2K::PictureDescriptor PDesc; JP2K::SequenceParser ParserLeft, ParserRight; byte_t IV_buf[CBC_BLOCK_SIZE]; - Kumu::FortunaRNG RNG; if ( Options.file_count != 2 ) { @@ -848,9 +852,12 @@ write_JP2K_S_file(CommandOptions& Options) fprintf(stderr, "ATTENTION! Writing SMPTE Universal Labels\n"); } +#ifdef HAVE_OPENSSL // configure encryption if( Options.key_flag ) { + Kumu::FortunaRNG RNG; + Kumu::GenRandomUUID(Info.ContextID); Info.EncryptedEssence = true; @@ -872,6 +879,7 @@ write_JP2K_S_file(CommandOptions& Options) result = HMAC->InitKey(Options.key_value, Info.LabelSetType); } } +#endif // HAVE_OPENSSL if ( ASDCP_SUCCESS(result) ) result = Writer.OpenWrite(Options.out_file, Info, PDesc); @@ -953,6 +961,7 @@ read_JP2K_S_file(CommandOptions& Options) } } +#ifdef HAVE_OPENSSL if ( ASDCP_SUCCESS(result) && Options.key_flag ) { Context = new AESDecContext; @@ -974,6 +983,7 @@ read_JP2K_S_file(CommandOptions& Options) } } } +#endif // HAVE_OPENSSL const int filename_max = 1024; char filename[filename_max]; @@ -1036,7 +1046,6 @@ write_JP2K_file(CommandOptions& Options) JP2K::PictureDescriptor PDesc; JP2K::SequenceParser Parser; byte_t IV_buf[CBC_BLOCK_SIZE]; - Kumu::FortunaRNG RNG; // set up essence parser Result_t result = Parser.OpenRead(Options.filenames[0], Options.j2c_pedantic); @@ -1070,9 +1079,11 @@ write_JP2K_file(CommandOptions& Options) fprintf(stderr, "ATTENTION! Writing SMPTE Universal Labels\n"); } +#ifdef HAVE_OPENSSL // configure encryption if( Options.key_flag ) { + Kumu::FortunaRNG RNG; Kumu::GenRandomUUID(Info.ContextID); Info.EncryptedEssence = true; @@ -1094,6 +1105,7 @@ write_JP2K_file(CommandOptions& Options) result = HMAC->InitKey(Options.key_value, Info.LabelSetType); } } +#endif if ( ASDCP_SUCCESS(result) ) result = Writer.OpenWrite(Options.out_file, Info, PDesc); @@ -1172,6 +1184,7 @@ read_JP2K_file(CommandOptions& Options) } } +#ifdef HAVE_OPENSSL if ( ASDCP_SUCCESS(result) && Options.key_flag ) { Context = new AESDecContext; @@ -1193,6 +1206,7 @@ read_JP2K_file(CommandOptions& Options) } } } +#endif // HAVE_OPENSSL ui32_t last_frame = Options.start_frame + ( Options.duration ? Options.duration : frame_count); if ( last_frame > frame_count ) @@ -1242,7 +1256,6 @@ write_PCM_file(CommandOptions& Options) PCM::AudioDescriptor ADesc; Rational PictureRate = Options.PictureRate(); byte_t IV_buf[CBC_BLOCK_SIZE]; - Kumu::FortunaRNG RNG; // set up essence parser Result_t result = Parser.OpenRead(Options.file_count, Options.filenames, PictureRate); @@ -1286,9 +1299,11 @@ write_PCM_file(CommandOptions& Options) fprintf(stderr, "ATTENTION! Writing SMPTE Universal Labels\n"); } +#ifdef HAVE_OPENSSL // configure encryption if( Options.key_flag ) { + Kumu::FortunaRNG RNG; Kumu::GenRandomUUID(Info.ContextID); Info.EncryptedEssence = true; @@ -1310,6 +1325,7 @@ write_PCM_file(CommandOptions& Options) result = HMAC->InitKey(Options.key_value, Info.LabelSetType); } } +#endif // HAVE_OPENSSL if ( ASDCP_SUCCESS(result) ) result = Writer.OpenWrite(Options.out_file, Info, ADesc); @@ -1421,6 +1437,7 @@ read_PCM_file(CommandOptions& Options) ( Options.mono_wav ? WavFileWriter::ST_MONO : WavFileWriter::ST_NONE ) )); } +#ifdef HAVE_OPENSSL if ( ASDCP_SUCCESS(result) && Options.key_flag ) { Context = new AESDecContext; @@ -1442,6 +1459,7 @@ read_PCM_file(CommandOptions& Options) } } } +#endif // HAVE_OPENSSL for ( ui32_t i = Options.start_frame; ASDCP_SUCCESS(result) && i < last_frame; i++ ) { @@ -1477,7 +1495,6 @@ write_timed_text_file(CommandOptions& Options) TimedText::FrameBuffer FrameBuffer; TimedText::TimedTextDescriptor TDesc; byte_t IV_buf[CBC_BLOCK_SIZE]; - Kumu::FortunaRNG RNG; // set up essence parser Result_t result = Parser.OpenRead(Options.filenames[0]); @@ -1509,9 +1526,11 @@ write_timed_text_file(CommandOptions& Options) fprintf(stderr, "ATTENTION! Writing SMPTE Universal Labels\n"); } +#ifdef HAVE_OPENSSL // configure encryption if( Options.key_flag ) { + Kumu::FortunaRNG RNG; Kumu::GenRandomUUID(Info.ContextID); Info.EncryptedEssence = true; @@ -1533,6 +1552,7 @@ write_timed_text_file(CommandOptions& Options) result = HMAC->InitKey(Options.key_value, Info.LabelSetType); } } +#endif // HAVE_OPENSSL if ( ASDCP_SUCCESS(result) ) result = Writer.OpenWrite(Options.out_file, Info, TDesc); @@ -1606,6 +1626,7 @@ read_timed_text_file(CommandOptions& Options) TimedText::DescriptorDump(TDesc); } +#ifdef HAVE_OPENSSL if ( ASDCP_SUCCESS(result) && Options.key_flag ) { Context = new AESDecContext; @@ -1627,6 +1648,7 @@ read_timed_text_file(CommandOptions& Options) } } } +#endif // HAVE_OPENSSL if ( ASDCP_FAILURE(result) ) return result; @@ -1880,7 +1902,6 @@ show_file_info(CommandOptions& Options) return result; } - // Result_t digest_file(const char* filename) @@ -1889,7 +1910,7 @@ digest_file(const char* filename) ASDCP_TEST_NULL_STR(filename); FileReader Reader; - SHA_CTX Ctx; + SHA1_CTX Ctx; SHA1_Init(&Ctx); ByteString Buf(8192); @@ -1962,11 +1983,9 @@ main(int argc, const char** argv) } else if ( Options.mode == MMT_GEN_KEY ) { - Kumu::FortunaRNG RNG; - byte_t bin_buf[KeyLen]; - - RNG.FillRandom(bin_buf, KeyLen); - printf("%s\n", Kumu::bin2hex(bin_buf, KeyLen, str_buf, 64)); + Kumu::SymmetricKey key; + GenRandomValue(key); + printf("%s\n", Kumu::bin2hex(key.Value(), key.Size(), str_buf, 64)); } else if ( Options.mode == MMT_GEN_ID ) { diff --git a/src/asdcp-unwrap.cpp b/src/asdcp-unwrap.cpp index a24219f..7b607d9 100755 --- a/src/asdcp-unwrap.cpp +++ b/src/asdcp-unwrap.cpp @@ -356,6 +356,7 @@ read_MPEG2_file(CommandOptions& Options) result = OutFile.OpenWrite(filename); } +#ifdef HAVE_OPENSSL if ( ASDCP_SUCCESS(result) && Options.key_flag ) { Context = new AESDecContext; @@ -377,6 +378,7 @@ read_MPEG2_file(CommandOptions& Options) } } } +#endif // HAVE_OPENSSL ui32_t last_frame = Options.start_frame + ( Options.duration ? Options.duration : frame_count); if ( last_frame > frame_count ) @@ -483,6 +485,7 @@ read_JP2K_S_file(CommandOptions& Options) } } +#ifdef HAVE_OPENSSL if ( ASDCP_SUCCESS(result) && Options.key_flag ) { Context = new AESDecContext; @@ -504,6 +507,7 @@ read_JP2K_S_file(CommandOptions& Options) } } } +#endif // HAVE_OPENSSL const int filename_max = 1024; char filename[filename_max]; @@ -589,6 +593,7 @@ read_JP2K_file(CommandOptions& Options) } } +#ifdef HAVE_OPENSSL if ( ASDCP_SUCCESS(result) && Options.key_flag ) { Context = new AESDecContext; @@ -610,6 +615,7 @@ read_JP2K_file(CommandOptions& Options) } } } +#endif // HAVE_OPENSSL ui32_t last_frame = Options.start_frame + ( Options.duration ? Options.duration : frame_count); if ( last_frame > frame_count ) @@ -721,6 +727,7 @@ read_PCM_file(CommandOptions& Options) } } +#ifdef HAVE_OPENSSL if ( ASDCP_SUCCESS(result) && Options.key_flag ) { Context = new AESDecContext; @@ -742,6 +749,7 @@ read_PCM_file(CommandOptions& Options) } } } +#endif // HAVE_OPENSSL for ( ui32_t i = Options.start_frame; ASDCP_SUCCESS(result) && i < last_frame; i++ ) { @@ -790,6 +798,7 @@ read_timed_text_file(CommandOptions& Options) TimedText::DescriptorDump(TDesc); } +#ifdef HAVE_OPENSSL if ( ASDCP_SUCCESS(result) && Options.key_flag ) { Context = new AESDecContext; @@ -811,6 +820,7 @@ read_timed_text_file(CommandOptions& Options) } } } +#endif // HAVE_OPENSSL if ( ASDCP_FAILURE(result) ) return result; @@ -881,6 +891,7 @@ read_DCData_file(CommandOptions& Options) } } +#ifdef HAVE_OPENSSL if ( ASDCP_SUCCESS(result) && Options.key_flag ) { Context = new AESDecContext; @@ -902,6 +913,7 @@ read_DCData_file(CommandOptions& Options) } } } +#endif // HAVE_OPENSSL ui32_t last_frame = Options.start_frame + ( Options.duration ? Options.duration : frame_count); if ( last_frame > frame_count ) diff --git a/src/asdcp-util.cpp b/src/asdcp-util.cpp index a3c891d..d93465c 100755 --- a/src/asdcp-util.cpp +++ b/src/asdcp-util.cpp @@ -35,8 +35,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <KM_fileio.h> #include <KM_prng.h> +#include <KM_sha1.h> #include <AS_DCP.h> -#include <openssl/sha.h> using namespace Kumu; @@ -182,7 +182,7 @@ Result_t digest_file(const std::string& filename) { FileReader Reader; - SHA_CTX Ctx; + SHA1_CTX Ctx; SHA1_Init(&Ctx); ByteString Buf(8192); @@ -244,17 +244,15 @@ main(int argc, const char** argv) if ( Options.mode == MMT_GEN_KEY ) { - Kumu::FortunaRNG RNG; - byte_t bin_buf[ASDCP::KeyLen]; - - RNG.FillRandom(bin_buf, ASDCP::KeyLen); - printf("%s\n", Kumu::bin2hex(bin_buf, ASDCP::KeyLen, str_buf, 64)); + SymmetricKey key_value; + Kumu::GenRandomValue(key_value); + printf("%s\n", key_value.EncodeHex(str_buf, 64)); } else if ( Options.mode == MMT_GEN_ID ) { - UUID TmpID; - Kumu::GenRandomValue(TmpID); - printf("%s\n", TmpID.EncodeHex(str_buf, 64)); + UUID id_value; + Kumu::GenRandomValue(id_value); + printf("%s\n", id_value.EncodeHex(str_buf, 64)); } else if ( Options.mode == MMT_DIGEST ) { diff --git a/src/asdcp-wrap.cpp b/src/asdcp-wrap.cpp index 66f291a..2028f53 100755 --- a/src/asdcp-wrap.cpp +++ b/src/asdcp-wrap.cpp @@ -534,8 +534,6 @@ write_MPEG2_file(CommandOptions& Options) MPEG2::Parser Parser; MPEG2::MXFWriter Writer; MPEG2::VideoDescriptor VDesc; - byte_t IV_buf[CBC_BLOCK_SIZE]; - Kumu::FortunaRNG RNG; // set up essence parser Result_t result = Parser.OpenRead(Options.filenames.front()); @@ -568,9 +566,12 @@ write_MPEG2_file(CommandOptions& Options) fprintf(stderr, "ATTENTION! Writing SMPTE Universal Labels\n"); } +#ifdef HAVE_OPENSSL // configure encryption if( Options.key_flag ) { + byte_t IV_buf[CBC_BLOCK_SIZE]; + Kumu::FortunaRNG RNG; Kumu::GenRandomUUID(Info.ContextID); Info.EncryptedEssence = true; @@ -596,6 +597,7 @@ write_MPEG2_file(CommandOptions& Options) result = HMAC->InitKey(Options.key_value, Info.LabelSetType); } } +#endif // HAVE_OPENSSL if ( ASDCP_SUCCESS(result) ) result = Writer.OpenWrite(Options.out_file, Info, VDesc); @@ -690,7 +692,6 @@ write_JP2K_S_file(CommandOptions& Options) JP2K::PictureDescriptor PDesc; JP2K::SequenceParser ParserLeft, ParserRight; byte_t IV_buf[CBC_BLOCK_SIZE]; - Kumu::FortunaRNG RNG; if ( Options.filenames.size() != 2 ) { @@ -738,9 +739,11 @@ write_JP2K_S_file(CommandOptions& Options) fprintf(stderr, "ATTENTION! Writing SMPTE Universal Labels\n"); } +#ifdef HAVE_OPENSSL // configure encryption if( Options.key_flag ) { + Kumu::FortunaRNG RNG; Kumu::GenRandomUUID(Info.ContextID); Info.EncryptedEssence = true; @@ -766,6 +769,7 @@ write_JP2K_S_file(CommandOptions& Options) result = HMAC->InitKey(Options.key_value, Info.LabelSetType); } } +#endif // HAVE_OPENSSL if ( ASDCP_SUCCESS(result) ) result = Writer.OpenWrite(Options.out_file, Info, PDesc); @@ -840,7 +844,6 @@ write_JP2K_file(CommandOptions& Options) JP2K::PictureDescriptor PDesc; JP2K::SequenceParser Parser; byte_t IV_buf[CBC_BLOCK_SIZE]; - Kumu::FortunaRNG RNG; // set up essence parser Result_t result = Parser.OpenRead(Options.filenames.front(), Options.j2c_pedantic); @@ -877,9 +880,11 @@ write_JP2K_file(CommandOptions& Options) fprintf(stderr, "ATTENTION! Writing SMPTE Universal Labels\n"); } +#ifdef HAVE_OPENSSL // configure encryption if( Options.key_flag ) { + Kumu::FortunaRNG RNG; Kumu::GenRandomUUID(Info.ContextID); Info.EncryptedEssence = true; @@ -905,6 +910,7 @@ write_JP2K_file(CommandOptions& Options) result = HMAC->InitKey(Options.key_value, Info.LabelSetType); } } +#endif // HAVE_OPENSSL if ( ASDCP_SUCCESS(result) ) result = Writer.OpenWrite(Options.out_file, Info, PDesc); @@ -977,7 +983,6 @@ write_PCM_file(CommandOptions& Options) PCM::AudioDescriptor ADesc; Rational PictureRate = Options.PictureRate(); byte_t IV_buf[CBC_BLOCK_SIZE]; - Kumu::FortunaRNG RNG; // set up essence parser Result_t result = Parser.OpenRead(Options.filenames, PictureRate); @@ -1021,9 +1026,11 @@ write_PCM_file(CommandOptions& Options) fprintf(stderr, "ATTENTION! Writing SMPTE Universal Labels\n"); } +#ifdef HAVE_OPENSSL // configure encryption if( Options.key_flag ) { + Kumu::FortunaRNG RNG; Kumu::GenRandomUUID(Info.ContextID); Info.EncryptedEssence = true; @@ -1049,6 +1056,7 @@ write_PCM_file(CommandOptions& Options) result = HMAC->InitKey(Options.key_value, Info.LabelSetType); } } +#endif // HAVE_OPENSSL if ( ASDCP_SUCCESS(result) ) result = Writer.OpenWrite(Options.out_file, Info, ADesc); @@ -1171,7 +1179,6 @@ write_PCM_with_ATMOS_sync_file(CommandOptions& Options) PCM::AudioDescriptor ADesc; Rational PictureRate = Options.PictureRate(); byte_t IV_buf[CBC_BLOCK_SIZE]; - Kumu::FortunaRNG RNG; WriterInfo Info = s_MyInfo; // fill in your favorite identifiers here if ( Options.asset_id_flag ) @@ -1213,9 +1220,11 @@ write_PCM_with_ATMOS_sync_file(CommandOptions& Options) Info.LabelSetType = LS_MXF_SMPTE; fprintf(stderr, "ATTENTION! Writing SMPTE Universal Labels\n"); +#ifdef HAVE_OPENSSL // configure encryption if( Options.key_flag ) { + Kumu::FortunaRNG RNG; Kumu::GenRandomUUID(Info.ContextID); Info.EncryptedEssence = true; @@ -1241,6 +1250,7 @@ write_PCM_with_ATMOS_sync_file(CommandOptions& Options) result = HMAC->InitKey(Options.key_value, Info.LabelSetType); } } +#endif // HAVE_OPENSSL if ( ASDCP_SUCCESS(result) ) result = Writer.OpenWrite(Options.out_file, Info, ADesc); @@ -1296,7 +1306,6 @@ write_PCM_with_ATMOS_sync_file(CommandOptions& Options) return result; } - //------------------------------------------------------------------------------------------ // TimedText essence @@ -1314,7 +1323,6 @@ write_timed_text_file(CommandOptions& Options) TimedText::FrameBuffer FrameBuffer; TimedText::TimedTextDescriptor TDesc; byte_t IV_buf[CBC_BLOCK_SIZE]; - Kumu::FortunaRNG RNG; // set up essence parser Result_t result = Parser.OpenRead(Options.filenames.front()); @@ -1344,9 +1352,11 @@ write_timed_text_file(CommandOptions& Options) Info.LabelSetType = LS_MXF_SMPTE; fprintf(stderr, "ATTENTION! Writing SMPTE Universal Labels\n"); +#ifdef HAVE_OPENSSL // configure encryption if( Options.key_flag ) { + Kumu::FortunaRNG RNG; Kumu::GenRandomUUID(Info.ContextID); Info.EncryptedEssence = true; @@ -1372,6 +1382,7 @@ write_timed_text_file(CommandOptions& Options) result = HMAC->InitKey(Options.key_value, Info.LabelSetType); } } +#endif // HAVE_OPENSSL if ( ASDCP_SUCCESS(result) ) result = Writer.OpenWrite(Options.out_file, Info, TDesc); @@ -1433,7 +1444,6 @@ write_dolby_atmos_file(CommandOptions& Options) ATMOS::AtmosDescriptor ADesc; DCData::SequenceParser Parser; byte_t IV_buf[CBC_BLOCK_SIZE]; - Kumu::FortunaRNG RNG; // set up essence parser Result_t result = Parser.OpenRead(Options.filenames.front()); @@ -1468,9 +1478,11 @@ write_dolby_atmos_file(CommandOptions& Options) Info.LabelSetType = LS_MXF_SMPTE; +#ifdef HAVE_OPENSSL // configure encryption if( Options.key_flag ) { + Kumu::FortunaRNG RNG; Kumu::GenRandomUUID(Info.ContextID); Info.EncryptedEssence = true; @@ -1496,6 +1508,7 @@ write_dolby_atmos_file(CommandOptions& Options) result = HMAC->InitKey(Options.key_value, Info.LabelSetType); } } +#endif if ( ASDCP_SUCCESS(result) ) result = Writer.OpenWrite(Options.out_file, Info, ADesc); @@ -1555,7 +1568,6 @@ write_aux_data_file(CommandOptions& Options) DCData::DCDataDescriptor DDesc; DCData::SequenceParser Parser; byte_t IV_buf[CBC_BLOCK_SIZE]; - Kumu::FortunaRNG RNG; // set up essence parser Result_t result = Parser.OpenRead(Options.filenames.front()); @@ -1585,9 +1597,11 @@ write_aux_data_file(CommandOptions& Options) Info.LabelSetType = LS_MXF_SMPTE; +#ifdef HAVE_OPENSSL // configure encryption if( Options.key_flag ) { + Kumu::FortunaRNG RNG; Kumu::GenRandomUUID(Info.ContextID); Info.EncryptedEssence = true; @@ -1613,6 +1627,7 @@ write_aux_data_file(CommandOptions& Options) result = HMAC->InitKey(Options.key_value, Info.LabelSetType); } } +#endif // HAVE_OPENSSL if ( ASDCP_SUCCESS(result) ) result = Writer.OpenWrite(Options.out_file, Info, DDesc); diff --git a/src/fips-186-rng-test.cpp b/src/fips-186-rng-test.cpp index 08a1665..8c94595 100755 --- a/src/fips-186-rng-test.cpp +++ b/src/fips-186-rng-test.cpp @@ -31,7 +31,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <KM_util.h> #include <KM_prng.h> -#include <openssl/sha.h> using namespace Kumu; diff --git a/src/kmfilegen.cpp b/src/kmfilegen.cpp index 2ce0332..21b1d8e 100755 --- a/src/kmfilegen.cpp +++ b/src/kmfilegen.cpp @@ -34,7 +34,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <iostream> #include <KM_fileio.h> #include <KM_prng.h> -#include <openssl/aes.h> +#include <KM_aes.h> #include <assert.h> using namespace Kumu; @@ -43,7 +43,7 @@ using namespace Kumu; static const char* PROGRAM_NAME = "kmfilegen"; // program name for messages const ui32_t RNG_KEY_SIZE = 16; const ui32_t RNG_KEY_SIZE_BITS = 128; -const ui32_t RNG_BLOCK_SIZE = 16; +const ui32_t RNG_BLOCK_SIZE = AES_BLOCKLEN; // globals ui32_t s_Nonce = 0; @@ -239,7 +239,7 @@ public: #pragma pack(4) class CTR_Setup { - AES_KEY m_Context; + AES_ctx m_Context; byte_t m_key[RNG_KEY_SIZE]; byte_t m_preamble[8]; ui32_t m_nonce; @@ -264,7 +264,7 @@ public: m_nonce = KM_i32_LE(s_Nonce--); m_ctr &= KM_i32_LE(0x7fffffff); // make sure we have 2GB headroom memcpy(buf, m_key, WriteSize()); - AES_set_encrypt_key(m_key, RNG_KEY_SIZE_BITS, &m_Context); + AES_init_ctx(&m_Context, m_key); } // @@ -272,7 +272,7 @@ public: { assert(buf); memcpy(m_key, buf, WriteSize()); - AES_set_encrypt_key(m_key, RNG_KEY_SIZE_BITS, &m_Context); + AES_init_ctx(&m_Context, m_key); } // @@ -281,7 +281,8 @@ public: ui32_t gen_count = 0; while ( gen_count + RNG_BLOCK_SIZE <= buf_len ) { - AES_encrypt(m_preamble, buf + gen_count, &m_Context); + memcpy(buf + gen_count, m_preamble, RNG_BLOCK_SIZE); + AES_encrypt(&m_Context, buf + gen_count); m_ctr = KM_i32_LE(KM_i32_LE(m_ctr) + 1); gen_count += RNG_BLOCK_SIZE; } @@ -308,9 +309,9 @@ CreateLargeFile(CommandOptions& Options) { if ( KM_SUCCESS(result)) { - CTR_Setup CTR; - CTR.SetupWrite(FB.Data()); - CTR.FillRandom(FB.Data() + CTR.WriteSize(), Megabyte - CTR.WriteSize()); + CTR_Setup counter; + counter.SetupWrite(FB.Data()); + counter.FillRandom(FB.Data() + counter.WriteSize(), Megabyte - counter.WriteSize()); result = Writer.Write(FB.RoData(), Megabyte, &write_count); assert(write_count == Megabyte); fprintf(stderr, "\r%8u ", ++write_total); @@ -327,21 +328,21 @@ Result_t validate_chunk(ByteString& FB, ByteString& CB, ui32_t* nonce_value) { assert(nonce_value); - CTR_Setup CTR; - CTR.SetupRead(FB.RoData()); + CTR_Setup counter; + counter.SetupRead(FB.RoData()); - CTR.FillRandom(CB.Data() + CTR.WriteSize(), - Megabyte - CTR.WriteSize()); + counter.FillRandom(CB.Data() + counter.WriteSize(), + Megabyte - counter.WriteSize()); - if ( memcmp(FB.RoData() + CTR.WriteSize(), - CB.RoData() + CTR.WriteSize(), - Megabyte - CTR.WriteSize()) != 0 ) + if ( memcmp(FB.RoData() + counter.WriteSize(), + CB.RoData() + counter.WriteSize(), + Megabyte - counter.WriteSize()) != 0 ) { fprintf(stderr, "Check data mismatched in chunk\n"); return RESULT_FAIL; } - *nonce_value = CTR.Nonce(); + *nonce_value = counter.Nonce(); return RESULT_OK; } diff --git a/src/phdr-unwrap.cpp b/src/phdr-unwrap.cpp index 21c088c..be62110 100755 --- a/src/phdr-unwrap.cpp +++ b/src/phdr-unwrap.cpp @@ -326,6 +326,7 @@ read_JP2K_file(CommandOptions& Options) } } +#ifdef HAVE_OPENSSL if ( ASDCP_SUCCESS(result) && Options.key_flag ) { Context = new AESDecContext; @@ -347,6 +348,7 @@ read_JP2K_file(CommandOptions& Options) } } } +#endif // HAVE_OPENSSL ui32_t last_frame = Options.start_frame + ( Options.duration ? Options.duration : frame_count); if ( last_frame > frame_count ) diff --git a/src/phdr-wrap.cpp b/src/phdr-wrap.cpp index b919b96..1632508 100755 --- a/src/phdr-wrap.cpp +++ b/src/phdr-wrap.cpp @@ -471,9 +471,6 @@ write_JP2K_file(CommandOptions& Options) AESEncContext* Context = 0; HMACContext* HMAC = 0; - byte_t IV_buf[CBC_BLOCK_SIZE]; - Kumu::FortunaRNG RNG; - ASDCP::MXF::FileDescriptor *essence_descriptor = 0; ASDCP::MXF::InterchangeObject_list_t essence_sub_descriptors; @@ -545,9 +542,12 @@ write_JP2K_file(CommandOptions& Options) else Kumu::GenRandomUUID(Info.AssetUUID); +#ifdef HAVE_OPENSSL // configure encryption if( Options.key_flag ) { + byte_t IV_buf[CBC_BLOCK_SIZE]; + Kumu::FortunaRNG RNG; Kumu::GenRandomUUID(Info.ContextID); Info.EncryptedEssence = true; @@ -569,6 +569,7 @@ write_JP2K_file(CommandOptions& Options) result = HMAC->InitKey(Options.key_value, Info.LabelSetType); } } +#endif // HAVE_OPENSSL if ( ASDCP_SUCCESS(result) ) { |
