Merge branch 'master' of github.com:stz2012/libarib25
This commit is contained in:
commit
f79b38b982
131
.appveyor.yml
Normal file
131
.appveyor.yml
Normal file
@ -0,0 +1,131 @@
|
||||
version: "0.2.5 build #{build}"
|
||||
shallow_clone: true
|
||||
|
||||
environment:
|
||||
SOLUTION: arib_std_b25.sln
|
||||
BUILDENV: MSBUILD
|
||||
|
||||
MSYS2_DIR: msys64
|
||||
|
||||
CYGWIN_MIRROR: http://cygwin.mirror.constant.com
|
||||
CYGWIN_PACKAGES: mpfr,mpc,gcc-core,gcc-g++,make,cmake
|
||||
|
||||
matrix:
|
||||
# Latest version of VisualStudio
|
||||
- JOB_NAME: "Visual Studio 16 2019 (Win32)"
|
||||
CMAKE_GENERATOR: "Visual Studio 16 2019"
|
||||
CMAKE_GENERATOR_PLATFORM: Win32
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
- JOB_NAME: "Visual Studio 16 2019 (Win64)"
|
||||
CMAKE_GENERATOR: "Visual Studio 16 2019"
|
||||
CMAKE_GENERATOR_PLATFORM: x64
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
- JOB_NAME: "Visual Studio 16 2019 (ARM)"
|
||||
CMAKE_GENERATOR: "Visual Studio 16 2019"
|
||||
CMAKE_GENERATOR_PLATFORM: ARM
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
- JOB_NAME: "Visual Studio 16 2019 (ARM64)"
|
||||
CMAKE_GENERATOR: "Visual Studio 16 2019"
|
||||
CMAKE_GENERATOR_PLATFORM: ARM64
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
|
||||
# Windows Server 2012R2 or Windows 8 or above
|
||||
- JOB_NAME: "Visual Studio 15 2017 (Win32)"
|
||||
CMAKE_GENERATOR: "Visual Studio 15 2017"
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
- JOB_NAME: "Visual Studio 15 2017 (Win64)"
|
||||
CMAKE_GENERATOR: "Visual Studio 15 2017 Win64"
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
|
||||
# Windows Server 2008R2 or Windows 7 or above
|
||||
- JOB_NAME: "Visual Studio 14 2015 (Win32)"
|
||||
CMAKE_GENERATOR: "Visual Studio 14 2015"
|
||||
- JOB_NAME: "Visual Studio 14 2015 (Win64)"
|
||||
CMAKE_GENERATOR: "Visual Studio 14 2015 Win64"
|
||||
- JOB_NAME: "Visual Studio 12 2013 (Win32)"
|
||||
CMAKE_GENERATOR: "Visual Studio 12 2013"
|
||||
- JOB_NAME: "Visual Studio 12 2013 (Win64)"
|
||||
CMAKE_GENERATOR: "Visual Studio 12 2013 Win64"
|
||||
- JOB_NAME: "Visual Studio 11 2012 (Win32)"
|
||||
CMAKE_GENERATOR: "Visual Studio 11 2012"
|
||||
- JOB_NAME: "Visual Studio 11 2012 (Win64)"
|
||||
CMAKE_GENERATOR: "Visual Studio 11 2012 Win64"
|
||||
|
||||
# WindowsXP or above (C99 is not yet supported)
|
||||
- JOB_NAME: "Visual Studio 10 2010 (Win32)"
|
||||
CMAKE_GENERATOR: "Visual Studio 10 2010"
|
||||
- JOB_NAME: "Visual Studio 10 2010 (Win64)"
|
||||
CMAKE_GENERATOR: "Visual Studio 10 2010 Win64"
|
||||
- JOB_NAME: "Visual Studio 9 2008 (Win32)"
|
||||
CMAKE_GENERATOR: "Visual Studio 9 2008"
|
||||
|
||||
# MSYS2
|
||||
- JOB_NAME: "MSYS2 MinGW32 (i686)"
|
||||
CMAKE_GENERATOR: "MSYS Makefiles"
|
||||
BUILDENV: MSYS2
|
||||
MSYS2_ARCH: i686
|
||||
MSYSTEM: MINGW32
|
||||
|
||||
- JOB_NAME: "MSYS2 MinGW64 (x86_64)"
|
||||
CMAKE_GENERATOR: "MSYS Makefiles"
|
||||
BUILDENV: MSYS2
|
||||
MSYS2_ARCH: x86_64
|
||||
MSYSTEM: MINGW64
|
||||
|
||||
# Cygwin
|
||||
- JOB_NAME: "Cygwin32 (x86)"
|
||||
CMAKE_GENERATOR: "Unix Makefiles"
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
BUILDENV: CYGWIN
|
||||
CYGWIN_DIR: cygwin
|
||||
CYGWIN_ARCH: x86
|
||||
|
||||
- JOB_NAME: "Cygwin64 (x86_64)"
|
||||
CMAKE_GENERATOR: "Unix Makefiles"
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
BUILDENV: CYGWIN
|
||||
CYGWIN_DIR: cygwin64
|
||||
CYGWIN_ARCH: x86_64
|
||||
|
||||
install:
|
||||
- if "%BUILDENV%" == "MSYS2"
|
||||
set MSYS2_ROOT=%HOMEDRIVE%\%MSYS2_DIR%
|
||||
- if "%BUILDENV%" == "CYGWIN"
|
||||
set CYGWIN_ROOT=%HOMEDRIVE%\%CYGWIN_DIR%
|
||||
|
||||
- if "%BUILDENV%" == "CYGWIN" (
|
||||
appveyor
|
||||
DownloadFile "https://cygwin.com/setup-%CYGWIN_ARCH%.exe"
|
||||
-FileName "%CYGWIN_ROOT%/setup-%CYGWIN_ARCH%.exe" &&
|
||||
"%CYGWIN_ROOT%/setup-%CYGWIN_ARCH%.exe"
|
||||
-qnNdOW
|
||||
--root "%CYGWIN_ROOT%"
|
||||
--site "%CYGWIN_MIRROR%"
|
||||
--local-package-dir "%CYGWIN_ROOT%/var/cache/setup"
|
||||
--packages "%CYGWIN_PACKAGES%"
|
||||
)
|
||||
|
||||
before_build:
|
||||
- mkdir build
|
||||
|
||||
- if "%BUILDENV%" == "MSBUILD" (
|
||||
cd build &&
|
||||
cmake --version &&
|
||||
cmake ..
|
||||
)
|
||||
|
||||
- if "%BUILDENV%" == "MSYS2"
|
||||
"%MSYS2_ROOT%/usr/bin/bash" --login -c 'cd "${APPVEYOR_BUILD_FOLDER}/build"; cmake --version; cmake ..'
|
||||
|
||||
- if "%BUILDENV%" == "CYGWIN"
|
||||
"%CYGWIN_ROOT%/bin/bash" --login -c 'cd "${APPVEYOR_BUILD_FOLDER}/build"; cmake --version; cmake ..'
|
||||
|
||||
build_script:
|
||||
- if "%BUILDENV%" == "MSBUILD"
|
||||
msbuild "%SOLUTION%" /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
|
||||
|
||||
- if "%BUILDENV%" == "MSYS2"
|
||||
"%MSYS2_ROOT%/usr/bin/bash" --login -c 'cd "${APPVEYOR_BUILD_FOLDER}/build"; make'
|
||||
|
||||
- if "%BUILDENV%" == "CYGWIN"
|
||||
"%CYGWIN_ROOT%/bin/bash" --login -c 'cd "${APPVEYOR_BUILD_FOLDER}/build"; make'
|
11
.editorconfig
Normal file
11
.editorconfig
Normal file
@ -0,0 +1,11 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
end_of_life = lf
|
||||
charset = utf-8
|
||||
indent_style = tab
|
||||
indent_size = 2
|
||||
|
||||
[*.yml]
|
||||
indent_style = space
|
||||
indent_size = 2
|
1
.tarball-version
Normal file
1
.tarball-version
Normal file
@ -0,0 +1 @@
|
||||
v0.2.5-20180204
|
99
.travis.yml
Normal file
99
.travis.yml
Normal file
@ -0,0 +1,99 @@
|
||||
sudo: false
|
||||
language: cpp
|
||||
|
||||
matrix:
|
||||
include:
|
||||
# Linux with GNU C Compiler
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- george-edison55-precise-backports
|
||||
packages:
|
||||
- gcc
|
||||
- cmake
|
||||
- cmake-data
|
||||
- libpcsclite-dev
|
||||
|
||||
# Linux with LLVM C Compiler
|
||||
- os: linux
|
||||
compiler: clang
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- george-edison55-precise-backports
|
||||
packages:
|
||||
- clang
|
||||
- cmake
|
||||
- cmake-data
|
||||
- libpcsclite-dev
|
||||
|
||||
# ARM Raspbian (jessie)
|
||||
- os: linux
|
||||
sudo: required
|
||||
compiler: gcc
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- qemu-user-static
|
||||
- debootstrap
|
||||
env:
|
||||
- TARGET_DIST=raspbian
|
||||
- TARGET_REPO=jessie
|
||||
- TARGET_ARCH=armhf
|
||||
- TARGET_SITE=http://archive.raspbian.com/raspbian
|
||||
- TARGET_DEPS=git,cmake,libpcsclite-dev
|
||||
- QEMU_CPU=arm11mpcore
|
||||
|
||||
# MacOS X 10.10 (Yosemite)
|
||||
- os: osx
|
||||
osx_image: xcode6.4
|
||||
compiler: clang
|
||||
|
||||
# MacOS X 10.11 (El Captain)
|
||||
- os: osx
|
||||
osx_image: xcode7.3
|
||||
compiler: clang
|
||||
|
||||
# macOS 10.11 (Sierra)
|
||||
- os: osx
|
||||
osx_image: xcode8
|
||||
compiler: clang
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- ${HOME}/rootfs/${TARGET_DIST}/${TARGET_REPO}/${TARGET_ARCH}/var/cache/apt/archives
|
||||
|
||||
before_script:
|
||||
- if [ ! -z "${TARGET_DIST}" ]; then
|
||||
ROOTFS="${HOME}/rootfs/${TARGET_DIST}/${TARGET_REPO}/${TARGET_ARCH}";
|
||||
if [ ! -f "/usr/share/debootstrap/scripts/${TARGET_REPO}" ]; then
|
||||
sudo ln -s "/usr/share/debootstrap/scripts/sid" "/usr/share/debootstrap/scripts/${TARGET_REPO}";
|
||||
fi;
|
||||
sudo mkdir -p "${ROOTFS}";
|
||||
sudo qemu-debootstrap
|
||||
--no-check-gpg --variant=buildd
|
||||
--include="${TARGET_DEPS}" --arch="${TARGET_ARCH}"
|
||||
"${TARGET_REPO}" "${ROOTFS}" "${TARGET_SITE}";
|
||||
sudo mount --bind /home "${ROOTFS}/home";
|
||||
export SHELL="sudo chroot ${ROOTFS} /bin/bash";
|
||||
else
|
||||
export SHELL="/bin/bash";
|
||||
fi
|
||||
|
||||
script:
|
||||
- >
|
||||
${SHELL} -e <<EOF
|
||||
install -d "${TRAVIS_BUILD_DIR}/build"
|
||||
cd "${TRAVIS_BUILD_DIR}/build"
|
||||
cmake ..
|
||||
make VERBOSE=1
|
||||
./b25 2>&1 | grep --color=auto "ARIB STD-B25"
|
||||
if [ "${TRAVIS_OS_NAME}" != "osx" ]; then
|
||||
./libaribb25.so 2>&1 | grep --color=auto "ARIB STD-B25"
|
||||
fi
|
||||
exit
|
||||
EOF
|
146
CMakeLists.txt
Normal file
146
CMakeLists.txt
Normal file
@ -0,0 +1,146 @@
|
||||
cmake_minimum_required(VERSION 2.8.5)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
|
||||
set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE INTERNAL "limit build types" FORCE)
|
||||
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "default build type")
|
||||
|
||||
set(CMAKE_INSTALL_SO_NO_EXE False)
|
||||
|
||||
project(arib_std_b25 C)
|
||||
enable_language(CXX)
|
||||
|
||||
include(GitRevision)
|
||||
include(GenerateExportHeader)
|
||||
include(GNUInstallDirs)
|
||||
find_package(PCSC REQUIRED)
|
||||
|
||||
if (UNIX OR MSYS)
|
||||
find_program(LDCONFIG_EXECUTABLE "ldconfig")
|
||||
set(WITH_PCSC_PACKAGE "libpcsclite" CACHE STRING "pkg-config package name for PC/SC")
|
||||
set(WITH_PCSC_LIBRARY "" CACHE STRING "library name for PC/SC")
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
option(USE_UNICODE "enable unicode support" ON)
|
||||
endif()
|
||||
option(USE_AVX2 "enable AVX2" OFF)
|
||||
if(NOT WIN32)
|
||||
option(USE_NEON "enable NEON" OFF)
|
||||
endif()
|
||||
|
||||
set(ARIB25_LIB_NAME "arib25")
|
||||
set(ARIB25_CMD_NAME "b25")
|
||||
|
||||
set(ARIB25_URL "https://github.com/stz2012/libarib25")
|
||||
set(ARIB25_DESCRIPTION "Reference implementation of ARIB STD-B25")
|
||||
set(ARIB25_COMPANY "㋲製作所")
|
||||
set(ARIB25_COPYRIGHT "©2012 茂木 和洋")
|
||||
set(ARIB25_PRODUCT "ARIB STD-B25")
|
||||
|
||||
set(ARIB25_MAJOR_VERSION "0")
|
||||
set(ARIB25_MINOR_VERSION "2")
|
||||
set(ARIB25_PATCH_VERSION "5")
|
||||
set(ARIB25_VERSION_NUMBER ${ARIB25_MAJOR_VERSION}.${ARIB25_MINOR_VERSION}.${ARIB25_PATCH_VERSION})
|
||||
set(ARIB25_VERSION_STRING stz-${ARIB25_VERSION_NUMBER})
|
||||
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "(GNU|Clang)")
|
||||
set(CMAKE_C_FLAGS "-Wall")
|
||||
set(CMAKE_C_FLAGS_DEBUG "-O2 -g")
|
||||
set(CMAKE_C_FLAGS_RELEASE "-O2")
|
||||
set(CMAKE_CXX_FLAGS "-Wall")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-O3 -g")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "-fvisibility=hidden")
|
||||
|
||||
if(UNIX AND NOT CYGWIN)
|
||||
include(ElfInterp)
|
||||
set(CMAKE_C_FLAGS "-fPIC ${CMAKE_C_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "-fPIC ${CMAKE_CXX_FLAGS}")
|
||||
if(NOT APPLE)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-eshow_version")
|
||||
endif()
|
||||
else(MINGW)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--enable-stdcall-fixup -static-libgcc")
|
||||
endif()
|
||||
|
||||
if(MINGW AND USE_UNICODE)
|
||||
set(CMAKE_C_FLAGS "-municode ${CMAKE_C_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "-municode ${CMAKE_CXX_FLAGS}")
|
||||
endif()
|
||||
|
||||
if(USE_AVX2)
|
||||
set(CMAKE_C_FLAGS "-mavx2 ${CMAKE_C_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "-mavx2 ${CMAKE_CXX_FLAGS}")
|
||||
endif()
|
||||
if(USE_NEON)
|
||||
set(CMAKE_C_FLAGS "-mfpu=neon ${CMAKE_C_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "-mfpu=neon ${CMAKE_CXX_FLAGS}")
|
||||
endif()
|
||||
elseif(CMAKE_C_COMPILER_ID MATCHES "(MSVC)")
|
||||
add_definitions("-D_CRT_SECURE_NO_WARNINGS")
|
||||
set(CMAKE_STATIC_LIBRARY_PREFIX lib)
|
||||
set(CMAKE_SHARED_LIBRARY_PREFIX lib)
|
||||
set(CMAKE_SUPPRESS_REGENERATION TRUE)
|
||||
|
||||
if(USE_AVX2)
|
||||
set(CMAKE_C_FLAGS "/arch:AVX2 ${CMAKE_C_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "/arch:AVX2 ${CMAKE_CXX_FLAGS}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
add_definitions("-DDEBUG")
|
||||
endif()
|
||||
|
||||
if(USE_UNICODE)
|
||||
add_definitions("-DUNICODE" "-D_UNICODE")
|
||||
endif()
|
||||
|
||||
add_definitions("-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64")
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
if(PCSC_INCLUDE_DIRS)
|
||||
include_directories(${PCSC_INCLUDE_DIRS})
|
||||
endif()
|
||||
link_directories(${PCSC_LIBRARY_DIRS})
|
||||
|
||||
add_library(arib25-objlib OBJECT src/arib_std_b25.c src/b_cas_card.c src/multi2.cc src/ts_section_parser.c src/version.c)
|
||||
set_target_properties(arib25-objlib PROPERTIES COMPILE_DEFINITIONS ARIB25_DLL)
|
||||
|
||||
add_library(arib25-static STATIC $<TARGET_OBJECTS:arib25-objlib>)
|
||||
set_target_properties(arib25-static PROPERTIES OUTPUT_NAME ${ARIB25_LIB_NAME})
|
||||
target_link_libraries(arib25-static PRIVATE ${PCSC_LIBRARIES})
|
||||
|
||||
add_library(arib25-shared SHARED $<TARGET_OBJECTS:arib25-objlib> ${CMAKE_CURRENT_BINARY_DIR}/version.rc)
|
||||
set_target_properties(arib25-shared PROPERTIES MACOSX_RPATH ON)
|
||||
set_target_properties(arib25-shared PROPERTIES DEFINE_SYMBOL ARIB25_DLL)
|
||||
set_target_properties(arib25-shared PROPERTIES COMPILE_DEFINITIONS ARIB25_DLL)
|
||||
set_target_properties(arib25-shared PROPERTIES OUTPUT_NAME ${ARIB25_LIB_NAME})
|
||||
set_target_properties(arib25-shared PROPERTIES SOVERSION ${ARIB25_MAJOR_VERSION})
|
||||
set_target_properties(arib25-shared PROPERTIES VERSION ${ARIB25_VERSION_NUMBER})
|
||||
target_link_libraries(arib25-shared PRIVATE ${PCSC_LIBRARIES})
|
||||
generate_export_header(arib25-shared BASE_NAME arib25_api EXPORT_FILE_NAME arib25_api.h)
|
||||
|
||||
add_executable(b25 src/td.c ${CMAKE_CURRENT_BINARY_DIR}/version.rc)
|
||||
set_target_properties(b25 PROPERTIES OUTPUT_NAME ${ARIB25_CMD_NAME})
|
||||
target_link_libraries(b25 PRIVATE ${PCSC_LIBRARIES})
|
||||
target_link_libraries(b25 PRIVATE arib25-shared)
|
||||
|
||||
configure_file(src/config.h.in config.h @ONLY)
|
||||
configure_file(src/version.rc.in version.rc @ONLY)
|
||||
|
||||
if(UNIX AND NOT CYGWIN)
|
||||
configure_file(src/libarib25.pc.in ${CMAKE_SHARED_LIBRARY_PREFIX}${ARIB25_LIB_NAME}.pc @ONLY)
|
||||
|
||||
install(TARGETS b25 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
install(TARGETS arib25-static arib25-shared ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
install(FILES src/arib_std_b25.h src/b_cas_card.h src/multi2.h src/ts_section_parser.h src/portable.h ${CMAKE_CURRENT_BINARY_DIR}/arib25_api.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/arib25)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_SHARED_LIBRARY_PREFIX}${ARIB25_LIB_NAME}.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||
install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -DLDCONFIG_EXECUTABLE=${LDCONFIG_EXECUTABLE} -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/PostInstall.cmake)")
|
||||
|
||||
add_custom_target(uninstall ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Uninstall.cmake)
|
||||
elseif(WIN32)
|
||||
install(TARGETS b25 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
install(TARGETS arib25-static arib25-shared ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
install(FILES src/arib_std_b25.h src/b_cas_card.h src/multi2.h src/ts_section_parser.h src/portable.h ${CMAKE_CURRENT_BINARY_DIR}/arib25_api.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/arib25)
|
||||
add_custom_target(uninstall ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Uninstall.cmake)
|
||||
endif()
|
201
LICENSE
Normal file
201
LICENSE
Normal file
@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2012 stz2012, MARUMO Manufacturing, 2ch NoNames.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
8
NOTICE
Normal file
8
NOTICE
Normal file
@ -0,0 +1,8 @@
|
||||
stz2012 - libarib25
|
||||
|
||||
Copyright (c)2012 stz2012 <tslroom@hotmail.com>
|
||||
|
||||
This product include software from MARUMO Manufacturing libarib25 project.
|
||||
* Copyright (c)2007-2012 MOGI, Kazuhiro <kazhiro@marumo.ne.jp>; All rights reserved.
|
||||
MARUMO Manufacturing (https://www.marumo.ne.jp/)
|
||||
Special Thanks: 2ch NoNames, eternalharvest, eru.
|
@ -1687,7 +1687,7 @@ static int proc_pmt(ARIB_STD_B25_PRIVATE_DATA *prv, TS_PROGRAM *pgrm)
|
||||
head += len;
|
||||
|
||||
/* save old streams */
|
||||
tmp_old_strm = pgrm->old_strm;
|
||||
memcpy(&tmp_old_strm, &(pgrm->old_strm), sizeof(TS_STREAM_LIST));
|
||||
|
||||
/* save current streams */
|
||||
pgrm->old_strm = pgrm->streams;
|
||||
@ -2092,6 +2092,22 @@ static int proc_ecm(DECRYPTOR_ELEM *dec, B_CAS_CARD *bcas, int32_t multi2_round)
|
||||
|
||||
dec->m2->set_scramble_key(dec->m2, res.scramble_key);
|
||||
|
||||
#if defined(DEBUG)
|
||||
int i;
|
||||
fprintf(stderr, "----\n");
|
||||
fprintf(stderr, "odd: ");
|
||||
for(i=0;i<8;i++){
|
||||
fprintf(stderr, " %02x", res.scramble_key[i]);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "even:");
|
||||
for(i=8;i<16;i++){
|
||||
fprintf(stderr, " %02x", res.scramble_key[i]);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
fflush(stderr);
|
||||
#endif
|
||||
|
||||
LAST:
|
||||
if(sect.raw != NULL){
|
||||
n = dec->ecm->ret(dec->ecm, §);
|
||||
@ -2100,8 +2116,43 @@ LAST:
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
#if defined(DEBUG)
|
||||
static void dump_pts(uint8_t *src, int32_t crypt)
|
||||
{
|
||||
int32_t pts_dts_flag;
|
||||
int64_t pts,dts;
|
||||
|
||||
src += 4; // TS ヘッダ部
|
||||
src += 4; // start_code_prefix + stream_id 部
|
||||
src += 2; // packet_length 部
|
||||
|
||||
pts_dts_flag = (src[1] >> 6) & 3;
|
||||
|
||||
src += 3;
|
||||
if(pts_dts_flag & 2){
|
||||
// PTS
|
||||
pts = (src[0] >> 1) & 0x07;
|
||||
pts <<= 15;
|
||||
pts += ((src[1] << 8) + src[2]) >> 1;
|
||||
pts <<= 15;
|
||||
pts += ((src[3] << 8) + src[4]) >> 1;
|
||||
src += 5;
|
||||
}
|
||||
if(pts_dts_flag & 1){
|
||||
// DTS
|
||||
dts = (src[0] >> 1) & 0x07;
|
||||
dts <<= 15;
|
||||
dts += ((src[1] << 8) + src[2]) >> 1;
|
||||
dts <<= 15;
|
||||
dts += ((src[3] << 8) + src[4]) >> 1;
|
||||
}
|
||||
|
||||
if(pts_dts_flag == 2){
|
||||
fprintf(stderr, " key=%d, pts=%"PRId64"\n", crypt, pts/90);
|
||||
fflush(stderr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int proc_arib_std_b25(ARIB_STD_B25_PRIVATE_DATA *prv)
|
||||
{
|
||||
@ -2207,9 +2258,14 @@ static int proc_arib_std_b25(ARIB_STD_B25_PRIVATE_DATA *prv)
|
||||
}else{
|
||||
prv->map[pid].normal_packet += 1;
|
||||
}
|
||||
|
||||
if(!append_work_buffer(&(prv->dbuf), curr, unit)){
|
||||
return ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY;
|
||||
#if defined(DEBUG)
|
||||
if( (hdr.payload_unit_start_indicator != 0) && (pid == 0x111) ){
|
||||
dump_pts(curr, crypt);
|
||||
}
|
||||
#endif
|
||||
if(!append_work_buffer(&(prv->dbuf), curr, 188)){
|
||||
r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY;
|
||||
goto LAST;
|
||||
}
|
||||
|
||||
if(prv->map[pid].type == PID_MAP_TYPE_ECM){
|
||||
|
@ -1,6 +1,7 @@
|
||||
#ifndef ARIB_STD_B25_H
|
||||
#define ARIB_STD_B25_H
|
||||
|
||||
#include "arib25_api.h"
|
||||
#include "portable.h"
|
||||
#include "b_cas_card.h"
|
||||
|
||||
|
@ -8,11 +8,15 @@
|
||||
|
||||
#include <winscard.h>
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
# include <windows.h>
|
||||
# include <tchar.h>
|
||||
#else
|
||||
#define TCHAR char
|
||||
#define _tcslen strlen
|
||||
# define TCHAR char
|
||||
# define _tcslen strlen
|
||||
# if !defined(__CYGWIN__)
|
||||
# include <wintypes.h>
|
||||
# endif
|
||||
# define _tcslen strlen
|
||||
#endif
|
||||
|
||||
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
@ -171,7 +175,7 @@ static int init_b_cas_card(void *bcas)
|
||||
}
|
||||
|
||||
prv->reader = (LPTSTR)(prv->pool);
|
||||
prv->sbuf = (uint8_t *)(prv->reader + len);
|
||||
prv->sbuf = prv->pool + len;
|
||||
prv->rbuf = prv->sbuf + B_CAS_BUFFER_MAX;
|
||||
prv->id.data = (int64_t *)(prv->rbuf + B_CAS_BUFFER_MAX);
|
||||
prv->id_max = 16;
|
||||
@ -508,7 +512,7 @@ static int change_id_max(B_CAS_CARD_PRIVATE_DATA *prv, int max)
|
||||
old_pwctrl = (uint8_t *)(prv->pwc.data);
|
||||
|
||||
prv->reader = (LPTSTR)p;
|
||||
prv->sbuf = p + reader_size;
|
||||
prv->sbuf = prv->pool + reader_size;
|
||||
prv->rbuf = prv->sbuf + B_CAS_BUFFER_MAX;
|
||||
prv->id.data = (int64_t *)(prv->rbuf + B_CAS_BUFFER_MAX);
|
||||
prv->id_max = max;
|
||||
@ -549,7 +553,7 @@ static int change_pwc_max(B_CAS_CARD_PRIVATE_DATA *prv, int max)
|
||||
old_cardid = (uint8_t *)(prv->id.data);
|
||||
|
||||
prv->reader = (LPTSTR)p;
|
||||
prv->sbuf = p + reader_size;
|
||||
prv->sbuf = prv->pool + reader_size;
|
||||
prv->rbuf = prv->sbuf + B_CAS_BUFFER_MAX;
|
||||
prv->id.data = (int64_t *)(prv->rbuf + B_CAS_BUFFER_MAX);
|
||||
prv->pwc.data = (B_CAS_PWR_ON_CTRL *)(prv->id.data + prv->id_max);
|
||||
|
@ -1,6 +1,7 @@
|
||||
#ifndef B_CAS_CARD_H
|
||||
#define B_CAS_CARD_H
|
||||
|
||||
#include "arib25_api.h"
|
||||
#include "portable.h"
|
||||
|
||||
typedef struct {
|
||||
|
17
aribb25/config.h.in
Normal file
17
aribb25/config.h.in
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#define ARIB25_MAJOR_VERSION @ARIB25_MAJOR_VERSION@
|
||||
#define ARIB25_MINOR_VERSION @ARIB25_MINOR_VERSION@
|
||||
#define ARIB25_PATCH_VERSION @ARIB25_PATCH_VERSION@
|
||||
#define ARIB25_VERSION_NUMBER "@ARIB25_VERSION_NUMBER@"
|
||||
#define ARIB25_VERSION_STRING "@ARIB25_VERSION_STRING@"
|
||||
|
||||
#define BUILD_OS_NAME "@CMAKE_SYSTEM@"
|
||||
#define BUILD_CC_NAME "@CMAKE_C_COMPILER_ID@"
|
||||
#define BUILD_CC_VERSION "@CMAKE_C_COMPILER_VERSION@"
|
||||
#define BUILD_GIT_REVISION "@GIT_REVISION@"
|
||||
|
||||
#define ELF_INTERP "@ELF_INTERP@"
|
||||
|
||||
#endif /* CONFIG_H */
|
11
aribb25/libarib25.pc.in
Normal file
11
aribb25/libarib25.pc.in
Normal file
@ -0,0 +1,11 @@
|
||||
prefix=@CMAKE_INSTALL_PREFIX@
|
||||
exec_prefix=${prefix}
|
||||
libdir=${exec_prefix}/lib
|
||||
includedir=${prefix}/include
|
||||
|
||||
Name: @CMAKE_LIBRARY_PREFIX@@ARIB25_LIB_NAME@
|
||||
Description: @ARIB25_DESCRIPTION@
|
||||
URL: @ARIB25_URL@
|
||||
Version: @ARIB25_VERSION_STRING@
|
||||
Libs: -L${libdir} -l@ARIB25_LIB_NAME@
|
||||
Cflags: -I${includedir}
|
271
aribb25/multi2.cc
Normal file
271
aribb25/multi2.cc
Normal file
@ -0,0 +1,271 @@
|
||||
#include <cstddef>
|
||||
#include <new>
|
||||
|
||||
#include "multi2.h"
|
||||
#include "multi2_error_code.h"
|
||||
#include "portable.h"
|
||||
|
||||
#include "multi2_compat.h"
|
||||
#include "multi2_cipher.h"
|
||||
|
||||
namespace multi2 {
|
||||
|
||||
struct multi2 : public MULTI2 {
|
||||
uint32_t ref_count;
|
||||
uint32_t round;
|
||||
|
||||
optional<system_key_type> system_key;
|
||||
optional<iv_type> iv;
|
||||
|
||||
array<optional<data_key_type>, 2> data_key;
|
||||
array<optional<work_key_type>, 2> work_key;
|
||||
|
||||
inline void set_system_key(uint8_t *p) {
|
||||
system_key_type s;
|
||||
for (size_t i = 0; i < s.size(); ++i) {
|
||||
s[i] = load_be(p + i * 4);
|
||||
}
|
||||
system_key = s;
|
||||
}
|
||||
|
||||
inline void set_iv(uint8_t *p) {
|
||||
iv_type v;
|
||||
v[0] = load_be(p);
|
||||
v[1] = load_be(p + 4);
|
||||
iv = v;
|
||||
}
|
||||
|
||||
inline void set_work_keys(uint8_t *p) {
|
||||
array<data_key_type, 2> k;
|
||||
k[0][0] = load_be(p);
|
||||
k[0][1] = load_be(p + 4);
|
||||
k[1][0] = load_be(p + 8);
|
||||
k[1][1] = load_be(p + 12);
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (!data_key[i] || *data_key[i] != k[i]) {
|
||||
data_key[i] = k[i];
|
||||
work_key[i].reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void clear_work_keys() {
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
data_key[i].reset();
|
||||
work_key[i].reset();
|
||||
}
|
||||
}
|
||||
|
||||
inline int encrypt(int32_t type, uint8_t *b, size_t n) {
|
||||
int i = (type == 0x02);
|
||||
|
||||
if (!iv) {
|
||||
return MULTI2_ERROR_UNSET_CBC_INIT;
|
||||
}
|
||||
|
||||
if (!work_key[i]) {
|
||||
if (!system_key) {
|
||||
return MULTI2_ERROR_UNSET_SYSTEM_KEY;
|
||||
}
|
||||
if (!data_key[i]) {
|
||||
return MULTI2_ERROR_UNSET_SCRAMBLE_KEY;
|
||||
}
|
||||
work_key[i] = schedule(*data_key[i], *system_key);
|
||||
}
|
||||
|
||||
encrypt_cbc_ofb(b, n, *iv, *work_key[i], round);
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int decrypt(int32_t type, uint8_t *b, size_t n) {
|
||||
int i = (type == 0x02);
|
||||
|
||||
if (!iv) {
|
||||
return MULTI2_ERROR_UNSET_CBC_INIT;
|
||||
}
|
||||
|
||||
if (!work_key[i]) {
|
||||
if (!system_key) {
|
||||
return MULTI2_ERROR_UNSET_SYSTEM_KEY;
|
||||
}
|
||||
if (!data_key[i]) {
|
||||
return MULTI2_ERROR_UNSET_SCRAMBLE_KEY;
|
||||
}
|
||||
work_key[i] = schedule(*data_key[i], *system_key);
|
||||
}
|
||||
|
||||
decrypt_cbc_ofb(b, n, *iv, *work_key[i], round);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
function prottypes (interface method)
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
||||
static void release_multi2(void *m2);
|
||||
static int add_ref_multi2(void *m2);
|
||||
static int set_round_multi2(void *m2, int32_t val);
|
||||
static int set_system_key_multi2(void *m2, uint8_t *val);
|
||||
static int set_init_cbc_multi2(void *m2, uint8_t *val);
|
||||
static int set_scramble_key_multi2(void *m2, uint8_t *val);
|
||||
static int clear_scramble_key_multi2(void *m2);
|
||||
static int encrypt_multi2(void *m2, int32_t type, uint8_t *buf, int32_t size);
|
||||
static int decrypt_multi2(void *m2, int32_t type, uint8_t *buf, int32_t size);
|
||||
|
||||
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
global function implementation
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
||||
ARIB25_API_EXPORT MULTI2 *create_multi2()
|
||||
{
|
||||
multi2::multi2 *m2;
|
||||
try {
|
||||
m2 = new multi2::multi2();
|
||||
} catch (std::bad_alloc &e) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
m2->ref_count = 1;
|
||||
m2->round = 4;
|
||||
|
||||
MULTI2 *r = static_cast<MULTI2 *>(m2);
|
||||
r->private_data = m2;
|
||||
|
||||
r->release = release_multi2;
|
||||
r->add_ref = add_ref_multi2;
|
||||
r->set_round = set_round_multi2;
|
||||
r->set_system_key = set_system_key_multi2;
|
||||
r->set_init_cbc = set_init_cbc_multi2;
|
||||
r->set_scramble_key = set_scramble_key_multi2;
|
||||
r->clear_scramble_key = clear_scramble_key_multi2;
|
||||
r->encrypt = encrypt_multi2;
|
||||
r->decrypt = decrypt_multi2;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
function prottypes (private method)
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
||||
static multi2::multi2 *private_data(void *m2);
|
||||
|
||||
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
interface method implementation
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
||||
static void release_multi2(void *m2)
|
||||
{
|
||||
multi2::multi2 *prv = private_data(m2);
|
||||
if (!prv) {
|
||||
return;
|
||||
}
|
||||
|
||||
--prv->ref_count;
|
||||
if (!prv->ref_count) {
|
||||
delete prv;
|
||||
}
|
||||
}
|
||||
|
||||
static int add_ref_multi2(void *m2)
|
||||
{
|
||||
multi2::multi2 *prv = private_data(m2);
|
||||
if (!prv) {
|
||||
return MULTI2_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
++prv->ref_count;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_round_multi2(void *m2, int32_t val)
|
||||
{
|
||||
multi2::multi2 *prv = private_data(m2);
|
||||
if (!prv) {
|
||||
return MULTI2_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
prv->round = val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_system_key_multi2(void *m2, uint8_t *val)
|
||||
{
|
||||
multi2::multi2 *prv = private_data(m2);
|
||||
if (!prv || !val) {
|
||||
return MULTI2_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
prv->set_system_key(val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_init_cbc_multi2(void *m2, uint8_t *val)
|
||||
{
|
||||
multi2::multi2 *prv = private_data(m2);
|
||||
if (!prv || !val) {
|
||||
return MULTI2_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
prv->set_iv(val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_scramble_key_multi2(void *m2, uint8_t *val)
|
||||
{
|
||||
multi2::multi2 *prv = private_data(m2);
|
||||
if (!prv || !val) {
|
||||
return MULTI2_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
prv->set_work_keys(val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clear_scramble_key_multi2(void *m2)
|
||||
{
|
||||
multi2::multi2 *prv = private_data(m2);
|
||||
if (!prv) {
|
||||
return MULTI2_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
prv->clear_work_keys();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int encrypt_multi2(void *m2, int32_t type, uint8_t *buf, int32_t size)
|
||||
{
|
||||
multi2::multi2 *prv = private_data(m2);
|
||||
if (!prv || !buf || size < 1) {
|
||||
return MULTI2_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return prv->encrypt(type, buf, size);
|
||||
}
|
||||
|
||||
static int decrypt_multi2(void *m2, int32_t type, uint8_t *buf, int32_t size)
|
||||
{
|
||||
multi2::multi2 *prv = private_data(m2);
|
||||
if (!prv || !buf || size < 1) {
|
||||
return MULTI2_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return prv->decrypt(type, buf, size);
|
||||
}
|
||||
|
||||
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
private method implementation
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
||||
static multi2::multi2 *private_data(void *m2)
|
||||
{
|
||||
if (!m2) {
|
||||
return NULL;
|
||||
}
|
||||
MULTI2 *p = static_cast<MULTI2 *>(m2);
|
||||
multi2::multi2 *r = static_cast<multi2::multi2 *>(p->private_data);
|
||||
if (static_cast<MULTI2 *>(r) != p) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
#ifndef MULTI2_H
|
||||
#define MULTI2_H
|
||||
|
||||
#include "arib25_api.h"
|
||||
#include "portable.h"
|
||||
#include "simd_instruction_type.h"
|
||||
|
||||
|
81
aribb25/multi2_block.h
Normal file
81
aribb25/multi2_block.h
Normal file
@ -0,0 +1,81 @@
|
||||
#pragma once
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
namespace multi2 {
|
||||
|
||||
inline uint32_t load_be(const uint8_t *p) {
|
||||
return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
|
||||
}
|
||||
|
||||
inline void store_be(uint8_t *p, uint32_t v) {
|
||||
p[0] = (v >> 24) & 0xff;
|
||||
p[1] = (v >> 16) & 0xff;
|
||||
p[2] = (v >> 8) & 0xff;
|
||||
p[3] = v & 0xff;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct block {
|
||||
T left;
|
||||
T right;
|
||||
|
||||
inline block() { }
|
||||
inline block(const T &l, const T &r) : left(l), right(r) { }
|
||||
|
||||
void load(const uint8_t *p);
|
||||
void store(uint8_t *p) const;
|
||||
|
||||
block<T> operator^(const block<T> &other) const;
|
||||
|
||||
std::pair<block<T>, block<uint32_t> > cbc_post_decrypt(const block<T> &ciphertext, const block<uint32_t> &state) const;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline size_t block_size() {
|
||||
return sizeof(T) * 2;
|
||||
}
|
||||
|
||||
typedef block<uint32_t> cbc_state;;
|
||||
|
||||
template<>
|
||||
inline void block<uint32_t>::load(const uint8_t *p) {
|
||||
left = load_be(p);
|
||||
right = load_be(p + 4);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void block<uint32_t>::store(uint8_t *p) const {
|
||||
store_be(p, left);
|
||||
store_be(p + 4, right);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline block<uint32_t> block<uint32_t>::operator^(const block<uint32_t> &other) const {
|
||||
return block<uint32_t>(left ^ other.left, right ^ other.right);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::pair<block<uint32_t>, cbc_state> block<uint32_t>::cbc_post_decrypt(const block<uint32_t> &c, const cbc_state &state) const {
|
||||
block<uint32_t> p = *this ^ state;
|
||||
return std::make_pair(p, c);
|
||||
}
|
||||
|
||||
template<size_t N, typename T>
|
||||
inline T rot(const T &v) {
|
||||
return (v << N) | (v >> (32 - N));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T rot1_sub(const T &v) {
|
||||
return v + (v >> 31);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T rot1_add_dec(const T &v) {
|
||||
return rot<1>(v) + v - T(1);
|
||||
}
|
||||
|
||||
}
|
233
aribb25/multi2_cipher.h
Normal file
233
aribb25/multi2_cipher.h
Normal file
@ -0,0 +1,233 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include "multi2_block.h"
|
||||
#include "multi2_ymm2.h"
|
||||
#include "multi2_ymm.h"
|
||||
#include "multi2_xmm.h"
|
||||
#include "multi2_neon2.h"
|
||||
#include "multi2_neon.h"
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
# define MULTI2_ALWAYS_INLINE __attribute__((always_inline))
|
||||
# define MULTI2_LIKELY(x) __builtin_expect(!!(x), 1)
|
||||
#else
|
||||
# define MULTI2_ALWAYS_INLINE
|
||||
# define MULTI2_LIKELY(x) (x)
|
||||
#endif
|
||||
|
||||
namespace multi2 {
|
||||
|
||||
typedef array<uint32_t, 8> system_key_type;
|
||||
typedef array<uint32_t, 2> iv_type;
|
||||
typedef array<uint32_t, 2> data_key_type;
|
||||
typedef array<uint32_t, 8> work_key_type;
|
||||
|
||||
template<typename T>
|
||||
struct pi {
|
||||
typedef block<T> block_type;
|
||||
|
||||
static inline block_type pi1(const block_type &p) {
|
||||
return block_type(p.left, p.right ^ p.left);
|
||||
}
|
||||
|
||||
static inline block_type pi2(const block_type &p, uint32_t k1) {
|
||||
T x = p.right;
|
||||
T y = x + T(k1);
|
||||
T z = rot1_add_dec(y);
|
||||
return block_type(p.left ^ rot<4>(z) ^ z, p.right);
|
||||
}
|
||||
|
||||
static inline block_type pi3(const block_type &p, uint32_t k2, uint32_t k3) {
|
||||
T x = p.left;
|
||||
T y = x + T(k2);
|
||||
T z = rot<2>(y) + y + T(1);
|
||||
T a = rot<8>(z) ^ z;
|
||||
T b = a + T(k3);
|
||||
T c = rot1_sub(b);
|
||||
return block_type(p.left, p.right ^ rot<16>(c) ^ (c | x));
|
||||
}
|
||||
|
||||
static inline block_type pi4(const block_type &p, uint32_t k4) {
|
||||
T x = p.right;
|
||||
T y = x + T(k4);
|
||||
return block_type(p.left ^ (rot<2>(y) + y + T(1)), p.right);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct cipher {
|
||||
typedef block<T> block_type;
|
||||
typedef pi<T> p;
|
||||
|
||||
static inline block_type encrypt(const block_type &b, const work_key_type &wk, int n) {
|
||||
block_type t = b;
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
t = p::pi1(t);
|
||||
t = p::pi2(t, wk[0]);
|
||||
t = p::pi3(t, wk[1], wk[2]);
|
||||
t = p::pi4(t, wk[3]);
|
||||
t = p::pi1(t);
|
||||
t = p::pi2(t, wk[4]);
|
||||
t = p::pi3(t, wk[5], wk[6]);
|
||||
t = p::pi4(t, wk[7]);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
static inline block_type decrypt(const block_type &b, const work_key_type &wk, int n) {
|
||||
block_type t = b;
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
t = p::pi4(t, wk[7]);
|
||||
t = p::pi3(t, wk[5], wk[6]);
|
||||
t = p::pi2(t, wk[4]);
|
||||
t = p::pi1(t);
|
||||
t = p::pi4(t, wk[3]);
|
||||
t = p::pi3(t, wk[1], wk[2]);
|
||||
t = p::pi2(t, wk[0]);
|
||||
t = p::pi1(t);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
inline work_key_type schedule(const data_key_type &dk, const system_key_type &sk) {
|
||||
typedef pi<uint32_t> p;
|
||||
|
||||
block<uint32_t> a0 = p::pi1(block<uint32_t>(dk[0], dk[1]));
|
||||
block<uint32_t> a1 = p::pi2(a0, sk[0]);
|
||||
block<uint32_t> a2 = p::pi3(a1, sk[1], sk[2]);
|
||||
block<uint32_t> a3 = p::pi4(a2, sk[3]);
|
||||
block<uint32_t> a4 = p::pi1(a3);
|
||||
block<uint32_t> a5 = p::pi2(a4, sk[4]);
|
||||
block<uint32_t> a6 = p::pi3(a5, sk[5], sk[6]);
|
||||
block<uint32_t> a7 = p::pi4(a6, sk[7]);
|
||||
block<uint32_t> a8 = p::pi1(a7);
|
||||
|
||||
work_key_type w;
|
||||
w[0] = a1.left;
|
||||
w[1] = a2.right;
|
||||
w[2] = a3.left;
|
||||
w[3] = a4.right;
|
||||
w[4] = a5.left;
|
||||
w[5] = a6.right;
|
||||
w[6] = a7.left;
|
||||
w[7] = a8.right;
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
inline void encrypt_cbc_ofb(uint8_t *buf, size_t n, const iv_type &iv, const work_key_type &key, int round) {
|
||||
|
||||
cbc_state state(iv[0], iv[1]);
|
||||
|
||||
while (block_size<uint32_t>() <= n) {
|
||||
block<uint32_t> p;
|
||||
p.load(buf);
|
||||
|
||||
block<uint32_t> c = cipher<uint32_t>::encrypt(p ^ state, key, round);
|
||||
c.store(buf);
|
||||
|
||||
state = c;
|
||||
buf += block_size<uint32_t>();
|
||||
n -= block_size<uint32_t>();
|
||||
}
|
||||
if (0 < n) {
|
||||
array<uint8_t, 8> t;
|
||||
memcpy(&t[0], buf, n);
|
||||
memset(&t[n], 0, 8 - n);
|
||||
|
||||
block<uint32_t> p;
|
||||
p.load(&t[0]);
|
||||
|
||||
block<uint32_t> c = p ^ cipher<uint32_t>::encrypt(state, key, round);
|
||||
c.store(&t[0]);
|
||||
memcpy(buf, &t[0], n);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
MULTI2_ALWAYS_INLINE
|
||||
static inline void decrypt_block(uint8_t *&buf, size_t &n, cbc_state &state, const work_key_type &key, int round) {
|
||||
block<T> c;
|
||||
c.load(buf);
|
||||
|
||||
block<T> d = cipher<T>::decrypt(c, key, round);
|
||||
std::pair<block<T>, cbc_state> ps = d.cbc_post_decrypt(c, state);
|
||||
ps.first.store(buf);
|
||||
|
||||
state = ps.second;
|
||||
buf += block_size<T>();
|
||||
n -= block_size<T>();
|
||||
}
|
||||
|
||||
inline void decrypt_cbc_ofb(uint8_t *buf, size_t n, const iv_type &iv, const work_key_type &key, int round) {
|
||||
|
||||
cbc_state state(iv[0], iv[1]);
|
||||
|
||||
#if defined(__AVX2__)
|
||||
if (MULTI2_LIKELY(n == 184)) {
|
||||
decrypt_block<x86::ymm2>(buf, n, state, key, round);
|
||||
decrypt_block<x86::ymm>(buf, n, state, key, round);
|
||||
return;
|
||||
}
|
||||
if (block_size<x86::ymm2>() <= n) {
|
||||
decrypt_block<x86::ymm2>(buf, n, state, key, round);
|
||||
}
|
||||
if (block_size<x86::ymm>() <= n) {
|
||||
decrypt_block<x86::ymm>(buf, n, state, key, round);
|
||||
}
|
||||
#if defined(__SSE2__)
|
||||
if (block_size<x86::xmm>() <= n) {
|
||||
decrypt_block<x86::xmm>(buf, n, state, key, round);
|
||||
}
|
||||
#endif
|
||||
|
||||
#elif defined(__SSE2__)
|
||||
while (block_size<x86::xmm>() <= n) {
|
||||
decrypt_block<x86::xmm>(buf, n, state, key, round);
|
||||
}
|
||||
|
||||
#elif defined(__ARM_NEON__) || defined(__ARM_NEON)
|
||||
if (MULTI2_LIKELY(n == 184)) {
|
||||
decrypt_block<arm::neon2<7> >(buf, n, state, key, round);
|
||||
decrypt_block<arm::neon2<8> >(buf, n, state, key, round);
|
||||
decrypt_block<arm::neon2<8> >(buf, n, state, key, round);
|
||||
return;
|
||||
}
|
||||
while (block_size<arm::neon2<8> >() <= n) {
|
||||
decrypt_block<arm::neon2<8> >(buf, n, state, key, round);
|
||||
}
|
||||
if (block_size<arm::neon>() <= n) {
|
||||
decrypt_block<arm::neon>(buf, n, state, key, round);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
while (block_size<uint32_t>() <= n) {
|
||||
decrypt_block<uint32_t>(buf, n, state, key, round);
|
||||
}
|
||||
if (0 < n) {
|
||||
array<uint8_t, 8> t;
|
||||
memcpy(&t[0], buf, n);
|
||||
memset(&t[n], 0, 8 - n);
|
||||
|
||||
block<uint32_t> c;
|
||||
c.load(&t[0]);
|
||||
|
||||
block<uint32_t> p = c ^ cipher<uint32_t>::encrypt(state, key, round);
|
||||
p.store(&t[0]);
|
||||
memcpy(buf, &t[0], n);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#undef MULTI2_ALWAYS_INLINE
|
||||
#undef MULTI2_LIKELY
|
42
aribb25/multi2_compat.h
Normal file
42
aribb25/multi2_compat.h
Normal file
@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace multi2 {
|
||||
|
||||
template<typename T, size_t N>
|
||||
class array {
|
||||
T v[N];
|
||||
|
||||
inline const T *begin() const { return &v[0]; }
|
||||
inline const T *end() const { return &v[N]; }
|
||||
|
||||
public:
|
||||
inline size_t size() { return N; }
|
||||
|
||||
inline bool operator!=(const array &other) const {
|
||||
return !std::equal(begin(), end(), other.begin());
|
||||
}
|
||||
inline T &operator[](size_t n) { return v[n]; }
|
||||
inline const T &operator[](size_t n) const { return v[n]; }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class optional {
|
||||
T v;
|
||||
bool has;
|
||||
|
||||
public:
|
||||
inline optional() : has(false) { }
|
||||
|
||||
inline optional &operator=(const T &other) {
|
||||
v = other;
|
||||
has = true;
|
||||
return *this;
|
||||
}
|
||||
inline void reset() { has = false; }
|
||||
inline operator bool() const { return has; }
|
||||
inline T &operator*() { return v; }
|
||||
};
|
||||
|
||||
}
|
113
aribb25/multi2_neon.h
Normal file
113
aribb25/multi2_neon.h
Normal file
@ -0,0 +1,113 @@
|
||||
#pragma once
|
||||
|
||||
#if defined(__ARM_NEON__) || defined(__ARM_NEON)
|
||||
|
||||
#if !defined(__BYTE_ORDER__) || !defined(__ORDER_LITTLE_ENDIAN__) || (__BYTE_ORDER__) != (__ORDER_LITTLE_ENDIAN__)
|
||||
#error "Currently, USE_NEON is only for little-endian."
|
||||
#endif
|
||||
|
||||
#include <utility>
|
||||
#include <arm_neon.h>
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include "multi2_block.h"
|
||||
|
||||
namespace multi2 {
|
||||
|
||||
namespace arm {
|
||||
|
||||
class neon {
|
||||
private:
|
||||
uint32x4_t v;
|
||||
|
||||
public:
|
||||
inline neon() { }
|
||||
inline neon(uint32_t n) { v = vdupq_n_u32(n); }
|
||||
inline neon(const uint32x4_t &r) { v = r; }
|
||||
|
||||
inline neon &operator=(const neon &other) {
|
||||
v = other.v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline neon operator+(const neon &other) const { return vaddq_u32(v, other.v); }
|
||||
inline neon operator-(const neon &other) const { return vsubq_u32(v, other.v); }
|
||||
inline neon operator^(const neon &other) const { return veorq_u32(v, other.v); }
|
||||
inline neon operator|(const neon &other) const { return vorrq_u32(v, other.v); }
|
||||
|
||||
inline const uint32x4_t &value() const { return v; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void block<arm::neon>::load(const uint8_t *p) {
|
||||
const uint32_t *q = reinterpret_cast<const uint32_t *>(p);
|
||||
uint32x4x2_t a = vld2q_u32(q);
|
||||
|
||||
left = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(a.val[0])));
|
||||
right = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(a.val[1])));
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void block<arm::neon>::store(uint8_t *p) const {
|
||||
uint32x4_t a0 = left.value();
|
||||
uint32x4_t a1 = right.value();
|
||||
|
||||
uint32x4_t b0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(a0)));
|
||||
uint32x4_t b1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(a1)));
|
||||
|
||||
uint32_t *q = reinterpret_cast<uint32_t *>(p);
|
||||
uint32x4x2_t d = { b0, b1 };
|
||||
vst2q_u32(q, d);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::pair<block<arm::neon>, cbc_state> block<arm::neon>::cbc_post_decrypt(const block<arm::neon> &c, const cbc_state &state) const {
|
||||
uint32x4_t c0 = c.left.value(); // 3 2 1 0
|
||||
uint32x4_t c1 = c.right.value();
|
||||
|
||||
uint32_t s0 = vgetq_lane_u32(c0, 3); // 3
|
||||
uint32_t s1 = vgetq_lane_u32(c1, 3);
|
||||
|
||||
uint32x4_t b0 = vextq_u32(c0, c0, 3); // 2 1 0 3
|
||||
uint32x4_t b1 = vextq_u32(c1, c1, 3);
|
||||
|
||||
uint32x4_t x0 = vsetq_lane_u32(state.left, b0, 0); // 2 1 0 s
|
||||
uint32x4_t x1 = vsetq_lane_u32(state.right, b1, 0);
|
||||
|
||||
uint32x4_t d0 = left.value(); // 3 2 1 0
|
||||
uint32x4_t d1 = right.value();
|
||||
|
||||
uint32x4_t p0 = veorq_u32(d0, x0);
|
||||
uint32x4_t p1 = veorq_u32(d1, x1);
|
||||
|
||||
return std::make_pair(block<arm::neon>(p0, p1), cbc_state(s0, s1));
|
||||
}
|
||||
|
||||
template<int N>
|
||||
inline arm::neon rot(const arm::neon &v) {
|
||||
uint32x4_t a = v.value();
|
||||
if (N == 16) {
|
||||
return vreinterpretq_u32_u16(vrev32q_u16(vreinterpretq_u16_u32(a)));
|
||||
} else {
|
||||
return vsliq_n_u32(vshrq_n_u32(a, 32 - N), a, N);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
inline arm::neon rot1_sub<arm::neon>(const arm::neon &v) {
|
||||
uint32x4_t a = v.value();
|
||||
return vsraq_n_u32(a, a, 31);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline arm::neon rot1_add_dec<arm::neon>(const arm::neon &v) {
|
||||
uint32x4_t d = vcgeq_s32(vreinterpretq_s32_u32(v.value()), vdupq_n_s32(0));
|
||||
return v + v + v + arm::neon(d);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* __ARM_NEON__ || __ARM_NEON */
|
201
aribb25/multi2_neon2.h
Normal file
201
aribb25/multi2_neon2.h
Normal file
@ -0,0 +1,201 @@
|
||||
#pragma once
|
||||
|
||||
#if defined(__ARM_NEON__) || defined(__ARM_NEON)
|
||||
|
||||
#include <utility>
|
||||
#include <arm_neon.h>
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include "multi2_block.h"
|
||||
|
||||
namespace multi2 {
|
||||
|
||||
namespace arm {
|
||||
|
||||
template<size_t S>
|
||||
class neon2 {
|
||||
private:
|
||||
uint32x4_t v0;
|
||||
uint32x4_t v1;
|
||||
|
||||
public:
|
||||
inline neon2() { }
|
||||
inline neon2(uint32_t n) { v0 = v1 = vdupq_n_u32(n); }
|
||||
inline neon2(const uint32x4_t &r0, const uint32x4_t &r1) {
|
||||
v0 = r0;
|
||||
v1 = r1;
|
||||
}
|
||||
|
||||
inline neon2 &operator=(const neon2 &other) {
|
||||
v0 = other.v0;
|
||||
v1 = other.v1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline neon2 operator+(const neon2 &other) const {
|
||||
return neon2(vaddq_u32(v0, other.v0), vaddq_u32(v1, other.v1));
|
||||
}
|
||||
inline neon2 operator-(const neon2 &other) const {
|
||||
return neon2(vsubq_u32(v0, other.v0), vsubq_u32(v1, other.v1));
|
||||
}
|
||||
inline neon2 operator^(const neon2 &other) const {
|
||||
return neon2(veorq_u32(v0, other.v0), veorq_u32(v1, other.v1));
|
||||
}
|
||||
inline neon2 operator|(const neon2 &other) const {
|
||||
return neon2(vorrq_u32(v0, other.v0), vorrq_u32(v1, other.v1));
|
||||
}
|
||||
|
||||
inline const uint32x4_t &value0() const { return v0; }
|
||||
inline const uint32x4_t &value1() const { return v1; }
|
||||
|
||||
static inline void load_block(block<neon2> &b, const uint8_t *p) {
|
||||
size_t d = 8 - (8 - S) * 2;
|
||||
const uint32_t *q = reinterpret_cast<const uint32_t *>(p);
|
||||
uint32x4x2_t a0 = vld2q_u32(q);
|
||||
uint32x4x2_t a1 = vld2q_u32(q + d);
|
||||
|
||||
uint32x4_t b0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(a0.val[0])));
|
||||
uint32x4_t b1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(a0.val[1])));
|
||||
uint32x4_t b2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(a1.val[0])));
|
||||
uint32x4_t b3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(a1.val[1])));
|
||||
|
||||
b.left = neon2(b0, b2);
|
||||
b.right = neon2(b1, b3);
|
||||
}
|
||||
|
||||
static inline void store_block(uint8_t *p, const block<neon2> &b) {
|
||||
uint32x4_t a0 = b.left.value0();
|
||||
uint32x4_t a1 = b.right.value0();
|
||||
uint32x4_t a2 = b.left.value1();
|
||||
uint32x4_t a3 = b.right.value1();
|
||||
|
||||
uint32x4_t b0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(a0)));
|
||||
uint32x4_t b1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(a1)));
|
||||
uint32x4_t b2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(a2)));
|
||||
uint32x4_t b3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(a3)));
|
||||
|
||||
size_t d = 8 - (8 - S) * 2;
|
||||
uint32_t *q = reinterpret_cast<uint32_t *>(p);
|
||||
uint32x4x2_t e0 = { b0, b1 };
|
||||
uint32x4x2_t e1 = { b2, b3 };
|
||||
vst2q_u32(q + d, e1);
|
||||
vst2q_u32(q, e0);
|
||||
}
|
||||
|
||||
static inline std::pair<block<neon2>, cbc_state> cbc_post_decrypt(const block<neon2> &d, const block<neon2> &c, const cbc_state &state) {
|
||||
uint32x4_t c0 = c.left.value0(); // 3 2 1 0
|
||||
uint32x4_t c1 = c.right.value0();
|
||||
uint32x4_t c2 = c.left.value1(); // d c b a
|
||||
uint32x4_t c3 = c.right.value1();
|
||||
|
||||
uint32_t s2 = vgetq_lane_u32(c2, 3); // d
|
||||
uint32_t s3 = vgetq_lane_u32(c3, 3);
|
||||
|
||||
uint32x4_t b0 = vextq_u32(c0, c0, 3); // 2 1 0 3
|
||||
uint32x4_t b1 = vextq_u32(c1, c1, 3);
|
||||
uint32x4_t b2 = vextq_u32(c0, c2, 3); // c b a 3
|
||||
uint32x4_t b3 = vextq_u32(c1, c3, 3);
|
||||
|
||||
uint32x4_t x0 = vsetq_lane_u32(state.left, b0, 0); // 2 1 0 s
|
||||
uint32x4_t x1 = vsetq_lane_u32(state.right, b1, 0);
|
||||
uint32x4_t x2 = b2; // c b a 3
|
||||
uint32x4_t x3 = b3;
|
||||
|
||||
uint32x4_t d0 = d.left.value0(); // 3 2 1 0
|
||||
uint32x4_t d1 = d.right.value0();
|
||||
uint32x4_t d2 = d.left.value1(); // d c b a
|
||||
uint32x4_t d3 = d.right.value1();
|
||||
|
||||
uint32x4_t p0 = veorq_u32(d0, x0); // 3 2 1 0
|
||||
uint32x4_t p1 = veorq_u32(d1, x1);
|
||||
uint32x4_t p2 = veorq_u32(d2, x2); // d c b a?
|
||||
uint32x4_t p3 = veorq_u32(d3, x3);
|
||||
|
||||
return std::make_pair(block<neon2>(neon2(p0, p2), neon2(p1, p3)), cbc_state(s2, s3));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<>
|
||||
inline size_t block_size<arm::neon2<7> >() {
|
||||
return 56;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline size_t block_size<arm::neon2<8> >() {
|
||||
return 64;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void block<arm::neon2<7> >::load(const uint8_t *p) {
|
||||
arm::neon2<7>::load_block(*this, p);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void block<arm::neon2<8> >::load(const uint8_t *p) {
|
||||
arm::neon2<8>::load_block(*this, p);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void block<arm::neon2<7> >::store(uint8_t *p) const {
|
||||
arm::neon2<7>::store_block(p, *this);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void block<arm::neon2<8> >::store(uint8_t *p) const {
|
||||
arm::neon2<8>::store_block(p, *this);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::pair<block<arm::neon2<7> >, cbc_state> block<arm::neon2<7> >::cbc_post_decrypt(const block<arm::neon2<7> > &c, const cbc_state &state) const {
|
||||
return arm::neon2<7>::cbc_post_decrypt(*this, c, state);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::pair<block<arm::neon2<8> >, cbc_state> block<arm::neon2<8> >::cbc_post_decrypt(const block<arm::neon2<8> > &c, const cbc_state &state) const {
|
||||
return arm::neon2<8>::cbc_post_decrypt(*this, c, state);
|
||||
}
|
||||
|
||||
template<int N, size_t S>
|
||||
inline arm::neon2<S> rot(const arm::neon2<S> &v) {
|
||||
uint32x4_t a0 = v.value0();
|
||||
uint32x4_t a1 = v.value1();
|
||||
if (N == 16) {
|
||||
uint32x4_t b0 = vreinterpretq_u32_u16(vrev32q_u16(vreinterpretq_u16_u32(a0)));
|
||||
uint32x4_t b1 = vreinterpretq_u32_u16(vrev32q_u16(vreinterpretq_u16_u32(a1)));
|
||||
return arm::neon2<S>(b0, b1);
|
||||
} else {
|
||||
uint32x4_t b0 = vshrq_n_u32(a0, 32 - N);
|
||||
uint32x4_t b1 = vshrq_n_u32(a1, 32 - N);
|
||||
|
||||
uint32x4_t c0 = vsliq_n_u32(b0, a0, N);
|
||||
uint32x4_t c1 = vsliq_n_u32(b1, a1, N);
|
||||
return arm::neon2<S>(c0, c1);
|
||||
}
|
||||
}
|
||||
|
||||
template<size_t S>
|
||||
inline arm::neon2<S> rot1_sub(const arm::neon2<S> &v) {
|
||||
uint32x4_t a0 = v.value0();
|
||||
uint32x4_t a1 = v.value1();
|
||||
|
||||
uint32x4_t b0 = vsraq_n_u32(a0, a0, 31);
|
||||
uint32x4_t b1 = vsraq_n_u32(a1, a1, 31);
|
||||
return arm::neon2<S>(b0, b1);
|
||||
}
|
||||
|
||||
template<size_t S>
|
||||
inline arm::neon2<S> rot1_add_dec(const arm::neon2<S> &v) {
|
||||
uint32x4_t a0 = v.value0();
|
||||
uint32x4_t a1 = v.value1();
|
||||
|
||||
uint32x4_t d0 = vcgeq_s32(vreinterpretq_s32_u32(a0), vdupq_n_s32(0));
|
||||
uint32x4_t d1 = vcgeq_s32(vreinterpretq_s32_u32(a1), vdupq_n_s32(0));
|
||||
return v + v + v + arm::neon2<S>(d0, d1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* __ARM_NEON__ || __ARM_NEON */
|
208
aribb25/multi2_xmm.h
Normal file
208
aribb25/multi2_xmm.h
Normal file
@ -0,0 +1,208 @@
|
||||
#pragma once
|
||||
|
||||
#if defined(__SSE2__)
|
||||
|
||||
#include <utility>
|
||||
|
||||
#if defined(_WIN32)
|
||||
# include <intrin.h>
|
||||
#else
|
||||
# include <x86intrin.h>
|
||||
#endif
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include "multi2_block.h"
|
||||
|
||||
namespace multi2 {
|
||||
|
||||
namespace x86 {
|
||||
|
||||
class xmm {
|
||||
private:
|
||||
__m128i v;
|
||||
|
||||
public:
|
||||
inline xmm() {
|
||||
#if !defined(NO_MM_UNDEFINED)
|
||||
v = _mm_undefined_si128();
|
||||
#endif
|
||||
}
|
||||
inline xmm(uint32_t n) { v = _mm_set1_epi32(n); }
|
||||
inline xmm(const __m128i &r) { v = r; }
|
||||
|
||||
inline xmm &operator=(const xmm &other) {
|
||||
v = other.v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline xmm operator+(const xmm &other) const { return _mm_add_epi32(v, other.v); }
|
||||
inline xmm operator-(const xmm &other) const { return _mm_sub_epi32(v, other.v); }
|
||||
inline xmm operator^(const xmm &other) const { return _mm_xor_si128(v, other.v); }
|
||||
inline xmm operator|(const xmm &other) const { return _mm_or_si128(v, other.v); }
|
||||
inline xmm operator<<(int n) const { return _mm_slli_epi32(v, n); }
|
||||
inline xmm operator>>(int n) const { return _mm_srli_epi32(v, n); }
|
||||
|
||||
inline const __m128i &value() const { return v; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#if defined(__SSSE3__)
|
||||
|
||||
template<>
|
||||
inline void block<x86::xmm>::load(const uint8_t *p) {
|
||||
const __m128i *q = reinterpret_cast<const __m128i *>(p);
|
||||
|
||||
__m128i a0 = _mm_loadu_si128(q); // 3 2 1 0 - DCBA
|
||||
__m128i a1 = _mm_loadu_si128(q + 1); // 7 6 5 4 - DCBA
|
||||
|
||||
__m128i s = _mm_set_epi8(12, 13, 14, 15, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3);
|
||||
__m128i b0 = _mm_shuffle_epi8(a0, s); // 3 1 2 0 - ABCD
|
||||
__m128i b1 = _mm_shuffle_epi8(a1, s); // 7 5 6 4 - ABCD
|
||||
|
||||
left = _mm_unpacklo_epi32(b0, b1); // 6 2 4 0 - ABCD
|
||||
right = _mm_unpackhi_epi32(b0, b1); // 7 3 5 1 - ABCD
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void block<x86::xmm>::store(uint8_t *p) const {
|
||||
__m128i a0 = left.value(); // 6 2 4 0 - ABCD
|
||||
__m128i a1 = right.value(); // 7 3 5 1 - ABCD
|
||||
|
||||
__m128i s = _mm_set_epi8(12, 13, 14, 15, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3);
|
||||
__m128i b0 = _mm_shuffle_epi8(a0, s); // 6 4 2 0 - DCBA
|
||||
__m128i b1 = _mm_shuffle_epi8(a1, s); // 7 5 3 1 - DCBA
|
||||
|
||||
__m128i c0 = _mm_unpacklo_epi32(b0, b1); // 3 2 1 0 - DCBA
|
||||
__m128i c1 = _mm_unpackhi_epi32(b0, b1); // 7 6 5 4 - DCBA
|
||||
|
||||
__m128i *q = reinterpret_cast<__m128i *>(p);
|
||||
_mm_storeu_si128(q, c0);
|
||||
_mm_storeu_si128(q + 1, c1);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline x86::xmm rot<8, x86::xmm>(const x86::xmm &v) {
|
||||
__m128i s = _mm_set_epi8(14, 13, 12, 15, 10, 9, 8, 11, 6, 5, 4, 7, 2, 1, 0, 3);
|
||||
return _mm_shuffle_epi8(v.value(), s);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline x86::xmm rot<16, x86::xmm>(const x86::xmm &v) {
|
||||
__m128i s = _mm_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2);
|
||||
return _mm_shuffle_epi8(v.value(), s);
|
||||
}
|
||||
|
||||
#else /* __SSSE3__ */
|
||||
|
||||
template<>
|
||||
inline void block<x86::xmm>::load(const uint8_t *p) {
|
||||
const __m128i *q = reinterpret_cast<const __m128i *>(p);
|
||||
|
||||
__m128i a0 = _mm_loadu_si128(q); // 3 2 1 0
|
||||
__m128i a1 = _mm_loadu_si128(q + 1); // 7 6 5 4
|
||||
|
||||
__m128i b0 = _mm_unpacklo_epi32(a0, a1); // 5 1 4 0
|
||||
__m128i b1 = _mm_unpackhi_epi32(a0, a1); // 7 3 6 2
|
||||
|
||||
__m128i c0 = _mm_unpacklo_epi32(b0, b1); // 6 4 2 0 - DCBA
|
||||
__m128i c1 = _mm_unpackhi_epi32(b0, b1); // 7 5 3 1 - DCBA
|
||||
|
||||
__m128i d0 = _mm_shufflehi_epi16(_mm_shufflelo_epi16(c0, _MM_SHUFFLE(2, 3, 0, 1)), _MM_SHUFFLE(2, 3, 0, 1)); // BADC
|
||||
__m128i d1 = _mm_shufflehi_epi16(_mm_shufflelo_epi16(c1, _MM_SHUFFLE(2, 3, 0, 1)), _MM_SHUFFLE(2, 3, 0, 1)); // BADC
|
||||
|
||||
left = _mm_or_si128(_mm_srli_epi16(d0, 8), _mm_slli_epi16(d0, 8)); // ABCD
|
||||
right = _mm_or_si128(_mm_srli_epi16(d1, 8), _mm_slli_epi16(d1, 8)); // ABCD
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void block<x86::xmm>::store(uint8_t *p) const {
|
||||
__m128i a0 = left.value(); // ABCD
|
||||
__m128i a1 = right.value(); // ABCD
|
||||
|
||||
__m128i b0 = _mm_or_si128(_mm_srli_epi16(a0, 8), _mm_slli_epi16(a0, 8)); // BADC
|
||||
__m128i b1 = _mm_or_si128(_mm_srli_epi16(a1, 8), _mm_slli_epi16(a1, 8)); // BADC
|
||||
|
||||
__m128i c0 = _mm_shufflehi_epi16(_mm_shufflelo_epi16(b0, _MM_SHUFFLE(2, 3, 0, 1)), _MM_SHUFFLE(2, 3, 0, 1)); // 6 4 2 0 - DCBA
|
||||
__m128i c1 = _mm_shufflehi_epi16(_mm_shufflelo_epi16(b1, _MM_SHUFFLE(2, 3, 0, 1)), _MM_SHUFFLE(2, 3, 0, 1)); // 7 5 3 1 - DCBA
|
||||
|
||||
__m128i d0 = _mm_unpacklo_epi32(c0, c1); // 3 2 1 0
|
||||
__m128i d1 = _mm_unpackhi_epi32(c0, c1); // 7 6 5 4
|
||||
|
||||
__m128i *q = reinterpret_cast<__m128i *>(p);
|
||||
_mm_storeu_si128(q, d0);
|
||||
_mm_storeu_si128(q + 1, d1);
|
||||
}
|
||||
|
||||
#endif /* __SSSE3__ */
|
||||
|
||||
#if defined(__SSE4_1__)
|
||||
|
||||
template<>
|
||||
inline std::pair<block<x86::xmm>, cbc_state> block<x86::xmm>::cbc_post_decrypt(const block<x86::xmm> &c, const cbc_state &state) const {
|
||||
__m128i c0 = c.left.value(); // 3 1 2 0
|
||||
__m128i c1 = c.right.value();
|
||||
|
||||
uint32_t s0 = _mm_extract_epi32(c0, 3); // 3
|
||||
uint32_t s1 = _mm_extract_epi32(c1, 3);
|
||||
|
||||
__m128i b0 = _mm_shuffle_epi32(c0, _MM_SHUFFLE(1, 0, 2, 3)); // 2 0 1 3
|
||||
__m128i b1 = _mm_shuffle_epi32(c1, _MM_SHUFFLE(1, 0, 2, 3));
|
||||
|
||||
__m128i x0 = _mm_insert_epi32(b0, state.left, 0); // 2 0 1 s
|
||||
__m128i x1 = _mm_insert_epi32(b1, state.right, 0);
|
||||
|
||||
__m128i d0 = left.value(); // 3 1 2 0
|
||||
__m128i d1 = right.value();
|
||||
|
||||
__m128i p0 = _mm_xor_si128(d0, x0);
|
||||
__m128i p1 = _mm_xor_si128(d1, x1);
|
||||
|
||||
return std::make_pair(block<x86::xmm>(p0, p1), cbc_state(s0, s1));
|
||||
}
|
||||
|
||||
#else /* __SSE4_1__ */
|
||||
|
||||
template<>
|
||||
inline std::pair<block<x86::xmm>, cbc_state> block<x86::xmm>::cbc_post_decrypt(const block<x86::xmm> &c, const cbc_state &state) const {
|
||||
__m128i c0 = c.left.value(); // 3 1 2 0 / 3 2 1 0
|
||||
__m128i c1 = c.right.value();
|
||||
|
||||
#if defined(__SSSE3__)
|
||||
const int s = _MM_SHUFFLE(1, 0, 2, 3);
|
||||
#else
|
||||
const int s = _MM_SHUFFLE(2, 1, 0, 3);
|
||||
#endif
|
||||
__m128i b0 = _mm_shuffle_epi32(c0, s); // 2 0 1 3 / 2 1 0 3
|
||||
__m128i b1 = _mm_shuffle_epi32(c1, s);
|
||||
|
||||
uint32_t s0 = _mm_cvtsi128_si32(b0); // 3
|
||||
uint32_t s1 = _mm_cvtsi128_si32(b1);
|
||||
|
||||
__m128i i0 = _mm_cvtsi32_si128(state.left); // - - - s
|
||||
__m128i i1 = _mm_cvtsi32_si128(state.right);
|
||||
|
||||
__m128i x0 = _mm_castps_si128(_mm_move_ss(_mm_castsi128_ps(b0), _mm_castsi128_ps(i0))); // 2 0 1 s / 2 1 0 s
|
||||
__m128i x1 = _mm_castps_si128(_mm_move_ss(_mm_castsi128_ps(b1), _mm_castsi128_ps(i1)));
|
||||
|
||||
__m128i d0 = left.value(); // 3 1 2 0 / 3 2 1 0
|
||||
__m128i d1 = right.value();
|
||||
|
||||
__m128i p0 = _mm_xor_si128(d0, x0);
|
||||
__m128i p1 = _mm_xor_si128(d1, x1);
|
||||
|
||||
return std::make_pair(block<x86::xmm>(p0, p1), cbc_state(s0, s1));
|
||||
}
|
||||
|
||||
#endif /* __SSE4_1__ */
|
||||
|
||||
template<>
|
||||
inline x86::xmm rot1_add_dec<x86::xmm>(const x86::xmm &v) {
|
||||
__m128i d = _mm_cmpgt_epi32(v.value(), _mm_set1_epi32(-1));
|
||||
return v + v + v + x86::xmm(d);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* __SSE2__ */
|
140
aribb25/multi2_ymm.h
Normal file
140
aribb25/multi2_ymm.h
Normal file
@ -0,0 +1,140 @@
|
||||
#pragma once
|
||||
|
||||
#if defined(__AVX2__)
|
||||
|
||||
#include <utility>
|
||||
|
||||
#if defined(_WIN32)
|
||||
# include <intrin.h>
|
||||
#else
|
||||
# include <x86intrin.h>
|
||||
#endif
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include "multi2_block.h"
|
||||
|
||||
namespace multi2 {
|
||||
|
||||
namespace x86 {
|
||||
|
||||
class ymm {
|
||||
private:
|
||||
__m256i v;
|
||||
|
||||
public:
|
||||
inline ymm() {
|
||||
#if !defined(NO_MM_UNDEFINED)
|
||||
v = _mm256_undefined_si256();
|
||||
#endif
|
||||
}
|
||||
inline ymm(uint32_t n) { v = _mm256_set1_epi32(n); }
|
||||
inline ymm(const __m256i &r) { v = r; }
|
||||
|
||||
inline ymm &operator=(const ymm &other) {
|
||||
v = other.v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline ymm operator+(const ymm &other) const { return _mm256_add_epi32(v, other.v); }
|
||||
inline ymm operator-(const ymm &other) const { return _mm256_sub_epi32(v, other.v); }
|
||||
inline ymm operator^(const ymm &other) const { return _mm256_xor_si256(v, other.v); }
|
||||
inline ymm operator|(const ymm &other) const { return _mm256_or_si256(v, other.v); }
|
||||
inline ymm operator<<(int n) const { return _mm256_slli_epi32(v, n); }
|
||||
inline ymm operator>>(int n) const { return _mm256_srli_epi32(v, n); }
|
||||
|
||||
inline const __m256i &value() const { return v; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void block<x86::ymm>::load(const uint8_t *p) {
|
||||
const __m256i *q = reinterpret_cast<const __m256i *>(p);
|
||||
|
||||
__m256i a0 = _mm256_loadu_si256(q); // 7 6 5 4 3 2 1 0 - DCBA
|
||||
__m256i a1 = _mm256_loadu_si256(q + 1); // f e d c b a 9 8 - DCBA
|
||||
|
||||
__m256i s = _mm256_set_epi8(
|
||||
12, 13, 14, 15, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3,
|
||||
12, 13, 14, 15, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3
|
||||
);
|
||||
__m256i b0 = _mm256_shuffle_epi8(a0, s); // 7 5 6 4 3 1 2 0 - ABCD
|
||||
__m256i b1 = _mm256_shuffle_epi8(a1, s); // f d e c b 9 a 8 - ABCD
|
||||
|
||||
left = _mm256_unpacklo_epi32(b0, b1); // e 6 c 4 a 2 8 0 - ABCD
|
||||
right = _mm256_unpackhi_epi32(b0, b1); // f 7 d 5 b 3 9 1 - ABCD
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void block<x86::ymm>::store(uint8_t *p) const {
|
||||
__m256i a0 = left.value(); // e 6 c 4 a 2 8 0 - ABCD
|
||||
__m256i a1 = right.value(); // f 7 d 5 b 3 9 1 - ABCD
|
||||
|
||||
__m256i s = _mm256_set_epi8(
|
||||
12, 13, 14, 15, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3,
|
||||
12, 13, 14, 15, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3
|
||||
);
|
||||
__m256i b0 = _mm256_shuffle_epi8(a0, s); // e c 6 4 a 8 2 0 - DCBA
|
||||
__m256i b1 = _mm256_shuffle_epi8(a1, s); // f d 7 5 b 9 3 1 - DCBA
|
||||
|
||||
__m256i c0 = _mm256_unpacklo_epi32(b0, b1); // 7 6 5 4 3 2 1 0 - DCBA
|
||||
__m256i c1 = _mm256_unpackhi_epi32(b0, b1); // f e d c 7 6 5 4 - DCBA
|
||||
|
||||
__m256i *q = reinterpret_cast<__m256i *>(p);
|
||||
_mm256_storeu_si256(q, c0);
|
||||
_mm256_storeu_si256(q + 1, c1);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::pair<block<x86::ymm>, cbc_state> block<x86::ymm>::cbc_post_decrypt(const block<x86::ymm> &c, const cbc_state &state) const {
|
||||
__m256i c0 = c.left.value(); // 7 3 6 2 5 1 4 0
|
||||
__m256i c1 = c.right.value();
|
||||
|
||||
uint32_t s0 = _mm256_extract_epi32(c0, 7); // 7
|
||||
uint32_t s1 = _mm256_extract_epi32(c1, 7);
|
||||
|
||||
__m256i s = _mm256_set_epi32(5, 4, 3, 2, 1, 0, 6, 7);
|
||||
__m256i a0 = _mm256_permutevar8x32_epi32(c0, s); // 6 2 5 1 4 0 3 7
|
||||
__m256i a1 = _mm256_permutevar8x32_epi32(c1, s);
|
||||
|
||||
__m256i x0 = _mm256_insert_epi32(a0, state.left, 0); // 6 2 5 1 4 0 3 s
|
||||
__m256i x1 = _mm256_insert_epi32(a1, state.right, 0);
|
||||
|
||||
__m256i d0 = left.value(); // 7 3 6 2 5 1 4 0
|
||||
__m256i d1 = right.value();
|
||||
|
||||
__m256i p0 = _mm256_xor_si256(d0, x0);
|
||||
__m256i p1 = _mm256_xor_si256(d1, x1);
|
||||
|
||||
return std::make_pair(block<x86::ymm>(p0, p1), cbc_state(s0, s1));
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
inline x86::ymm rot<8, x86::ymm>(const x86::ymm &v) {
|
||||
__m256i s = _mm256_set_epi8(
|
||||
14, 13, 12, 15, 10, 9, 8, 11, 6, 5, 4, 7, 2, 1, 0, 3,
|
||||
14, 13, 12, 15, 10, 9, 8, 11, 6, 5, 4, 7, 2, 1, 0, 3
|
||||
);
|
||||
return _mm256_shuffle_epi8(v.value(), s);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline x86::ymm rot<16, x86::ymm>(const x86::ymm &v) {
|
||||
__m256i s = _mm256_set_epi8(
|
||||
13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2,
|
||||
13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2
|
||||
);
|
||||
return _mm256_shuffle_epi8(v.value(), s);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline x86::ymm rot1_add_dec<x86::ymm>(const x86::ymm &v) {
|
||||
__m256i d = _mm256_cmpgt_epi32(v.value(), _mm256_set1_epi32(-1));
|
||||
return v + v + v + x86::ymm(d);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* __AVX2__ */
|
192
aribb25/multi2_ymm2.h
Normal file
192
aribb25/multi2_ymm2.h
Normal file
@ -0,0 +1,192 @@
|
||||
#pragma once
|
||||
|
||||
#if defined(__AVX2__)
|
||||
|
||||
#include <utility>
|
||||
|
||||
#if defined(_WIN32)
|
||||
# include <intrin.h>
|
||||
#else
|
||||
# include <x86intrin.h>
|
||||
#endif
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include "multi2_block.h"
|
||||
|
||||
namespace multi2 {
|
||||
|
||||
namespace x86 {
|
||||
|
||||
class ymm2 {
|
||||
private:
|
||||
__m256i v0;
|
||||
__m256i v1;
|
||||
|
||||
public:
|
||||
inline ymm2() {
|
||||
#if !defined(NO_MM_UNDEFINED)
|
||||
v0 = v1 = _mm256_undefined_si256();
|
||||
#endif
|
||||
}
|
||||
inline ymm2(uint32_t n) { v0 = v1 = _mm256_set1_epi32(n); }
|
||||
inline ymm2(const __m256i &r0, const __m256i &r1) {
|
||||
v0 = r0;
|
||||
v1 = r1;
|
||||
}
|
||||
|
||||
inline ymm2 &operator=(const ymm2 &other) {
|
||||
v0 = other.v0;
|
||||
v1 = other.v1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline ymm2 operator+(const ymm2 &other) const {
|
||||
return x86::ymm2(_mm256_add_epi32(v0, other.v0), _mm256_add_epi32(v1, other.v1));
|
||||
}
|
||||
inline ymm2 operator-(const ymm2 &other) const {
|
||||
return x86::ymm2(_mm256_sub_epi32(v0, other.v0), _mm256_sub_epi32(v1, other.v1));
|
||||
}
|
||||
inline ymm2 operator^(const ymm2 &other) const {
|
||||
return x86::ymm2(_mm256_xor_si256(v0, other.v0), _mm256_xor_si256(v1, other.v1));
|
||||
}
|
||||
inline ymm2 operator|(const ymm2 &other) const {
|
||||
return x86::ymm2(_mm256_or_si256(v0, other.v0), _mm256_or_si256(v1, other.v1));
|
||||
}
|
||||
inline ymm2 operator<<(int n) const {
|
||||
return x86::ymm2(_mm256_slli_epi32(v0, n), _mm256_slli_epi32(v1, n));
|
||||
}
|
||||
inline ymm2 operator>>(int n) const {
|
||||
return x86::ymm2(_mm256_srli_epi32(v0, n), _mm256_srli_epi32(v1, n));
|
||||
}
|
||||
|
||||
inline const __m256i &value0() const { return v0; }
|
||||
inline const __m256i &value1() const { return v1; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<>
|
||||
inline size_t block_size<x86::ymm2>() {
|
||||
return 120;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void block<x86::ymm2>::load(const uint8_t *p) {
|
||||
const __m256i *q0 = reinterpret_cast<const __m256i *>(p);
|
||||
const __m256i *q1 = reinterpret_cast<const __m256i *>(p + 56);
|
||||
|
||||
__m256i a0 = _mm256_loadu_si256(q0); // 07 06 05 04 03 02 01 00 - DCBA
|
||||
__m256i a1 = _mm256_loadu_si256(q0 + 1); // 0f 0e 0d 0c 0b 0a 09 08 - DCBA
|
||||
__m256i a2 = _mm256_loadu_si256(q1); // 15 14 13 12 11 10 0f 0e - DCBA
|
||||
__m256i a3 = _mm256_loadu_si256(q1 + 1); // 1d 1c 1b 1a 19 18 17 16 - DCBA
|
||||
|
||||
__m256i s = _mm256_set_epi8(
|
||||
12, 13, 14, 15, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3,
|
||||
12, 13, 14, 15, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3
|
||||
);
|
||||
__m256i b0 = _mm256_shuffle_epi8(a0, s); // 07 05 06 04 03 01 02 00 - ABCD
|
||||
__m256i b1 = _mm256_shuffle_epi8(a1, s); // 0f 0d 0e 0c 0b 09 0a 08 - ABCD
|
||||
__m256i b2 = _mm256_shuffle_epi8(a2, s); // 15 13 14 12 11 0f 10 0e - ABCD
|
||||
__m256i b3 = _mm256_shuffle_epi8(a3, s); // 1d 1b 1c 1a 19 17 18 16 - ABCD
|
||||
|
||||
__m256i c0 = _mm256_unpacklo_epi32(b0, b1); // 0e 06 0c 04 0a 02 08 00 - ABCD
|
||||
__m256i c1 = _mm256_unpackhi_epi32(b0, b1); // 0f 07 0d 05 0b 03 09 01 - ABCD
|
||||
__m256i c2 = _mm256_unpacklo_epi32(b2, b3); // 1c 14 1a 12 18 10 16 0e - ABCD
|
||||
__m256i c3 = _mm256_unpackhi_epi32(b2, b3); // 1d 15 1b 13 19 11 17 0f - ABCD
|
||||
|
||||
left = x86::ymm2(c0, c2); // 0e 06 0c 04 0a 02 08 00 - 1c 14 1a 12 18 10 16 0e
|
||||
right = x86::ymm2(c1, c3); // 0f 07 0d 05 0b 03 09 01 - 1d 15 1b 13 19 11 17 0f
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void block<x86::ymm2>::store(uint8_t *p) const {
|
||||
__m256i a0 = left.value0(); // 0e 06 0c 04 0a 02 08 00 - ABCD
|
||||
__m256i a1 = right.value0(); // 0f 07 0d 05 0b 03 09 01 - ABCD
|
||||
__m256i a2 = left.value1(); // 1c 14 1a 12 18 10 16 -- - ABCD
|
||||
__m256i a3 = right.value1(); // 1d 15 1b 13 19 11 17 -- - ABCD
|
||||
|
||||
__m256i s = _mm256_set_epi8(
|
||||
12, 13, 14, 15, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3,
|
||||
12, 13, 14, 15, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3
|
||||
);
|
||||
__m256i b0 = _mm256_shuffle_epi8(a0, s); // 0e 0c 06 04 0a 08 02 00 - DCBA
|
||||
__m256i b1 = _mm256_shuffle_epi8(a1, s); // 0f 0d 07 05 0b 09 03 01 - DCBA
|
||||
__m256i b2 = _mm256_shuffle_epi8(a2, s); // 1c 1a 14 12 18 16 10 -- - DCBA
|
||||
__m256i b3 = _mm256_shuffle_epi8(a3, s); // 1d 1b 15 13 19 17 11 -- - DCBA
|
||||
|
||||
__m256i c0 = _mm256_unpacklo_epi32(b0, b1); // 07 06 05 04 03 02 01 00 - DCBA
|
||||
__m256i c1 = _mm256_unpackhi_epi32(b0, b1); // 0f 0e 0d 0c 07 06 05 04 - DCBA
|
||||
__m256i c2 = _mm256_unpacklo_epi32(b2, b3); // 15 14 13 12 11 10 -- -- - DCBA
|
||||
__m256i c3 = _mm256_unpackhi_epi32(b2, b3); // 1d 1c 1b 1a 19 18 17 16 - DCBA
|
||||
|
||||
__m256i *q0 = reinterpret_cast<__m256i *>(p);
|
||||
__m256i *q1 = reinterpret_cast<__m256i *>(p + 56);
|
||||
_mm256_storeu_si256(q0, c0);
|
||||
_mm256_storeu_si256(q1, c2);
|
||||
_mm256_storeu_si256(q0 + 1, c1);
|
||||
_mm256_storeu_si256(q1 + 1, c3);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::pair<block<x86::ymm2>, cbc_state> block<x86::ymm2>::cbc_post_decrypt(const block<x86::ymm2> &c, const cbc_state &state) const {
|
||||
__m256i c0 = c.left.value0(); // 7 3 6 2 5 1 4 0
|
||||
__m256i c1 = c.right.value0();
|
||||
__m256i c2 = c.left.value1(); // e a d 9 c 8 b 7
|
||||
__m256i c3 = c.right.value1();
|
||||
|
||||
uint32_t s2 = _mm256_extract_epi32(c2, 7); // e
|
||||
uint32_t s3 = _mm256_extract_epi32(c3, 7);
|
||||
|
||||
__m256i s = _mm256_set_epi32(5, 4, 3, 2, 1, 0, 6, 7);
|
||||
__m256i a0 = _mm256_permutevar8x32_epi32(c0, s); // 6 2 5 1 4 0 3 7
|
||||
__m256i a1 = _mm256_permutevar8x32_epi32(c1, s);
|
||||
__m256i a2 = _mm256_permutevar8x32_epi32(c2, s); // d 9 c 8 b 7 a e
|
||||
__m256i a3 = _mm256_permutevar8x32_epi32(c3, s);
|
||||
|
||||
__m256i x0 = _mm256_insert_epi32(a0, state.left, 0); // 6 2 5 1 4 0 3 s
|
||||
__m256i x1 = _mm256_insert_epi32(a1, state.right, 0);
|
||||
__m256i x2 = a2; // d 9 c 8 b 7 a e
|
||||
__m256i x3 = a3;
|
||||
|
||||
__m256i d0 = left.value0(); // 7 3 6 2 5 1 4 0
|
||||
__m256i d1 = right.value0();
|
||||
__m256i d2 = left.value1(); // e a d 9 c 8 b 7
|
||||
__m256i d3 = right.value1();
|
||||
|
||||
__m256i p0 = _mm256_xor_si256(d0, x0);
|
||||
__m256i p1 = _mm256_xor_si256(d1, x1);
|
||||
__m256i p2 = _mm256_xor_si256(d2, x2);
|
||||
__m256i p3 = _mm256_xor_si256(d3, x3);
|
||||
|
||||
return std::make_pair(block<x86::ymm2>(x86::ymm2(p0, p2), x86::ymm2(p1, p3)), cbc_state(s2, s3));
|
||||
}
|
||||
|
||||
template<>
|
||||
inline x86::ymm2 rot<8, x86::ymm2>(const x86::ymm2 &v) {
|
||||
__m256i s = _mm256_set_epi8(
|
||||
14, 13, 12, 15, 10, 9, 8, 11, 6, 5, 4, 7, 2, 1, 0, 3,
|
||||
14, 13, 12, 15, 10, 9, 8, 11, 6, 5, 4, 7, 2, 1, 0, 3
|
||||
);
|
||||
return x86::ymm2(_mm256_shuffle_epi8(v.value0(), s), _mm256_shuffle_epi8(v.value1(), s));
|
||||
}
|
||||
|
||||
template<>
|
||||
inline x86::ymm2 rot<16, x86::ymm2>(const x86::ymm2 &v) {
|
||||
__m256i s = _mm256_set_epi8(
|
||||
13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2,
|
||||
13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2
|
||||
);
|
||||
return x86::ymm2(_mm256_shuffle_epi8(v.value0(), s), _mm256_shuffle_epi8(v.value1(), s));
|
||||
}
|
||||
|
||||
template<>
|
||||
inline x86::ymm2 rot1_add_dec<x86::ymm2>(const x86::ymm2 &v) {
|
||||
__m256i d0 = _mm256_cmpgt_epi32(v.value0(), _mm256_set1_epi32(-1));
|
||||
__m256i d1 = _mm256_cmpgt_epi32(v.value1(), _mm256_set1_epi32(-1));
|
||||
return v + v + v + x86::ymm2(d0, d1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* __AVX2__ */
|
@ -1,6 +1,7 @@
|
||||
#ifndef TS_SECTION_PARSER_H
|
||||
#define TS_SECTION_PARSER_H
|
||||
|
||||
#include "arib25_api.h"
|
||||
#include "ts_common_types.h"
|
||||
|
||||
typedef struct {
|
||||
|
17
aribb25/version.c
Normal file
17
aribb25/version.c
Normal file
@ -0,0 +1,17 @@
|
||||
#include <stdio.h>
|
||||
#include <config.h>
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
# if !defined(__APPLE__)
|
||||
const char elf_interp[] __attribute__((section(".interp"))) = ELF_INTERP;
|
||||
# endif
|
||||
#include <unistd.h>
|
||||
|
||||
void show_version(void)
|
||||
{
|
||||
fprintf(stderr, "libaribb25.so - ARIB STD-B25 shared library version %s (%s)\n", ARIB25_VERSION_STRING, BUILD_GIT_REVISION);
|
||||
fprintf(stderr, " built with %s %s on %s\n", BUILD_CC_NAME, BUILD_CC_VERSION, BUILD_OS_NAME);
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
#endif
|
48
aribb25/version.rc.in
Normal file
48
aribb25/version.rc.in
Normal file
@ -0,0 +1,48 @@
|
||||
#include <windows.h>
|
||||
#include <config.h>
|
||||
#pragma code_page(65001)
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION @ARIB25_MAJOR_VERSION@,@ARIB25_MINOR_VERSION@,@ARIB25_PATCH_VERSION@,0
|
||||
PRODUCTVERSION @ARIB25_MAJOR_VERSION@,@ARIB25_MINOR_VERSION@,@ARIB25_PATCH_VERSION@,0
|
||||
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||
#ifdef DEBUG
|
||||
FILEFLAGS VS_FF_DEBUG | VS_FF_PRERELEASE
|
||||
#else
|
||||
FILEFLAGS 0
|
||||
#endif
|
||||
FILEOS VOS_NT_WINDOWS32
|
||||
#ifdef ARIB25_DLL
|
||||
FILETYPE VFT_DLL
|
||||
#else
|
||||
FILETYPE VFT_APP
|
||||
#endif
|
||||
FILESUBTYPE VFT2_UNKNOWN
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "080904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "@ARIB25_COMPANY@"
|
||||
VALUE "FileDescription", "@ARIB25_PRODUCT@ built with @CMAKE_C_COMPILER_ID@ @CMAKE_C_COMPILER_VERSION@ on @CMAKE_SYSTEM@"
|
||||
VALUE "FileVersion", "@ARIB25_VERSION_STRING@"
|
||||
VALUE "InternalName", "@PROJECT_NAME@"
|
||||
VALUE "LegalCopyright", "@ARIB25_COPYRIGHT@"
|
||||
#if defined(ARIB25_DLL)
|
||||
VALUE "OriginalFilename", "@CMAKE_SHARED_LIBRARY_PREFIX@@ARIB25_LIB_NAME@@CMAKE_SHARED_LIBRARY_SUFFIX@"
|
||||
#else
|
||||
VALUE "OriginalFilename", "@ARIB25_CMD_NAME@@CMAKE_EXECUTABLE_SUFFIX@"
|
||||
#endif
|
||||
#if defined(UNICODE)
|
||||
VALUE "ProductName", "@ARIB25_PRODUCT@ UNICODE"
|
||||
#else
|
||||
VALUE "ProductName", "@ARIB25_PRODUCT@"
|
||||
#endif
|
||||
VALUE "ProductVersion", "@ARIB25_VERSION_STRING@ (" BUILD_GIT_REVISION ")"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x809, 1200
|
||||
END
|
||||
END
|
19
cmake/ElfInterp.cmake
Normal file
19
cmake/ElfInterp.cmake
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
find_program(OBJCOPY_EXECUTABLE "objcopy")
|
||||
if(OBJCOPY_EXECUTABLE)
|
||||
set(ELF_INTERP_BIN ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/elf_interp)
|
||||
set(ELF_INTERP_SRC ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/elf_interp.c)
|
||||
set(ELF_INTERP_DAT ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/elf_interp.dat)
|
||||
|
||||
file(WRITE ${ELF_INTERP_SRC} "int main(int argc, char **argv) { return 0; }")
|
||||
|
||||
execute_process(COMMAND ${CMAKE_C_COMPILER} ${CMAKE_C_FLAGS} -o ${ELF_INTERP_BIN} ${ELF_INTERP_SRC})
|
||||
execute_process(COMMAND ${OBJCOPY_EXECUTABLE} -O binary --only-section=.interp ${ELF_INTERP_BIN} ${ELF_INTERP_DAT})
|
||||
|
||||
if(EXISTS ${ELF_INTERP_DAT})
|
||||
file(READ ${ELF_INTERP_DAT} ELF_INTERP)
|
||||
string(STRIP ${ELF_INTERP} ELF_INTERP)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
message(STATUS "ELF Interpreter: ${ELF_INTERP}")
|
31
cmake/FindPCSC.cmake
Normal file
31
cmake/FindPCSC.cmake
Normal file
@ -0,0 +1,31 @@
|
||||
find_package(PkgConfig)
|
||||
if(PKG_CONFIG_FOUND AND WITH_PCSC_PACKAGE AND NOT CMAKE_CROSSCOMPILING)
|
||||
if(WITH_PCSC_PACKAGE STREQUAL "libpcsclite")
|
||||
pkg_check_modules(PCSC ${WITH_PCSC_PACKAGE})
|
||||
else()
|
||||
pkg_check_modules(PCSC REQUIRED ${WITH_PCSC_PACKAGE})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT PCSC_FOUND)
|
||||
find_path(PCSC_INCLUDE_DIRS NAMES WinSCard.h winscard.h PATH_SUFFIXES PCSC)
|
||||
if(WITH_PCSC_LIBRARY)
|
||||
find_library(PCSC_LIBRARIES NAMES ${WITH_PCSC_LIBRARY})
|
||||
else()
|
||||
find_library(PCSC_LIBRARIES NAMES pcsclite PCSC WinSCard winscard)
|
||||
endif()
|
||||
|
||||
if(PCSC_LIBRARIES)
|
||||
set(PCSC_FOUND True)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT PCSC_FOUND AND NOT WITH_PCSC_LIBRARY AND WIN32)
|
||||
set(PCSC_LIBRARIES winscard)
|
||||
set(PCSC_FOUND True)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(PCSC DEFAULT_MSG PCSC_LIBRARIES)
|
||||
|
||||
mark_as_advanced(PCSC_INCLUDE_DIRS PCSC_LIBRARIES)
|
26
cmake/GitRevision.cmake
Normal file
26
cmake/GitRevision.cmake
Normal file
@ -0,0 +1,26 @@
|
||||
find_package(Git)
|
||||
if(GIT_FOUND AND IS_DIRECTORY ${CMAKE_SOURCE_DIR}/.git)
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} describe --always --tags
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE GIT_REVISION
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} diff --shortstat --exit-code --quiet
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
RESULT_VARIABLE GIT_IS_DIRTY
|
||||
)
|
||||
|
||||
if(GIT_IS_DIRTY)
|
||||
set(GIT_REVISION "${GIT_REVISION} dirty")
|
||||
endif()
|
||||
else()
|
||||
if (EXISTS ${CMAKE_SOURCE_DIR}/.tarball-version)
|
||||
file(STRINGS ${CMAKE_SOURCE_DIR}/.tarball-version GIT_REVISION LIMIT_COUNT 1)
|
||||
else()
|
||||
set(GIT_REVISION "Unknown Source")
|
||||
endif()
|
||||
set(GIT_IS_DIRTY False)
|
||||
endif()
|
7
cmake/PostInstall.cmake
Normal file
7
cmake/PostInstall.cmake
Normal file
@ -0,0 +1,7 @@
|
||||
if(LDCONFIG_EXECUTABLE)
|
||||
message(STATUS "Running: ldconfig")
|
||||
execute_process(COMMAND ${LDCONFIG_EXECUTABLE} RESULT_VARIABLE ldconfig_result)
|
||||
if (NOT ldconfig_result EQUAL 0)
|
||||
message(WARNING "ldconfig failed")
|
||||
endif()
|
||||
endif()
|
24
cmake/Uninstall.cmake
Normal file
24
cmake/Uninstall.cmake
Normal file
@ -0,0 +1,24 @@
|
||||
set(MANIFEST "${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt")
|
||||
|
||||
if(NOT EXISTS ${MANIFEST})
|
||||
message(FATAL_ERROR "Cannot find install manifest: '${MANIFEST}'")
|
||||
endif()
|
||||
|
||||
file(STRINGS ${MANIFEST} files)
|
||||
foreach(file ${files})
|
||||
if(EXISTS ${file} OR IS_SYMLINK ${file})
|
||||
message(STATUS "Removing file: '${file}'")
|
||||
|
||||
exec_program(
|
||||
${CMAKE_COMMAND} ARGS "-E remove ${file}"
|
||||
OUTPUT_VARIABLE stdout
|
||||
RETURN_VALUE result
|
||||
)
|
||||
|
||||
if(NOT "${result}" STREQUAL 0)
|
||||
message(FATAL_ERROR "Failed to remove file: '${file}'.")
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "File '${file}' does not exist.")
|
||||
endif()
|
||||
endforeach(file)
|
46
src/portable.h
Normal file
46
src/portable.h
Normal file
@ -0,0 +1,46 @@
|
||||
#ifndef PORTABLE_H
|
||||
#define PORTABLE_H
|
||||
|
||||
#if (defined(_WIN32) && defined(_MSC_VER) && _MSC_VER < 1800)
|
||||
|
||||
typedef unsigned char uint8_t;
|
||||
typedef signed char int8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef signed short int16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef signed int int32_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
typedef signed __int64 int64_t;
|
||||
|
||||
#else
|
||||
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#define _open open
|
||||
#define _close close
|
||||
#define _read read
|
||||
#define _write write
|
||||
#define _lseeki64 lseek
|
||||
#define _telli64(fd) (lseek(fd,0,SEEK_CUR))
|
||||
#define _O_BINARY (0)
|
||||
#define _O_RDONLY (O_RDONLY)
|
||||
#define _O_WRONLY (O_WRONLY)
|
||||
#define _O_SEQUENTIAL (0)
|
||||
#define _O_CREAT (O_CREAT)
|
||||
#define _O_TRUNC (O_TRUNC)
|
||||
#define _S_IREAD (S_IRUSR|S_IRGRP|S_IROTH)
|
||||
#define _S_IWRITE (S_IWUSR|S_IWGRP|S_IWOTH)
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ < 5 && !(__GNUC__ == 4 && 9 <= __GNUC_MINOR__))
|
||||
#define NO_MM_UNDEFINED
|
||||
#endif
|
||||
#if defined(__clang__) && (__clang_major__ < 4 && !(__clang_major__ == 3 && 8 <= __clang_minor__))
|
||||
#define NO_MM_UNDEFINED
|
||||
#endif
|
||||
|
||||
#endif /* PORTABLE_H */
|
441
src/td.c
Normal file
441
src/td.c
Normal file
@ -0,0 +1,441 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <config.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <io.h>
|
||||
#include <windows.h>
|
||||
#include <crtdbg.h>
|
||||
#include <tchar.h>
|
||||
#else
|
||||
#define __STDC_FORMAT_MACROS
|
||||
#define TCHAR char
|
||||
#define _T(X) X
|
||||
#define _ftprintf fprintf
|
||||
#define _ttoi atoi
|
||||
#define _tmain main
|
||||
#define _topen _open
|
||||
#include <inttypes.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include "arib_std_b25.h"
|
||||
#include "b_cas_card.h"
|
||||
|
||||
typedef struct {
|
||||
int32_t round;
|
||||
int32_t strip;
|
||||
int32_t emm;
|
||||
int32_t verbose;
|
||||
int32_t power_ctrl;
|
||||
} OPTION;
|
||||
|
||||
static void show_usage();
|
||||
static int parse_arg(OPTION *dst, int argc, TCHAR **argv);
|
||||
static void test_arib_std_b25(const TCHAR *src, const TCHAR *dst, OPTION *opt);
|
||||
static void show_bcas_power_on_control_info(B_CAS_CARD *bcas);
|
||||
|
||||
int _tmain(int argc, TCHAR **argv)
|
||||
{
|
||||
int n;
|
||||
OPTION opt;
|
||||
|
||||
#if defined(_WIN32)
|
||||
_CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
|
||||
_CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );
|
||||
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
|
||||
_CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );
|
||||
_CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
|
||||
_CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );
|
||||
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_DELAY_FREE_MEM_DF|_CRTDBG_CHECK_ALWAYS_DF|_CRTDBG_LEAK_CHECK_DF);
|
||||
#endif
|
||||
|
||||
n = parse_arg(&opt, argc, argv);
|
||||
if(n+2 > argc){
|
||||
show_usage();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
for(;n<=(argc-2);n+=2){
|
||||
test_arib_std_b25(argv[n+0], argv[n+1], &opt);
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
_CrtDumpMemoryLeaks();
|
||||
#endif
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
static void show_usage()
|
||||
{
|
||||
_ftprintf(stderr, _T("b25 - ARIB STD-B25 test program version %s (%s)\n"), _T(ARIB25_VERSION_STRING), _T(BUILD_GIT_REVISION));
|
||||
_ftprintf(stderr, _T(" built with %s %s on %s\n"), _T(BUILD_CC_NAME), _T(BUILD_CC_VERSION), _T(BUILD_OS_NAME));
|
||||
_ftprintf(stderr, _T("usage: b25 [options] src.m2t dst.m2t [more pair ..]\n"));
|
||||
_ftprintf(stderr, _T("options:\n"));
|
||||
_ftprintf(stderr, _T(" -r round (integer, default=4)\n"));
|
||||
_ftprintf(stderr, _T(" -s strip\n"));
|
||||
_ftprintf(stderr, _T(" 0: keep null(padding) stream (default)\n"));
|
||||
_ftprintf(stderr, _T(" 1: strip null stream\n"));
|
||||
_ftprintf(stderr, _T(" -m EMM\n"));
|
||||
_ftprintf(stderr, _T(" 0: ignore EMM (default)\n"));
|
||||
_ftprintf(stderr, _T(" 1: send EMM to B-CAS card\n"));
|
||||
_ftprintf(stderr, _T(" -p power_on_control_info\n"));
|
||||
_ftprintf(stderr, _T(" 0: do nothing additionally\n"));
|
||||
_ftprintf(stderr, _T(" 1: show B-CAS EMM receiving request (default)\n"));
|
||||
_ftprintf(stderr, _T(" -v verbose\n"));
|
||||
_ftprintf(stderr, _T(" 0: silent\n"));
|
||||
_ftprintf(stderr, _T(" 1: show processing status (default)\n"));
|
||||
_ftprintf(stderr, _T("\n"));
|
||||
}
|
||||
|
||||
static int parse_arg(OPTION *dst, int argc, TCHAR **argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
dst->round = 4;
|
||||
dst->strip = 0;
|
||||
dst->emm = 0;
|
||||
dst->power_ctrl = 1;
|
||||
dst->verbose = 1;
|
||||
|
||||
for(i=1;i<argc;i++){
|
||||
if(argv[i][0] != '-'){
|
||||
break;
|
||||
}
|
||||
switch(argv[i][1]){
|
||||
case 'm':
|
||||
if(argv[i][2]){
|
||||
dst->emm = _ttoi(argv[i]+2);
|
||||
}else{
|
||||
dst->emm = _ttoi(argv[i+1]);
|
||||
i += 1;
|
||||
}
|
||||
break;
|
||||
case 'p':
|
||||
if(argv[i][2]){
|
||||
dst->power_ctrl = _ttoi(argv[i]+2);
|
||||
}else{
|
||||
dst->power_ctrl = _ttoi(argv[i+1]);
|
||||
i += 1;
|
||||
}
|
||||
break;
|
||||
case 'r':
|
||||
if(argv[i][2]){
|
||||
dst->round = _ttoi(argv[i]+2);
|
||||
}else{
|
||||
dst->round = _ttoi(argv[i+1]);
|
||||
i += 1;
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
if(argv[i][2]){
|
||||
dst->strip = _ttoi(argv[i]+2);
|
||||
}else{
|
||||
dst->strip = _ttoi(argv[i+1]);
|
||||
i += 1;
|
||||
}
|
||||
break;
|
||||
case 'v':
|
||||
if(argv[i][2]){
|
||||
dst->verbose = _ttoi(argv[i]+2);
|
||||
}else{
|
||||
dst->verbose = _ttoi(argv[i+1]);
|
||||
i += 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_ftprintf(stderr, _T("error - unknown option '-%c'\n"), argv[i][1]);
|
||||
return argc;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static void test_arib_std_b25(const TCHAR *src, const TCHAR *dst, OPTION *opt)
|
||||
{
|
||||
int code,i,n,m;
|
||||
int sfd,dfd;
|
||||
|
||||
int64_t total;
|
||||
int64_t offset;
|
||||
#if defined(_WIN32)
|
||||
unsigned long tick,tock;
|
||||
#else
|
||||
struct timeval tick,tock;
|
||||
double millisec;
|
||||
#endif
|
||||
double mbps;
|
||||
|
||||
ARIB_STD_B25 *b25;
|
||||
B_CAS_CARD *bcas;
|
||||
|
||||
ARIB_STD_B25_PROGRAM_INFO pgrm;
|
||||
|
||||
uint8_t data[64*1024];
|
||||
|
||||
ARIB_STD_B25_BUFFER sbuf;
|
||||
ARIB_STD_B25_BUFFER dbuf;
|
||||
|
||||
sfd = -1;
|
||||
dfd = -1;
|
||||
b25 = NULL;
|
||||
bcas = NULL;
|
||||
|
||||
sfd = _topen(src, _O_BINARY|_O_RDONLY|_O_SEQUENTIAL);
|
||||
if(sfd < 0){
|
||||
_ftprintf(stderr, _T("error - failed on _open(%s) [src]\n"), src);
|
||||
goto LAST;
|
||||
}
|
||||
|
||||
_lseeki64(sfd, 0, SEEK_END);
|
||||
total = _telli64(sfd);
|
||||
_lseeki64(sfd, 0, SEEK_SET);
|
||||
|
||||
b25 = create_arib_std_b25();
|
||||
if(b25 == NULL){
|
||||
_ftprintf(stderr, _T("error - failed on create_arib_std_b25()\n"));
|
||||
goto LAST;
|
||||
}
|
||||
|
||||
code = b25->set_multi2_round(b25, opt->round);
|
||||
if(code < 0){
|
||||
_ftprintf(stderr, _T("error - failed on ARIB_STD_B25::set_multi2_round() : code=%d\n"), code);
|
||||
goto LAST;
|
||||
}
|
||||
|
||||
code = b25->set_strip(b25, opt->strip);
|
||||
if(code < 0){
|
||||
_ftprintf(stderr, _T("error - failed on ARIB_STD_B25::set_strip() : code=%d\n"), code);
|
||||
goto LAST;
|
||||
}
|
||||
|
||||
code = b25->set_emm_proc(b25, opt->emm);
|
||||
if(code < 0){
|
||||
_ftprintf(stderr, _T("error - failed on ARIB_STD_B25::set_emm_proc() : code=%d\n"), code);
|
||||
goto LAST;
|
||||
}
|
||||
|
||||
bcas = create_b_cas_card();
|
||||
if(bcas == NULL){
|
||||
_ftprintf(stderr, _T("error - failed on create_b_cas_card()\n"));
|
||||
goto LAST;
|
||||
}
|
||||
|
||||
code = bcas->init(bcas);
|
||||
if(code < 0){
|
||||
_ftprintf(stderr, _T("error - failed on B_CAS_CARD::init() : code=%d\n"), code);
|
||||
goto LAST;
|
||||
}
|
||||
|
||||
code = b25->set_b_cas_card(b25, bcas);
|
||||
if(code < 0){
|
||||
_ftprintf(stderr, _T("error - failed on ARIB_STD_B25::set_b_cas_card() : code=%d\n"), code);
|
||||
goto LAST;
|
||||
}
|
||||
|
||||
dfd = _topen(dst, _O_BINARY|_O_WRONLY|_O_SEQUENTIAL|_O_CREAT|_O_TRUNC, _S_IREAD|_S_IWRITE);
|
||||
if(dfd < 0){
|
||||
_ftprintf(stderr, _T("error - failed on _open(%s) [dst]\n"), dst);
|
||||
goto LAST;
|
||||
}
|
||||
|
||||
offset = 0;
|
||||
#if defined(_WIN32)
|
||||
tock = GetTickCount();
|
||||
#else
|
||||
gettimeofday(&tock, NULL);
|
||||
#endif
|
||||
while( (n = _read(sfd, data, sizeof(data))) > 0 ){
|
||||
sbuf.data = data;
|
||||
sbuf.size = n;
|
||||
|
||||
code = b25->put(b25, &sbuf);
|
||||
if(code < 0){
|
||||
_ftprintf(stderr, _T("error - failed on ARIB_STD_B25::put() : code=%d\n"), code);
|
||||
goto LAST;
|
||||
}
|
||||
|
||||
code = b25->get(b25, &dbuf);
|
||||
if(code < 0){
|
||||
_ftprintf(stderr, _T("error - failed on ARIB_STD_B25::get() : code=%d\n"), code);
|
||||
goto LAST;
|
||||
}
|
||||
|
||||
if(dbuf.size > 0){
|
||||
n = _write(dfd, dbuf.data, dbuf.size);
|
||||
if(n != dbuf.size){
|
||||
_ftprintf(stderr, _T("error failed on _write(%d)\n"), dbuf.size);
|
||||
goto LAST;
|
||||
}
|
||||
}
|
||||
|
||||
offset += sbuf.size;
|
||||
if(opt->verbose != 0){
|
||||
m = (int)((uint64_t)10000*offset/total);
|
||||
mbps = 0.0;
|
||||
#if defined(_WIN32)
|
||||
tick = GetTickCount();
|
||||
if (tick-tock > 100) {
|
||||
mbps = offset;
|
||||
mbps /= 1024;
|
||||
mbps /= (tick-tock);
|
||||
}
|
||||
#else
|
||||
gettimeofday(&tick, NULL);
|
||||
millisec = (tick.tv_sec - tock.tv_sec) * 1000;
|
||||
millisec += (tick.tv_usec - tock.tv_usec) / 1000;
|
||||
if(millisec > 100.0) {
|
||||
mbps = offset;
|
||||
mbps /= 1024;
|
||||
mbps /= millisec;
|
||||
}
|
||||
#endif
|
||||
_ftprintf(stderr, _T("\rprocessing: %2d.%02d%% [%6.2f MB/sec]"), m/100, m%100, mbps);
|
||||
}
|
||||
}
|
||||
|
||||
code = b25->flush(b25);
|
||||
if(code < 0){
|
||||
_ftprintf(stderr, _T("error - failed on ARIB_STD_B25::flush() : code=%d\n"), code);
|
||||
goto LAST;
|
||||
}
|
||||
|
||||
code = b25->get(b25, &dbuf);
|
||||
if(code < 0){
|
||||
_ftprintf(stderr, _T("error - failed on ARIB_STD_B25::get() : code=%d\n"), code);
|
||||
goto LAST;
|
||||
}
|
||||
|
||||
if(dbuf.size > 0){
|
||||
n = _write(dfd, dbuf.data, dbuf.size);
|
||||
if(n != dbuf.size){
|
||||
_ftprintf(stderr, _T("error - failed on _write(%d)\n"), dbuf.size);
|
||||
goto LAST;
|
||||
}
|
||||
}
|
||||
|
||||
if(opt->verbose != 0){
|
||||
mbps = 0.0;
|
||||
#if defined(_WIN32)
|
||||
tick = GetTickCount();
|
||||
if (tick-tock > 100) {
|
||||
mbps = offset;
|
||||
mbps /= 1024;
|
||||
mbps /= (tick-tock);
|
||||
}
|
||||
#else
|
||||
gettimeofday(&tick, NULL);
|
||||
millisec = (tick.tv_sec - tock.tv_sec) * 1000;
|
||||
millisec += (tick.tv_usec - tock.tv_usec) / 1000;
|
||||
if(millisec > 100.0) {
|
||||
mbps = offset;
|
||||
mbps /= 1024;
|
||||
mbps /= millisec;
|
||||
}
|
||||
#endif
|
||||
_ftprintf(stderr, _T("\rprocessing: finish [%6.2f MB/sec]\n"), mbps);
|
||||
fflush(stderr);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
n = b25->get_program_count(b25);
|
||||
if(n < 0){
|
||||
_ftprintf(stderr, _T("error - failed on ARIB_STD_B25::get_program_count() : code=%d\n"), code);
|
||||
goto LAST;
|
||||
}
|
||||
for(i=0;i<n;i++){
|
||||
code = b25->get_program_info(b25, &pgrm, i);
|
||||
if(code < 0){
|
||||
_ftprintf(stderr, _T("error - failed on ARIB_STD_B25::get_program_info(%d) : code=%d\n"), i, code);
|
||||
goto LAST;
|
||||
}
|
||||
if(pgrm.ecm_unpurchased_count > 0){
|
||||
_ftprintf(stderr, _T("warning - unpurchased ECM is detected\n"));
|
||||
_ftprintf(stderr, _T(" channel: %d\n"), pgrm.program_number);
|
||||
_ftprintf(stderr, _T(" unpurchased ECM count: %d\n"), pgrm.ecm_unpurchased_count);
|
||||
_ftprintf(stderr, _T(" last ECM error code: %04x\n"), pgrm.last_ecm_error_code);
|
||||
#if defined(_WIN32)
|
||||
_ftprintf(stderr, _T(" undecrypted TS packet: %I64d\n"), pgrm.undecrypted_packet_count);
|
||||
_ftprintf(stderr, _T(" total TS packet: %I64d\n"), pgrm.total_packet_count);
|
||||
#else
|
||||
_ftprintf(stderr, _T(" undecrypted TS packet: %"PRId64"\n"), pgrm.undecrypted_packet_count);
|
||||
_ftprintf(stderr, _T(" total TS packet: %"PRId64"\n"), pgrm.total_packet_count);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if(opt->power_ctrl != 0){
|
||||
show_bcas_power_on_control_info(bcas);
|
||||
}
|
||||
|
||||
LAST:
|
||||
|
||||
if(sfd >= 0){
|
||||
_close(sfd);
|
||||
sfd = -1;
|
||||
}
|
||||
|
||||
if(dfd >= 0){
|
||||
_close(dfd);
|
||||
dfd = -1;
|
||||
}
|
||||
|
||||
if(b25 != NULL){
|
||||
b25->release(b25);
|
||||
b25 = NULL;
|
||||
}
|
||||
|
||||
if(bcas != NULL){
|
||||
bcas->release(bcas);
|
||||
bcas = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void show_bcas_power_on_control_info(B_CAS_CARD *bcas)
|
||||
{
|
||||
int code;
|
||||
int i,w;
|
||||
B_CAS_PWR_ON_CTRL_INFO pwc;
|
||||
|
||||
code = bcas->get_pwr_on_ctrl(bcas, &pwc);
|
||||
if(code < 0){
|
||||
_ftprintf(stderr, _T("error - failed on B_CAS_CARD::get_pwr_on_ctrl() : code=%d\n"), code);
|
||||
return;
|
||||
}
|
||||
|
||||
if(pwc.count == 0){
|
||||
_ftprintf(stdout, _T("no EMM receiving request\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
_ftprintf(stdout, _T("total %d EMM receiving request\n"), pwc.count);
|
||||
for(i=0;i<pwc.count;i++){
|
||||
_ftprintf(stdout, _T("+ [%d] : tune "), i);
|
||||
switch(pwc.data[i].network_id){
|
||||
case 4:
|
||||
w = pwc.data[i].transport_id;
|
||||
_ftprintf(stdout, _T("BS-%d/TS-%d "), ((w >> 4) & 0x1f), (w & 7));
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
w = pwc.data[i].transport_id;
|
||||
_ftprintf(stdout, _T("ND-%d/TS-%d "), ((w >> 4) & 0x1f), (w & 7));
|
||||
break;
|
||||
default:
|
||||
_ftprintf(stdout, _T("unknown(b:0x%02x,n:0x%04x,t:0x%04x) "), pwc.data[i].broadcaster_group_id, pwc.data[i].network_id, pwc.data[i].transport_id);
|
||||
break;
|
||||
}
|
||||
_ftprintf(stdout, _T("between %04d %02d/%02d "), pwc.data[i].s_yy, pwc.data[i].s_mm, pwc.data[i].s_dd);
|
||||
_ftprintf(stdout, _T("to %04d %02d/%02d "), pwc.data[i].l_yy, pwc.data[i].l_mm, pwc.data[i].l_dd);
|
||||
_ftprintf(stdout, _T("least %d hours\n"), pwc.data[i].hold_time);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user