diff --git a/Makefile b/Makefile index 2e97c09..ba345f4 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,11 @@ # Compiler CC = gcc CFLAGS = -Wall -Wextra -Iinclude -g +LDFLAGS = + +# Coverage flags +CFLAGS_COVERAGE = -Wall -Wextra -Iinclude -g -O0 -fprofile-arcs -ftest-coverage +LDFLAGS_COVERAGE = -fprofile-arcs -ftest-coverage # Debug toggle ifeq ($(DEBUG),1) @@ -26,7 +31,11 @@ APPS = $(patsubst $(APP_DIR)/%.c, $(BIN_DIR)/%, $(APP_SRCS)) TESTS = $(patsubst $(TEST_DIR)/%.c, $(BIN_DIR)/%, $(TEST_SRCS)) # Default target -all: $(OBJ_DIR) $(BIN_DIR) $(APPS) $(TESTS) +all: $(OBJ_DIR) $(BIN_DIR) apps tests + +# Build apps and tests separately +apps: $(APPS) +tests: $(TESTS) # Compile source files $(OBJ_DIR)/%.o: $(SRC_DIR)/%.c @@ -47,8 +56,8 @@ $(OBJ_DIR): $(BIN_DIR): mkdir -p $(BIN_DIR) -# Run all tests dynamically and fail CI if any test fails -test: $(TESTS) +# Run all tests dynamically +test: tests @echo "Running all tests..." @failed=0; \ for t in $(TESTS); do \ @@ -68,8 +77,28 @@ test: $(TESTS) echo "All tests PASSED."; \ fi +# Coverage targets +coverage: clean_coverage + @echo "Building tests with coverage flags..." + $(MAKE) clean + $(MAKE) CFLAGS="$(CFLAGS_COVERAGE)" LDFLAGS="$(LDFLAGS_COVERAGE)" all + @echo "Running tests for coverage..." + $(MAKE) test + @echo "Capturing coverage..." + lcov --capture --directory . --output-file coverage.info --ignore-errors unsupported,unused + genhtml coverage.info --output-directory coverage-report + @echo "Coverage report generated: coverage-report/index.html" + +clean_coverage: + rm -f *.gcda *.gcno coverage.info + rm -rf coverage-report + +# Optional: quick badge +badge: + @coverage=$(shell lcov --summary coverage.info 2>/dev/null | awk '/lines/ {val=$$3; gsub("%","",val); print int(val)}'); \ + if [ -z "$$coverage" ]; then coverage=0; fi; \ + echo "" + # Clean clean: rm -rf $(OBJ_DIR)/*.o $(BIN_DIR)/* - -.PHONY: all clean test diff --git a/README.md b/README.md index 53ebc06..75e4f6d 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [](https://opensource.org/licenses/MIT)  + This repository implements several cryptographic standards in C. diff --git a/bin/main_128 b/bin/main_128 index 5e9c91d..b3911fd 100755 Binary files a/bin/main_128 and b/bin/main_128 differ diff --git a/bin/main_256 b/bin/main_256 index d82ab65..2cf3b85 100755 Binary files a/bin/main_256 and b/bin/main_256 differ diff --git a/bin/main_sbox_timing_256 b/bin/main_sbox_timing_256 index faf0b6a..12e4fef 100755 Binary files a/bin/main_sbox_timing_256 and b/bin/main_sbox_timing_256 differ diff --git a/bin/main_timing_256 b/bin/main_timing_256 index 0c51ec9..d0067d0 100755 Binary files a/bin/main_timing_256 and b/bin/main_timing_256 differ diff --git a/bin/test_aes_128 b/bin/test_aes_128 index 48ae0e1..a6f1bd5 100755 Binary files a/bin/test_aes_128 and b/bin/test_aes_128 differ diff --git a/bin/test_aes_192 b/bin/test_aes_192 index 508c99e..b07c00f 100755 Binary files a/bin/test_aes_192 and b/bin/test_aes_192 differ diff --git a/bin/test_aes_256 b/bin/test_aes_256 index 4078d1b..bbbb68a 100755 Binary files a/bin/test_aes_256 and b/bin/test_aes_256 differ diff --git a/bin/test_cbc b/bin/test_cbc index 943b305..a812660 100755 Binary files a/bin/test_cbc and b/bin/test_cbc differ diff --git a/bin/test_ccm b/bin/test_ccm index 509ee94..688bef5 100755 Binary files a/bin/test_ccm and b/bin/test_ccm differ diff --git a/bin/test_cfb b/bin/test_cfb index 8972acd..2c3d27d 100755 Binary files a/bin/test_cfb and b/bin/test_cfb differ diff --git a/bin/test_cmac b/bin/test_cmac index 399e5ae..31b7836 100755 Binary files a/bin/test_cmac and b/bin/test_cmac differ diff --git a/bin/test_ctr b/bin/test_ctr index 2d11a9f..c425f04 100755 Binary files a/bin/test_ctr and b/bin/test_ctr differ diff --git a/bin/test_ecb b/bin/test_ecb index 7086d73..1493baa 100755 Binary files a/bin/test_ecb and b/bin/test_ecb differ diff --git a/bin/test_gcm b/bin/test_gcm index 1b60ab3..62ae296 100755 Binary files a/bin/test_gcm and b/bin/test_gcm differ diff --git a/bin/test_gmac b/bin/test_gmac index a8acb9f..e89916a 100755 Binary files a/bin/test_gmac and b/bin/test_gmac differ diff --git a/bin/test_ofb b/bin/test_ofb index 194731d..c13a2bb 100755 Binary files a/bin/test_ofb and b/bin/test_ofb differ diff --git a/bin/test_xts b/bin/test_xts index d2e49e3..fcce89d 100755 Binary files a/bin/test_xts and b/bin/test_xts differ diff --git a/coverage-report/amber.png b/coverage-report/amber.png new file mode 100644 index 0000000..2cab170 Binary files /dev/null and b/coverage-report/amber.png differ diff --git a/coverage-report/cmd_line b/coverage-report/cmd_line new file mode 100644 index 0000000..e97e8bf --- /dev/null +++ b/coverage-report/cmd_line @@ -0,0 +1 @@ +genhtml coverage.info --output-directory coverage-report diff --git a/coverage-report/emerald.png b/coverage-report/emerald.png new file mode 100644 index 0000000..38ad4f4 Binary files /dev/null and b/coverage-report/emerald.png differ diff --git a/coverage-report/gcov.css b/coverage-report/gcov.css new file mode 100644 index 0000000..1cacc83 --- /dev/null +++ b/coverage-report/gcov.css @@ -0,0 +1,1125 @@ +/* All views: initial background and text color */ +body +{ + color: #000000; + background-color: #ffffff; +} + +/* All views: standard link format*/ +a:link +{ + color: #284fa8; + text-decoration: underline; +} + +/* All views: standard link - visited format */ +a:visited +{ + color: #00cb40; + text-decoration: underline; +} + +/* All views: standard link - activated format */ +a:active +{ + color: #ff0040; + text-decoration: underline; +} + +/* All views: main title format */ +td.title +{ + text-align: center; + padding-bottom: 10px; + font-family: sans-serif; + font-size: 20pt; + font-style: italic; + font-weight: bold; +} +/* table footnote */ +td.footnote +{ + text-align: left; + padding-left: 100px; + padding-right: 10px; + background-color: #dae7fe; /* light blue table background color */ + /* dark blue table header color + background-color: #6688d4; */ + white-space: nowrap; + font-family: sans-serif; + font-style: italic; + font-size:70%; +} +/* "Line coverage date bins" leader */ +td.subTableHeader +{ + text-align: center; + padding-bottom: 6px; + font-family: sans-serif; + font-weight: bold; + vertical-align: center; +} + +/* All views: header item format */ +td.headerItem +{ + text-align: right; + padding-right: 6px; + font-family: sans-serif; + font-weight: bold; + vertical-align: top; + white-space: nowrap; +} + +/* All views: header item value format */ +td.headerValue +{ + text-align: left; + color: #284fa8; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; +} + +/* All views: header item coverage table heading */ +td.headerCovTableHead +{ + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; +} + +/* All views: header item coverage table entry */ +td.headerCovTableEntry +{ + text-align: right; + color: #284fa8; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #dae7fe; +} + +/* All views: header item coverage table entry for high coverage rate */ +td.headerCovTableEntryHi +{ + text-align: right; + color: #000000; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #a7fc9d; +} + +/* All views: header item coverage table entry for medium coverage rate */ +td.headerCovTableEntryMed +{ + text-align: right; + color: #000000; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #ffea20; +} + +/* All views: header item coverage table entry for ow coverage rate */ +td.headerCovTableEntryLo +{ + text-align: right; + color: #000000; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #ff0000; +} + +/* All views: header legend value for legend entry */ +td.headerValueLeg +{ + text-align: left; + color: #000000; + font-family: sans-serif; + font-size: 80%; + white-space: nowrap; + padding-top: 4px; +} + +/* All views: color of horizontal ruler */ +td.ruler +{ + background-color: #6688d4; +} + +/* All views: version string format */ +td.versionInfo +{ + text-align: center; + padding-top: 2px; + font-family: sans-serif; + font-style: italic; +} + +/* Directory view/File view (all)/Test case descriptions: + table headline format */ +td.tableHead +{ + text-align: center; + color: #ffffff; + background-color: #6688d4; + font-family: sans-serif; + font-size: 120%; + font-weight: bold; + white-space: nowrap; + padding-left: 4px; + padding-right: 4px; +} + +span.tableHeadSort +{ + padding-right: 4px; +} + +/* Directory view/File view (all): filename entry format */ +td.coverFile +{ + text-align: left; + padding-left: 10px; + padding-right: 20px; + color: #284fa8; + background-color: #dae7fe; + font-family: monospace; +} + +/* Directory view/File view (all): directory name entry format */ +td.coverDirectory +{ + text-align: left; + padding-left: 10px; + padding-right: 20px; + color: #284fa8; + background-color: #b8d0ff; + font-family: monospace; +} + +/* Directory view/File view (all): filename entry format */ +td.overallOwner +{ + text-align: center; + font-weight: bold; + font-family: sans-serif; + background-color: #dae7fe; + padding-right: 10px; + padding-left: 10px; +} + +/* Directory view/File view (all): filename entry format */ +td.ownerName +{ + text-align: right; + font-style: italic; + font-family: sans-serif; + background-color: #E5DBDB; + padding-right: 10px; + padding-left: 20px; +} + +/* Directory view/File view (all): bar-graph entry format*/ +td.coverBar +{ + padding-left: 10px; + padding-right: 10px; + background-color: #dae7fe; +} + +/* Directory view/File view (all): bar-graph entry format*/ +td.owner_coverBar +{ + padding-left: 10px; + padding-right: 10px; + background-color: #E5DBDB; +} + +/* Directory view/File view (all): bar-graph outline color */ +td.coverBarOutline +{ + background-color: #000000; +} + +/* Directory view/File view (all): percentage entry for files with + high coverage rate */ +td.coverPerHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #a7fc9d; + font-weight: bold; + font-family: sans-serif; +} + +/* 'owner' entry: slightly lighter color than 'coverPerHi' */ +td.owner_coverPerHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #82E0AA; + font-weight: bold; + font-family: sans-serif; +} + +/* Directory view/File view (all): line count entry */ +td.coverNumDflt +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #dae7fe; + white-space: nowrap; + font-family: sans-serif; +} + +/* td background color and font for the 'owner' section of the table */ +td.ownerTla +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #E5DBDB; + white-space: nowrap; + font-family: sans-serif; + font-style: italic; +} + +/* Directory view/File view (all): line count entry for files with + high coverage rate */ +td.coverNumHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #a7fc9d; + white-space: nowrap; + font-family: sans-serif; +} + +td.owner_coverNumHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #82E0AA; + white-space: nowrap; + font-family: sans-serif; +} + +/* Directory view/File view (all): percentage entry for files with + medium coverage rate */ +td.coverPerMed +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #ffea20; + font-weight: bold; + font-family: sans-serif; +} + +td.owner_coverPerMed +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #F9E79F; + font-weight: bold; + font-family: sans-serif; +} + +/* Directory view/File view (all): line count entry for files with + medium coverage rate */ +td.coverNumMed +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #ffea20; + white-space: nowrap; + font-family: sans-serif; +} + +td.owner_coverNumMed +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #F9E79F; + white-space: nowrap; + font-family: sans-serif; +} + +/* Directory view/File view (all): percentage entry for files with + low coverage rate */ +td.coverPerLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #ff0000; + font-weight: bold; + font-family: sans-serif; +} + +td.owner_coverPerLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #EC7063; + font-weight: bold; + font-family: sans-serif; +} + +/* Directory view/File view (all): line count entry for files with + low coverage rate */ +td.coverNumLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #ff0000; + white-space: nowrap; + font-family: sans-serif; +} + +td.owner_coverNumLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #EC7063; + white-space: nowrap; + font-family: sans-serif; +} + +/* File view (all): "show/hide details" link format */ +a.detail:link +{ + color: #b8d0ff; + font-size:80%; +} + +/* File view (all): "show/hide details" link - visited format */ +a.detail:visited +{ + color: #b8d0ff; + font-size:80%; +} + +/* File view (all): "show/hide details" link - activated format */ +a.detail:active +{ + color: #ffffff; + font-size:80%; +} + +/* File view (detail): test name entry */ +td.testName +{ + text-align: right; + padding-right: 10px; + background-color: #dae7fe; + font-family: sans-serif; +} + +/* File view (detail): test percentage entry */ +td.testPer +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #dae7fe; + font-family: sans-serif; +} + +/* File view (detail): test lines count entry */ +td.testNum +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #dae7fe; + font-family: sans-serif; +} + +/* Test case descriptions: test name format*/ +dt +{ + font-family: sans-serif; + font-weight: bold; +} + +/* Test case descriptions: description table body */ +td.testDescription +{ + padding-top: 10px; + padding-left: 30px; + padding-bottom: 10px; + padding-right: 30px; + background-color: #dae7fe; +} + +/* Source code view: function entry */ +td.coverFn +{ + text-align: left; + padding-left: 10px; + padding-right: 20px; + color: #284fa8; + background-color: #dae7fe; + font-family: monospace; +} + +/* Source code view: function entry zero count*/ +td.coverFnLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #ff0000; + font-weight: bold; + font-family: sans-serif; +} + +/* Source code view: function entry nonzero count*/ +td.coverFnHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #dae7fe; + font-weight: bold; + font-family: sans-serif; +} + +td.coverFnAlias +{ + text-align: right; + padding-left: 10px; + padding-right: 20px; + color: #284fa8; + /* make this a slightly different color than the leader - otherwise, + otherwise the alias is hard to distinguish in the table */ + background-color: #E5DBDB; /* very light pale grey/blue */ + font-family: monospace; +} + +/* Source code view: function entry zero count*/ +td.coverFnAliasLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #EC7063; /* lighter red */ + font-family: sans-serif; +} + +/* Source code view: function entry nonzero count*/ +td.coverFnAliasHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #dae7fe; + font-weight: bold; + font-family: sans-serif; +} + +/* Source code view: source code format */ +pre.source +{ + font-family: monospace; + white-space: pre; + margin-top: 2px; +} + +/* elided/removed code */ +span.elidedSource +{ + font-family: sans-serif; + /*font-size: 8pt; */ + font-style: italic; + background-color: lightgrey; +} + +/* Source code view: line number format */ +span.lineNum +{ + background-color: #efe383; +} + +/* Source code view: line number format when there are deleted + lines in the corresponding location */ +span.lineNumWithDelete +{ + foreground-color: #efe383; + background-color: lightgrey; +} + +/* Source code view: format for Cov legend */ +span.coverLegendCov +{ + padding-left: 10px; + padding-right: 10px; + padding-bottom: 2px; + background-color: #cad7fe; +} + +/* Source code view: format for NoCov legend */ +span.coverLegendNoCov +{ + padding-left: 10px; + padding-right: 10px; + padding-bottom: 2px; + background-color: #ff6230; +} + +/* Source code view: format for the source code heading line */ +pre.sourceHeading +{ + white-space: pre; + font-family: monospace; + font-weight: bold; + margin: 0px; +} + +/* All views: header legend value for low rate */ +td.headerValueLegL +{ + font-family: sans-serif; + text-align: center; + white-space: nowrap; + padding-left: 4px; + padding-right: 2px; + background-color: #ff0000; + font-size: 80%; +} + +/* All views: header legend value for med rate */ +td.headerValueLegM +{ + font-family: sans-serif; + text-align: center; + white-space: nowrap; + padding-left: 2px; + padding-right: 2px; + background-color: #ffea20; + font-size: 80%; +} + +/* All views: header legend value for hi rate */ +td.headerValueLegH +{ + font-family: sans-serif; + text-align: center; + white-space: nowrap; + padding-left: 2px; + padding-right: 4px; + background-color: #a7fc9d; + font-size: 80%; +} + +/* All views except source code view: legend format for low coverage */ +span.coverLegendCovLo +{ + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + background-color: #ff0000; +} + +/* All views except source code view: legend format for med coverage */ +span.coverLegendCovMed +{ + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + background-color: #ffea20; +} + +/* All views except source code view: legend format for hi coverage */ +span.coverLegendCovHi +{ + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + background-color: #a7fc9d; +} + +a.branchTla:link +{ + color: #000000; +} + +a.branchTla:visited +{ + color: #000000; +} + +a.mcdcTla:link +{ + color: #000000; +} + +a.mcdcTla:visited +{ + color: #000000; +} + +/* Source code view/table entry background: format for lines classified as "Uncovered New Code (+ => 0): +Newly added code is not tested" */ +td.tlaUNC +{ + text-align: right; + background-color: #FF6230; +} +td.tlaBgUNC { + background-color: #FF6230; +} + +/* Source code view/table entry background: format for lines classified as "Uncovered New Code (+ => 0): +Newly added code is not tested" */ +span.tlaUNC +{ + text-align: left; + background-color: #FF6230; +} +span.tlaBgUNC { + background-color: #FF6230; +} +a.tlaBgUNC { + background-color: #FF6230; + color: #000000; +} + +td.headerCovTableHeadUNC { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #FF6230; +} + +/* Source code view/table entry background: format for lines classified as "Lost Baseline Coverage (1 => 0): +Unchanged code is no longer tested" */ +td.tlaLBC +{ + text-align: right; + background-color: #FF6230; +} +td.tlaBgLBC { + background-color: #FF6230; +} + +/* Source code view/table entry background: format for lines classified as "Lost Baseline Coverage (1 => 0): +Unchanged code is no longer tested" */ +span.tlaLBC +{ + text-align: left; + background-color: #FF6230; +} +span.tlaBgLBC { + background-color: #FF6230; +} +a.tlaBgLBC { + background-color: #FF6230; + color: #000000; +} + +td.headerCovTableHeadLBC { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #FF6230; +} + +/* Source code view/table entry background: format for lines classified as "Uncovered Included Code (# => 0): +Previously unused code is untested" */ +td.tlaUIC +{ + text-align: right; + background-color: #FF6230; +} +td.tlaBgUIC { + background-color: #FF6230; +} + +/* Source code view/table entry background: format for lines classified as "Uncovered Included Code (# => 0): +Previously unused code is untested" */ +span.tlaUIC +{ + text-align: left; + background-color: #FF6230; +} +span.tlaBgUIC { + background-color: #FF6230; +} +a.tlaBgUIC { + background-color: #FF6230; + color: #000000; +} + +td.headerCovTableHeadUIC { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #FF6230; +} + +/* Source code view/table entry background: format for lines classified as "Uncovered Baseline Code (0 => 0): +Unchanged code was untested before, is untested now" */ +td.tlaUBC +{ + text-align: right; + background-color: #FF6230; +} +td.tlaBgUBC { + background-color: #FF6230; +} + +/* Source code view/table entry background: format for lines classified as "Uncovered Baseline Code (0 => 0): +Unchanged code was untested before, is untested now" */ +span.tlaUBC +{ + text-align: left; + background-color: #FF6230; +} +span.tlaBgUBC { + background-color: #FF6230; +} +a.tlaBgUBC { + background-color: #FF6230; + color: #000000; +} + +td.headerCovTableHeadUBC { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #FF6230; +} + +/* Source code view/table entry background: format for lines classified as "Gained Baseline Coverage (0 => 1): +Unchanged code is tested now" */ +td.tlaGBC +{ + text-align: right; + background-color: #CAD7FE; +} +td.tlaBgGBC { + background-color: #CAD7FE; +} + +/* Source code view/table entry background: format for lines classified as "Gained Baseline Coverage (0 => 1): +Unchanged code is tested now" */ +span.tlaGBC +{ + text-align: left; + background-color: #CAD7FE; +} +span.tlaBgGBC { + background-color: #CAD7FE; +} +a.tlaBgGBC { + background-color: #CAD7FE; + color: #000000; +} + +td.headerCovTableHeadGBC { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #CAD7FE; +} + +/* Source code view/table entry background: format for lines classified as "Gained Included Coverage (# => 1): +Previously unused code is tested now" */ +td.tlaGIC +{ + text-align: right; + background-color: #CAD7FE; +} +td.tlaBgGIC { + background-color: #CAD7FE; +} + +/* Source code view/table entry background: format for lines classified as "Gained Included Coverage (# => 1): +Previously unused code is tested now" */ +span.tlaGIC +{ + text-align: left; + background-color: #CAD7FE; +} +span.tlaBgGIC { + background-color: #CAD7FE; +} +a.tlaBgGIC { + background-color: #CAD7FE; + color: #000000; +} + +td.headerCovTableHeadGIC { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #CAD7FE; +} + +/* Source code view/table entry background: format for lines classified as "Gained New Coverage (+ => 1): +Newly added code is tested" */ +td.tlaGNC +{ + text-align: right; + background-color: #CAD7FE; +} +td.tlaBgGNC { + background-color: #CAD7FE; +} + +/* Source code view/table entry background: format for lines classified as "Gained New Coverage (+ => 1): +Newly added code is tested" */ +span.tlaGNC +{ + text-align: left; + background-color: #CAD7FE; +} +span.tlaBgGNC { + background-color: #CAD7FE; +} +a.tlaBgGNC { + background-color: #CAD7FE; + color: #000000; +} + +td.headerCovTableHeadGNC { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #CAD7FE; +} + +/* Source code view/table entry background: format for lines classified as "Covered Baseline Code (1 => 1): +Unchanged code was tested before and is still tested" */ +td.tlaCBC +{ + text-align: right; + background-color: #CAD7FE; +} +td.tlaBgCBC { + background-color: #CAD7FE; +} + +/* Source code view/table entry background: format for lines classified as "Covered Baseline Code (1 => 1): +Unchanged code was tested before and is still tested" */ +span.tlaCBC +{ + text-align: left; + background-color: #CAD7FE; +} +span.tlaBgCBC { + background-color: #CAD7FE; +} +a.tlaBgCBC { + background-color: #CAD7FE; + color: #000000; +} + +td.headerCovTableHeadCBC { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #CAD7FE; +} + +/* Source code view/table entry background: format for lines classified as "Excluded Uncovered Baseline (0 => #): +Previously untested code is unused now" */ +td.tlaEUB +{ + text-align: right; + background-color: #FFFFFF; +} +td.tlaBgEUB { + background-color: #FFFFFF; +} + +/* Source code view/table entry background: format for lines classified as "Excluded Uncovered Baseline (0 => #): +Previously untested code is unused now" */ +span.tlaEUB +{ + text-align: left; + background-color: #FFFFFF; +} +span.tlaBgEUB { + background-color: #FFFFFF; +} +a.tlaBgEUB { + background-color: #FFFFFF; + color: #000000; +} + +td.headerCovTableHeadEUB { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #FFFFFF; +} + +/* Source code view/table entry background: format for lines classified as "Excluded Covered Baseline (1 => #): +Previously tested code is unused now" */ +td.tlaECB +{ + text-align: right; + background-color: #FFFFFF; +} +td.tlaBgECB { + background-color: #FFFFFF; +} + +/* Source code view/table entry background: format for lines classified as "Excluded Covered Baseline (1 => #): +Previously tested code is unused now" */ +span.tlaECB +{ + text-align: left; + background-color: #FFFFFF; +} +span.tlaBgECB { + background-color: #FFFFFF; +} +a.tlaBgECB { + background-color: #FFFFFF; + color: #000000; +} + +td.headerCovTableHeadECB { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #FFFFFF; +} + +/* Source code view/table entry background: format for lines classified as "Deleted Uncovered Baseline (0 => -): +Previously untested code has been deleted" */ +td.tlaDUB +{ + text-align: right; + background-color: #FFFFFF; +} +td.tlaBgDUB { + background-color: #FFFFFF; +} + +/* Source code view/table entry background: format for lines classified as "Deleted Uncovered Baseline (0 => -): +Previously untested code has been deleted" */ +span.tlaDUB +{ + text-align: left; + background-color: #FFFFFF; +} +span.tlaBgDUB { + background-color: #FFFFFF; +} +a.tlaBgDUB { + background-color: #FFFFFF; + color: #000000; +} + +td.headerCovTableHeadDUB { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #FFFFFF; +} + +/* Source code view/table entry background: format for lines classified as "Deleted Covered Baseline (1 => -): +Previously tested code has been deleted" */ +td.tlaDCB +{ + text-align: right; + background-color: #FFFFFF; +} +td.tlaBgDCB { + background-color: #FFFFFF; +} + +/* Source code view/table entry background: format for lines classified as "Deleted Covered Baseline (1 => -): +Previously tested code has been deleted" */ +span.tlaDCB +{ + text-align: left; + background-color: #FFFFFF; +} +span.tlaBgDCB { + background-color: #FFFFFF; +} +a.tlaBgDCB { + background-color: #FFFFFF; + color: #000000; +} + +td.headerCovTableHeadDCB { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #FFFFFF; +} + +/* Source code view: format for date/owner bin that is not hit */ +span.missBins +{ + background-color: #ff0000 /* red */ +} diff --git a/coverage-report/glass.png b/coverage-report/glass.png new file mode 100644 index 0000000..e1abc00 Binary files /dev/null and b/coverage-report/glass.png differ diff --git a/coverage-report/index-sort-f.html b/coverage-report/index-sort-f.html new file mode 100644 index 0000000..c165e29 --- /dev/null +++ b/coverage-report/index-sort-f.html @@ -0,0 +1,117 @@ + + + + +
+ +| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| + | + | + | + | + | + | + | ||
| Directory |
+ Line Coverage |
+ Function Coverage |
+ ||||||
| Rate | +Total | +Hit | +Rate | +Total | +Hit | +|||
| tests/ | +
+ |
+ 83.6 % | +590 | +493 | +92.6 % | +27 | +25 | +|
| src/ | +
+ |
+ 98.3 % | +960 | +944 | +100.0 % | +78 | +78 | +|
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| + | + | + | + | + | + | + | ||
| Directory |
+ Line Coverage |
+ Function Coverage |
+ ||||||
| Rate | +Total | +Hit | +Rate | +Total | +Hit | +|||
| tests/ | +
+ |
+ 83.6 % | +590 | +493 | +92.6 % | +27 | +25 | +|
| src/ | +
+ |
+ 98.3 % | +960 | +944 | +100.0 % | +78 | +78 | +|
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| + | + | + | + | + | + | + | ||
| Directory |
+ Line Coverage |
+ Function Coverage |
+ ||||||
| Rate | +Total | +Hit | +Rate | +Total | +Hit | +|||
| src/ | +
+ |
+ 98.3 % | +960 | +944 | +100.0 % | +78 | +78 | +|
| tests/ | +
+ |
+ 83.6 % | +590 | +493 | +92.6 % | +27 | +25 | +|
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| aes128_decrypt_block | + +46 | + + + +
| inv_mix_columns | + +414 | + + + +
| inv_shift_rows | + +460 | + + + +
| inv_sub_bytes | + +460 | + + + +
| mul | + +26496 | + + + +
| aes128_encrypt_block | + +174832 | + + + +
| mix_columns | + +1573488 | + + + +
| shift_rows | + +1748320 | + + + +
| sub_bytes | + +1748320 | + + + +
| add_round_key | + +1923658 | + + + +
| xtime | + +25175808 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| add_round_key | + +1923658 | + + + +
| aes128_decrypt_block | + +46 | + + + +
| aes128_encrypt_block | + +174832 | + + + +
| inv_mix_columns | + +414 | + + + +
| inv_shift_rows | + +460 | + + + +
| inv_sub_bytes | + +460 | + + + +
| mix_columns | + +1573488 | + + + +
| mul | + +26496 | + + + +
| shift_rows | + +1748320 | + + + +
| sub_bytes | + +1748320 | + + + +
| xtime | + +25175808 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : #include "../include/aes_128.h" + 2 : #include "../include/sbox.h" + 3 : + 4 : // Internal helpers + 5 1923658 : static void add_round_key(uint8_t state[16], const uint8_t *round_key) { + 6 32702186 : for (int i = 0; i < 16; i++) { + 7 30778528 : state[i] ^= round_key[i]; + 8 30778528 : } + 9 1923658 : } + 10 : + 11 1748320 : static void sub_bytes(uint8_t state[16], const uint8_t sbox[256]) { + 12 29721440 : for (int i = 0; i < 16; i++) { + 13 27973120 : state[i] = sbox[state[i]]; + 14 27973120 : } + 15 1748320 : } + 16 : + 17 1748320 : static void shift_rows(uint8_t state[16]) { + 18 : uint8_t tmp; + 19 : + 20 : // Row 1: shift left by 1 + 21 1748320 : tmp = state[1]; + 22 1748320 : state[1] = state[5]; + 23 1748320 : state[5] = state[9]; + 24 1748320 : state[9] = state[13]; + 25 1748320 : state[13] = tmp; + 26 : + 27 : // Row 2: shift left by 2 + 28 1748320 : tmp = state[2]; + 29 1748320 : state[2] = state[10]; + 30 1748320 : state[10] = tmp; + 31 1748320 : tmp = state[6]; + 32 1748320 : state[6] = state[14]; + 33 1748320 : state[14] = tmp; + 34 : + 35 : // Row 3: shift left by 3 (or right by 1) + 36 1748320 : tmp = state[3]; + 37 1748320 : state[3] = state[15]; + 38 1748320 : state[15] = state[11]; + 39 1748320 : state[11] = state[7]; + 40 1748320 : state[7] = tmp; + 41 1748320 : } + 42 : + 43 : // GF(2^8) multiplication by 2 + 44 25175808 : static uint8_t xtime(uint8_t x) { + 45 25175808 : return (x << 1) ^ ((x & 0x80) ? 0x1B : 0); + 46 : } + 47 : + 48 1573488 : static void mix_columns(uint8_t state[16]) { + 49 7867440 : for (int c = 0; c < 4; c++) { + 50 6293952 : uint8_t *col = &state[c * 4]; + 51 6293952 : uint8_t t = col[0] ^ col[1] ^ col[2] ^ col[3]; + 52 6293952 : uint8_t tmp0 = col[0]; + 53 6293952 : uint8_t tmp1 = col[1]; + 54 6293952 : uint8_t tmp2 = col[2]; + 55 6293952 : uint8_t tmp3 = col[3]; + 56 : + 57 6293952 : col[0] ^= t ^ xtime(tmp0 ^ tmp1); + 58 6293952 : col[1] ^= t ^ xtime(tmp1 ^ tmp2); + 59 6293952 : col[2] ^= t ^ xtime(tmp2 ^ tmp3); + 60 6293952 : col[3] ^= t ^ xtime(tmp3 ^ tmp0); + 61 6293952 : } + 62 1573488 : } + 63 : + 64 174832 : void aes128_encrypt_block(const uint8_t input[16], uint8_t output[16], const uint8_t round_keys[176], const uint8_t sbox[256]) { + 65 : uint8_t state[16]; + 66 : + 67 : // Copy input into state + 68 2972144 : for (int i = 0; i < 16; i++) { + 69 2797312 : state[i] = input[i]; + 70 2797312 : } + 71 : + 72 : // Initial round key + 73 174832 : add_round_key(state, round_keys); + 74 : + 75 : // 9 main rounds + 76 1748320 : for (int round = 1; round <= 9; round++) { + 77 1573488 : sub_bytes(state, sbox); + 78 1573488 : shift_rows(state); + 79 1573488 : mix_columns(state); + 80 1573488 : add_round_key(state, round_keys + round * 16); + 81 1573488 : } + 82 : + 83 : // Final round + 84 174832 : sub_bytes(state, sbox); + 85 174832 : shift_rows(state); + 86 174832 : add_round_key(state, round_keys + 10 * 16); + 87 : + 88 : // Copy state to output + 89 2972144 : for (int i = 0; i < 16; i++) { + 90 2797312 : output[i] = state[i]; + 91 2797312 : } + 92 174832 : } + 93 : + 94 : // Inverse ShiftRows + 95 460 : static void inv_shift_rows(uint8_t state[16]) { + 96 : uint8_t tmp; + 97 : + 98 : // Row 1: shift right by 1 + 99 460 : tmp = state[13]; + 100 460 : state[13] = state[9]; + 101 460 : state[9] = state[5]; + 102 460 : state[5] = state[1]; + 103 460 : state[1] = tmp; + 104 : + 105 : // Row 2: shift right by 2 + 106 460 : tmp = state[2]; + 107 460 : state[2] = state[10]; + 108 460 : state[10] = tmp; + 109 460 : tmp = state[6]; + 110 460 : state[6] = state[14]; + 111 460 : state[14] = tmp; + 112 : + 113 : // Row 3: shift right by 3 (or left by 1) + 114 460 : tmp = state[3]; + 115 460 : state[3] = state[7]; + 116 460 : state[7] = state[11]; + 117 460 : state[11] = state[15]; + 118 460 : state[15] = tmp; + 119 460 : } + 120 : + 121 : // GF(2^8) multiplication helper for inverse MixColumns + 122 26496 : static uint8_t mul(uint8_t a, uint8_t b) { + 123 26496 : uint8_t p = 0; + 124 : uint8_t hi_bit_set; + 125 238464 : for (int i = 0; i < 8; i++) { + 126 211968 : if (b & 1) + 127 72864 : p ^= a; + 128 211968 : hi_bit_set = a & 0x80; + 129 211968 : a <<= 1; + 130 211968 : if (hi_bit_set) + 131 105888 : a ^= 0x1b; // AES irreducible polynomial + 132 211968 : b >>= 1; + 133 211968 : } + 134 26496 : return p; + 135 : } + 136 : + 137 414 : static void inv_mix_columns(uint8_t state[16]) { + 138 2070 : for (int c = 0; c < 4; c++) { + 139 1656 : uint8_t *col = &state[c * 4]; + 140 1656 : uint8_t a0 = col[0], a1 = col[1], a2 = col[2], a3 = col[3]; + 141 : + 142 1656 : col[0] = mul(a0, 0x0e) ^ mul(a1, 0x0b) ^ mul(a2, 0x0d) ^ mul(a3, 0x09); + 143 1656 : col[1] = mul(a0, 0x09) ^ mul(a1, 0x0e) ^ mul(a2, 0x0b) ^ mul(a3, 0x0d); + 144 1656 : col[2] = mul(a0, 0x0d) ^ mul(a1, 0x09) ^ mul(a2, 0x0e) ^ mul(a3, 0x0b); + 145 1656 : col[3] = mul(a0, 0x0b) ^ mul(a1, 0x0d) ^ mul(a2, 0x09) ^ mul(a3, 0x0e); + 146 1656 : } + 147 414 : } + 148 : + 149 460 : static void inv_sub_bytes(uint8_t state[16], const uint8_t inv_sbox[256]) { + 150 7820 : for (int i = 0; i < 16; i++) { + 151 7360 : state[i] = inv_sbox[state[i]]; + 152 7360 : } + 153 460 : } + 154 : + 155 46 : void aes128_decrypt_block(const uint8_t input[16], uint8_t output[16], const uint8_t round_keys[176], const uint8_t sbox[256]) { + 156 : uint8_t state[16]; + 157 : uint8_t inv_sbox[256]; + 158 : + 159 : // Generate inverse S-box + 160 46 : initialize_inverse_sbox(sbox, inv_sbox); + 161 : + 162 : // Copy input to state + 163 782 : for (int i = 0; i < 16; i++) { + 164 736 : state[i] = input[i]; + 165 736 : } + 166 : + 167 : // Initial AddRoundKey with last round key + 168 46 : add_round_key(state, round_keys + 10 * 16); + 169 : + 170 : // 9 rounds + 171 460 : for (int round = 9; round >= 1; round--) { + 172 414 : inv_shift_rows(state); + 173 414 : inv_sub_bytes(state, inv_sbox); + 174 414 : add_round_key(state, round_keys + round * 16); + 175 414 : inv_mix_columns(state); + 176 414 : } + 177 : + 178 : // Final round + 179 46 : inv_shift_rows(state); + 180 46 : inv_sub_bytes(state, inv_sbox); + 181 46 : add_round_key(state, round_keys); + 182 : + 183 : // Copy state to output + 184 782 : for (int i = 0; i < 16; i++) { + 185 736 : output[i] = state[i]; + 186 736 : } + 187 46 : } + 188 : ++ |
+
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| aes192_decrypt_block | + +4 | + + + +
| inv_mix_columns | + +44 | + + + +
| inv_shift_rows | + +48 | + + + +
| inv_sub_bytes | + +48 | + + + +
| mul | + +2816 | + + + +
| aes192_encrypt_block | + +175142 | + + + +
| mix_columns | + +1926562 | + + + +
| shift_rows | + +2101704 | + + + +
| sub_bytes | + +2101704 | + + + +
| add_round_key | + +2276898 | + + + +
| xtime | + +30824992 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| add_round_key | + +2276898 | + + + +
| aes192_decrypt_block | + +4 | + + + +
| aes192_encrypt_block | + +175142 | + + + +
| inv_mix_columns | + +44 | + + + +
| inv_shift_rows | + +48 | + + + +
| inv_sub_bytes | + +48 | + + + +
| mix_columns | + +1926562 | + + + +
| mul | + +2816 | + + + +
| shift_rows | + +2101704 | + + + +
| sub_bytes | + +2101704 | + + + +
| xtime | + +30824992 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : #include "../include/aes_192.h" + 2 : #include "../include/sbox.h" + 3 : + 4 : // Internal helpers (reused from AES-128) + 5 2276898 : static void add_round_key(uint8_t state[16], const uint8_t *round_key) { + 6 38707266 : for (int i = 0; i < 16; i++) { + 7 36430368 : state[i] ^= round_key[i]; + 8 36430368 : } + 9 2276898 : } + 10 : + 11 2101704 : static void sub_bytes(uint8_t state[16], const uint8_t sbox[256]) { + 12 35728968 : for (int i = 0; i < 16; i++) { + 13 33627264 : state[i] = sbox[state[i]]; + 14 33627264 : } + 15 2101704 : } + 16 : + 17 2101704 : static void shift_rows(uint8_t state[16]) { + 18 : uint8_t tmp; + 19 : + 20 : // Row 1: shift left by 1 + 21 2101704 : tmp = state[1]; + 22 2101704 : state[1] = state[5]; + 23 2101704 : state[5] = state[9]; + 24 2101704 : state[9] = state[13]; + 25 2101704 : state[13] = tmp; + 26 : + 27 : // Row 2: shift left by 2 + 28 2101704 : tmp = state[2]; + 29 2101704 : state[2] = state[10]; + 30 2101704 : state[10] = tmp; + 31 2101704 : tmp = state[6]; + 32 2101704 : state[6] = state[14]; + 33 2101704 : state[14] = tmp; + 34 : + 35 : // Row 3: shift left by 3 + 36 2101704 : tmp = state[3]; + 37 2101704 : state[3] = state[15]; + 38 2101704 : state[15] = state[11]; + 39 2101704 : state[11] = state[7]; + 40 2101704 : state[7] = tmp; + 41 2101704 : } + 42 : + 43 30824992 : static uint8_t xtime(uint8_t x) { + 44 30824992 : return (x << 1) ^ ((x & 0x80) ? 0x1B : 0); + 45 : } + 46 : + 47 1926562 : static void mix_columns(uint8_t state[16]) { + 48 9632810 : for (int c = 0; c < 4; c++) { + 49 7706248 : uint8_t *col = &state[c * 4]; + 50 7706248 : uint8_t t = col[0] ^ col[1] ^ col[2] ^ col[3]; + 51 7706248 : uint8_t tmp0 = col[0]; + 52 7706248 : uint8_t tmp1 = col[1]; + 53 7706248 : uint8_t tmp2 = col[2]; + 54 7706248 : uint8_t tmp3 = col[3]; + 55 : + 56 7706248 : col[0] ^= t ^ xtime(tmp0 ^ tmp1); + 57 7706248 : col[1] ^= t ^ xtime(tmp1 ^ tmp2); + 58 7706248 : col[2] ^= t ^ xtime(tmp2 ^ tmp3); + 59 7706248 : col[3] ^= t ^ xtime(tmp3 ^ tmp0); + 60 7706248 : } + 61 1926562 : } + 62 : + 63 : // AES-192 Encryption (12 rounds) + 64 175142 : void aes192_encrypt_block(const uint8_t input[16], uint8_t output[16], + 65 : const uint8_t round_keys[208], const uint8_t sbox[256]) { + 66 : uint8_t state[16]; + 67 : + 68 : // Copy input to state + 69 2977414 : for (int i = 0; i < 16; i++) { + 70 2802272 : state[i] = input[i]; + 71 2802272 : } + 72 : + 73 : // Initial round key + 74 175142 : add_round_key(state, round_keys); + 75 : + 76 : // 11 main rounds + 77 2101704 : for (int round = 1; round <= 11; round++) { + 78 1926562 : sub_bytes(state, sbox); + 79 1926562 : shift_rows(state); + 80 1926562 : mix_columns(state); + 81 1926562 : add_round_key(state, round_keys + round * 16); + 82 1926562 : } + 83 : + 84 : // Final round (no MixColumns) + 85 175142 : sub_bytes(state, sbox); + 86 175142 : shift_rows(state); + 87 175142 : add_round_key(state, round_keys + 12 * 16); + 88 : + 89 : // Copy state to output + 90 2977414 : for (int i = 0; i < 16; i++) { + 91 2802272 : output[i] = state[i]; + 92 2802272 : } + 93 175142 : } + 94 : + 95 : // Inverse operations for decryption + 96 48 : static void inv_shift_rows(uint8_t state[16]) { + 97 : uint8_t tmp; + 98 : + 99 : // Row 1: shift right by 1 + 100 48 : tmp = state[13]; + 101 48 : state[13] = state[9]; + 102 48 : state[9] = state[5]; + 103 48 : state[5] = state[1]; + 104 48 : state[1] = tmp; + 105 : + 106 : // Row 2: shift right by 2 + 107 48 : tmp = state[2]; + 108 48 : state[2] = state[10]; + 109 48 : state[10] = tmp; + 110 48 : tmp = state[6]; + 111 48 : state[6] = state[14]; + 112 48 : state[14] = tmp; + 113 : + 114 : // Row 3: shift right by 3 + 115 48 : tmp = state[3]; + 116 48 : state[3] = state[7]; + 117 48 : state[7] = state[11]; + 118 48 : state[11] = state[15]; + 119 48 : state[15] = tmp; + 120 48 : } + 121 : + 122 2816 : static uint8_t mul(uint8_t a, uint8_t b) { + 123 2816 : uint8_t p = 0; + 124 : uint8_t hi_bit_set; + 125 25344 : for (int i = 0; i < 8; i++) { + 126 22528 : if (b & 1) + 127 7744 : p ^= a; + 128 22528 : hi_bit_set = a & 0x80; + 129 22528 : a <<= 1; + 130 22528 : if (hi_bit_set) + 131 11152 : a ^= 0x1b; + 132 22528 : b >>= 1; + 133 22528 : } + 134 2816 : return p; + 135 : } + 136 : + 137 44 : static void inv_mix_columns(uint8_t state[16]) { + 138 220 : for (int c = 0; c < 4; c++) { + 139 176 : uint8_t *col = &state[c * 4]; + 140 176 : uint8_t a0 = col[0], a1 = col[1], a2 = col[2], a3 = col[3]; + 141 : + 142 176 : col[0] = mul(a0, 0x0e) ^ mul(a1, 0x0b) ^ mul(a2, 0x0d) ^ mul(a3, 0x09); + 143 176 : col[1] = mul(a0, 0x09) ^ mul(a1, 0x0e) ^ mul(a2, 0x0b) ^ mul(a3, 0x0d); + 144 176 : col[2] = mul(a0, 0x0d) ^ mul(a1, 0x09) ^ mul(a2, 0x0e) ^ mul(a3, 0x0b); + 145 176 : col[3] = mul(a0, 0x0b) ^ mul(a1, 0x0d) ^ mul(a2, 0x09) ^ mul(a3, 0x0e); + 146 176 : } + 147 44 : } + 148 : + 149 48 : static void inv_sub_bytes(uint8_t state[16], const uint8_t inv_sbox[256]) { + 150 816 : for (int i = 0; i < 16; i++) { + 151 768 : state[i] = inv_sbox[state[i]]; + 152 768 : } + 153 48 : } + 154 : + 155 : // AES-192 Decryption (12 rounds) + 156 4 : void aes192_decrypt_block(const uint8_t input[16], uint8_t output[16], + 157 : const uint8_t round_keys[208], const uint8_t sbox[256]) { + 158 : uint8_t state[16]; + 159 : uint8_t inv_sbox[256]; + 160 : + 161 : // Generate inverse S-box + 162 4 : initialize_inverse_sbox(sbox, inv_sbox); + 163 : + 164 : // Copy input to state + 165 68 : for (int i = 0; i < 16; i++) { + 166 64 : state[i] = input[i]; + 167 64 : } + 168 : + 169 : // Initial AddRoundKey with last round key + 170 4 : add_round_key(state, round_keys + 12 * 16); + 171 : + 172 : // 11 rounds + 173 48 : for (int round = 11; round >= 1; round--) { + 174 44 : inv_shift_rows(state); + 175 44 : inv_sub_bytes(state, inv_sbox); + 176 44 : add_round_key(state, round_keys + round * 16); + 177 44 : inv_mix_columns(state); + 178 44 : } + 179 : + 180 : // Final round (no InvMixColumns) + 181 4 : inv_shift_rows(state); + 182 4 : inv_sub_bytes(state, inv_sbox); + 183 4 : add_round_key(state, round_keys); + 184 : + 185 : // Copy state to output + 186 68 : for (int i = 0; i < 16; i++) { + 187 64 : output[i] = state[i]; + 188 64 : } + 189 4 : } ++ |
+
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| aes256_decrypt_block | + +4 | + + + +
| inv_mix_columns | + +52 | + + + +
| inv_shift_rows | + +56 | + + + +
| inv_sub_bytes | + +56 | + + + +
| aes256_encrypt_block | + +174668 | + + + +
| mix_columns | + +2270684 | + + + +
| shift_rows | + +2445352 | + + + +
| sub_bytes | + +2445352 | + + + +
| add_round_key | + +2620080 | + + + +
| gf_mul | + +72665216 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| add_round_key | + +2620080 | + + + +
| aes256_decrypt_block | + +4 | + + + +
| aes256_encrypt_block | + +174668 | + + + +
| gf_mul | + +72665216 | + + + +
| inv_mix_columns | + +52 | + + + +
| inv_shift_rows | + +56 | + + + +
| inv_sub_bytes | + +56 | + + + +
| mix_columns | + +2270684 | + + + +
| shift_rows | + +2445352 | + + + +
| sub_bytes | + +2445352 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : #include <stdint.h> + 2 : #include <string.h> // for memcpy + 3 : #include "../include/aes_256.h" + 4 : #include "../include/aes_defs.h" // for AES-256 constants + 5 : #include "../include/sbox.h" // for S-box and inverse S-box initialization + 6 : + 7 : // Forward declarations of helper functions + 8 : static void sub_bytes(uint8_t state[AES256_BLOCK_SIZE], const uint8_t sbox[256]); + 9 : static void shift_rows(uint8_t state[AES256_BLOCK_SIZE]); + 10 : static void mix_columns(uint8_t state[AES256_BLOCK_SIZE]); + 11 : static void add_round_key(uint8_t state[AES256_BLOCK_SIZE], const uint8_t round_key[AES256_BLOCK_SIZE]); + 12 : + 13 : static void inv_sub_bytes(uint8_t state[AES256_BLOCK_SIZE], const uint8_t inv_sbox[256]); + 14 : static void inv_shift_rows(uint8_t state[AES256_BLOCK_SIZE]); + 15 : static void inv_mix_columns(uint8_t state[AES256_BLOCK_SIZE]); + 16 : + 17 : // GF(2^8) multiplication helper used in mix_columns and inv_mix_columns + 18 72665216 : static uint8_t gf_mul(uint8_t a, uint8_t b) { + 19 72665216 : uint8_t p = 0; + 20 653986944 : for (int i = 0; i < 8; i++) { + 21 581321728 : if (b & 1) p ^= a; + 22 581321728 : uint8_t hi_bit_set = a & 0x80; + 23 581321728 : a <<= 1; + 24 581321728 : if (hi_bit_set) a ^= 0x1B; // irreducible polynomial + 25 581321728 : b >>= 1; + 26 581321728 : } + 27 72665216 : return p; + 28 : } + 29 : + 30 2445352 : void sub_bytes(uint8_t state[AES256_BLOCK_SIZE], const uint8_t sbox[256]) { + 31 41570984 : for (int i = 0; i < AES256_BLOCK_SIZE; i++) { + 32 39125632 : state[i] = sbox[state[i]]; + 33 39125632 : } + 34 2445352 : } + 35 : + 36 2445352 : void shift_rows(uint8_t state[AES256_BLOCK_SIZE]) { + 37 : // Row 1: rotate left by 1 + 38 2445352 : uint8_t tmp = state[1]; + 39 2445352 : state[1] = state[5]; + 40 2445352 : state[5] = state[9]; + 41 2445352 : state[9] = state[13]; + 42 2445352 : state[13] = tmp; + 43 : + 44 : // Row 2: rotate left by 2 + 45 2445352 : tmp = state[2]; + 46 2445352 : uint8_t tmp2 = state[6]; + 47 2445352 : state[2] = state[10]; + 48 2445352 : state[6] = state[14]; + 49 2445352 : state[10] = tmp; + 50 2445352 : state[14] = tmp2; + 51 : + 52 : // Row 3: rotate left by 3 + 53 2445352 : tmp = state[3]; + 54 2445352 : state[3] = state[15]; + 55 2445352 : state[15] = state[11]; + 56 2445352 : state[11] = state[7]; + 57 2445352 : state[7] = tmp; + 58 2445352 : } + 59 : + 60 2270684 : void mix_columns(uint8_t state[AES256_BLOCK_SIZE]) { + 61 11353420 : for (int c = 0; c < 4; c++) { + 62 9082736 : uint8_t *col = &state[c * 4]; + 63 9082736 : uint8_t a0 = col[0], a1 = col[1], a2 = col[2], a3 = col[3]; + 64 : + 65 9082736 : col[0] = gf_mul(a0, 2) ^ gf_mul(a1, 3) ^ a2 ^ a3; + 66 9082736 : col[1] = a0 ^ gf_mul(a1, 2) ^ gf_mul(a2, 3) ^ a3; + 67 9082736 : col[2] = a0 ^ a1 ^ gf_mul(a2, 2) ^ gf_mul(a3, 3); + 68 9082736 : col[3] = gf_mul(a0, 3) ^ a1 ^ a2 ^ gf_mul(a3, 2); + 69 9082736 : } + 70 2270684 : } + 71 : + 72 2620080 : void add_round_key(uint8_t state[AES256_BLOCK_SIZE], const uint8_t round_key[AES256_BLOCK_SIZE]) { + 73 44541360 : for (int i = 0; i < AES256_BLOCK_SIZE; i++) { + 74 41921280 : state[i] ^= round_key[i]; + 75 41921280 : } + 76 2620080 : } + 77 : + 78 174668 : void aes256_encrypt_block(const uint8_t input[AES256_BLOCK_SIZE], uint8_t output[AES256_BLOCK_SIZE], + 79 : const uint8_t round_keys[AES256_EXPANDED_KEY_SIZE], const uint8_t sbox[256]) { + 80 : uint8_t state[AES256_BLOCK_SIZE]; + 81 174668 : memcpy(state, input, AES256_BLOCK_SIZE); + 82 : + 83 174668 : add_round_key(state, round_keys); + 84 : + 85 2445352 : for (int round = 1; round < AES256_NUM_ROUNDS; round++) { + 86 2270684 : sub_bytes(state, sbox); + 87 2270684 : shift_rows(state); + 88 2270684 : mix_columns(state); + 89 2270684 : add_round_key(state, round_keys + round * AES256_BLOCK_SIZE); + 90 2270684 : } + 91 : + 92 : // Final round (no mix_columns) + 93 174668 : sub_bytes(state, sbox); + 94 174668 : shift_rows(state); + 95 174668 : add_round_key(state, round_keys + AES256_NUM_ROUNDS * AES256_BLOCK_SIZE); + 96 : + 97 174668 : memcpy(output, state, AES256_BLOCK_SIZE); + 98 174668 : } + 99 : + 100 : // ---------- Inverse functions ------------ + 101 : + 102 56 : void inv_sub_bytes(uint8_t state[AES256_BLOCK_SIZE], const uint8_t inv_sbox[256]) { + 103 952 : for (int i = 0; i < AES256_BLOCK_SIZE; i++) { + 104 896 : state[i] = inv_sbox[state[i]]; + 105 896 : } + 106 56 : } + 107 : + 108 56 : void inv_shift_rows(uint8_t state[AES256_BLOCK_SIZE]) { + 109 : // Row 1: rotate right by 1 + 110 56 : uint8_t tmp = state[13]; + 111 56 : state[13] = state[9]; + 112 56 : state[9] = state[5]; + 113 56 : state[5] = state[1]; + 114 56 : state[1] = tmp; + 115 : + 116 : // Row 2: rotate right by 2 + 117 56 : tmp = state[2]; + 118 56 : uint8_t tmp2 = state[6]; + 119 56 : state[2] = state[10]; + 120 56 : state[6] = state[14]; + 121 56 : state[10] = tmp; + 122 56 : state[14] = tmp2; + 123 : + 124 : // Row 3: rotate right by 3 + 125 56 : tmp = state[3]; + 126 56 : state[3] = state[7]; + 127 56 : state[7] = state[11]; + 128 56 : state[11] = state[15]; + 129 56 : state[15] = tmp; + 130 56 : } + 131 : + 132 52 : void inv_mix_columns(uint8_t state[AES256_BLOCK_SIZE]) { + 133 260 : for (int c = 0; c < 4; c++) { + 134 208 : uint8_t *col = &state[c * 4]; + 135 208 : uint8_t a0 = col[0], a1 = col[1], a2 = col[2], a3 = col[3]; + 136 : + 137 208 : col[0] = gf_mul(a0, 0x0e) ^ gf_mul(a1, 0x0b) ^ gf_mul(a2, 0x0d) ^ gf_mul(a3, 0x09); + 138 208 : col[1] = gf_mul(a0, 0x09) ^ gf_mul(a1, 0x0e) ^ gf_mul(a2, 0x0b) ^ gf_mul(a3, 0x0d); + 139 208 : col[2] = gf_mul(a0, 0x0d) ^ gf_mul(a1, 0x09) ^ gf_mul(a2, 0x0e) ^ gf_mul(a3, 0x0b); + 140 208 : col[3] = gf_mul(a0, 0x0b) ^ gf_mul(a1, 0x0d) ^ gf_mul(a2, 0x09) ^ gf_mul(a3, 0x0e); + 141 208 : } + 142 52 : } + 143 : + 144 4 : void aes256_decrypt_block(const uint8_t input[AES256_BLOCK_SIZE], uint8_t output[AES256_BLOCK_SIZE], + 145 : const uint8_t round_keys[AES256_EXPANDED_KEY_SIZE], const uint8_t sbox[256]) { + 146 : uint8_t state[AES256_BLOCK_SIZE]; + 147 : uint8_t inv_sbox[256]; + 148 4 : initialize_inverse_sbox(sbox, inv_sbox); + 149 : + 150 4 : memcpy(state, input, AES256_BLOCK_SIZE); + 151 : + 152 4 : add_round_key(state, round_keys + AES256_NUM_ROUNDS * AES256_BLOCK_SIZE); + 153 : + 154 56 : for (int round = AES256_NUM_ROUNDS - 1; round >= 1; round--) { + 155 52 : inv_shift_rows(state); + 156 52 : inv_sub_bytes(state, inv_sbox); + 157 52 : add_round_key(state, round_keys + round * AES256_BLOCK_SIZE); + 158 52 : inv_mix_columns(state); + 159 52 : } + 160 : + 161 4 : inv_shift_rows(state); + 162 4 : inv_sub_bytes(state, inv_sbox); + 163 4 : add_round_key(state, round_keys); + 164 : + 165 4 : memcpy(output, state, AES256_BLOCK_SIZE); + 166 4 : } ++ |
+
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| aes_block_wrapper_dec | + +44 | + + + +
| aes_block_wrapper | + +524640 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| aes_block_wrapper | + +524640 | + + + +
| aes_block_wrapper_dec | + +44 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : #include <stdint.h> + 2 : #include <stddef.h> + 3 : + 4 : #include "../include/aes_128.h" + 5 : #include "../include/aes_192.h" + 6 : #include "../include/aes_256.h" + 7 : #include "../include/sbox.h" + 8 : + 9 : /* Context struct to pass round_keys, sbox, and key_len to aes_block_wrapper */ + 10 : struct aes_ctx { + 11 : const uint8_t *round_keys; + 12 : const uint8_t *sbox; + 13 : size_t key_len; // 16, 24, or 32 bytes + 14 : }; + 15 : + 16 : /* Adapter to match encrypt_block_fn in cbc.h / ctr.h */ + 17 524640 : void aes_block_wrapper(const uint8_t in[16], uint8_t out[16], const void *ctx) { + 18 524640 : const struct aes_ctx *aes = (const struct aes_ctx *)ctx; + 19 : + 20 524640 : if (aes->key_len == 16) { + 21 174830 : aes128_encrypt_block(in, out, aes->round_keys, aes->sbox); + 22 524640 : } else if (aes->key_len == 24) { + 23 175138 : aes192_encrypt_block(in, out, aes->round_keys, aes->sbox); + 24 349810 : } else if (aes->key_len == 32) { + 25 174664 : aes256_encrypt_block(in, out, aes->round_keys, aes->sbox); + 26 174664 : } + 27 524640 : } + 28 : + 29 : /* Adapter for decryption */ + 30 44 : void aes_block_wrapper_dec(const uint8_t in[16], uint8_t out[16], const void *ctx) { + 31 44 : const struct aes_ctx *aes = (const struct aes_ctx *)ctx; + 32 : + 33 44 : if (aes->key_len == 16) { + 34 44 : aes128_decrypt_block(in, out, aes->round_keys, aes->sbox); + 35 44 : } else if (aes->key_len == 24) { + 36 0 : aes192_decrypt_block(in, out, aes->round_keys, aes->sbox); + 37 0 : } else if (aes->key_len == 32) { + 38 0 : aes256_decrypt_block(in, out, aes->round_keys, aes->sbox); + 39 0 : } + 40 44 : } ++ |
+
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| aes_cbc_decrypt | + +2 | + + + +
| aes_cbc_encrypt | + +2 | + + + +
| pkcs7_pad | + +2 | + + + +
| pkcs7_unpad | + +2 | + + + +
| xor_block | + +12 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| aes_cbc_decrypt | + +2 | + + + +
| aes_cbc_encrypt | + +2 | + + + +
| pkcs7_pad | + +2 | + + + +
| pkcs7_unpad | + +2 | + + + +
| xor_block | + +12 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : #include "cbc.h" + 2 : #include <string.h> + 3 : #include <stdlib.h> + 4 : + 5 : /* PKCS#7 padding helper: returns number of padding bytes appended (1..16) */ + 6 2 : static size_t pkcs7_pad(const uint8_t *in, size_t in_len, uint8_t *out) { + 7 2 : size_t pad_len = AES_BLOCK - (in_len % AES_BLOCK); + 8 2 : if (pad_len == 0) pad_len = AES_BLOCK; + 9 : /* copy input */ + 10 2 : memcpy(out, in, in_len); + 11 : /* append pad bytes */ + 12 22 : for (size_t i = 0; i < pad_len; ++i) out[in_len + i] = (uint8_t)pad_len; + 13 2 : return pad_len; + 14 : } + 15 : + 16 : /* remove PKCS#7 pad; returns 0 on success and sets *out_len to unpadded length. + 17 : * Returns non-zero on invalid padding. + 18 : */ + 19 2 : static int pkcs7_unpad(uint8_t *buf, size_t buf_len, size_t *out_len) { + 20 2 : if (buf_len == 0 || (buf_len % AES_BLOCK) != 0) return -1; + 21 2 : uint8_t pad = buf[buf_len - 1]; + 22 2 : if (pad == 0 || pad > AES_BLOCK) return -2; + 23 : /* check that last pad bytes equal pad */ + 24 22 : for (size_t i = 0; i < pad; ++i) { + 25 20 : if (buf[buf_len - 1 - i] != pad) return -3; + 26 20 : } + 27 2 : *out_len = buf_len - pad; + 28 2 : return 0; + 29 2 : } + 30 : + 31 : /* XOR helper */ + 32 12 : static inline void xor_block(uint8_t out[AES_BLOCK], const uint8_t a[AES_BLOCK], const uint8_t b[AES_BLOCK]) { + 33 204 : for (int i = 0; i < AES_BLOCK; ++i) out[i] = a[i] ^ b[i]; + 34 12 : } + 35 : + 36 2 : int aes_cbc_encrypt(const uint8_t *in, size_t in_len, + 37 : uint8_t *out, size_t *out_len, + 38 : const uint8_t iv[AES_BLOCK], + 39 : encrypt_block_fn encrypt, const void *ctx) + 40 : { + 41 2 : if (!in || !out || !out_len || !iv || !encrypt) return -1; + 42 : + 43 : /* padded buffer size = ceil(in_len/16)*16 + 16 (if in_len %16 ==0, add a full block) */ + 44 2 : size_t padded_len = ((in_len + AES_BLOCK - 1) / AES_BLOCK) * AES_BLOCK; + 45 2 : if (padded_len == in_len) padded_len += AES_BLOCK; + 46 : + 47 2 : uint8_t *buf = (uint8_t*)malloc(padded_len); + 48 2 : if (!buf) return -2; + 49 : + 50 : /* create padded plaintext in buf */ + 51 2 : size_t pad_len = pkcs7_pad(in, in_len, buf); + 52 2 : (void)pad_len; /* padded_len equals in_len + pad_len */ + 53 : + 54 : uint8_t prev[AES_BLOCK]; + 55 2 : memcpy(prev, iv, AES_BLOCK); + 56 : + 57 8 : for (size_t off = 0; off < padded_len; off += AES_BLOCK) { + 58 : uint8_t block[AES_BLOCK]; + 59 6 : xor_block(block, buf + off, prev); + 60 6 : encrypt(block, out + off, ctx); + 61 : /* new prev = ciphertext block */ + 62 6 : memcpy(prev, out + off, AES_BLOCK); + 63 6 : } + 64 : + 65 2 : *out_len = padded_len; + 66 : /* wipe sensitive buffer */ + 67 2 : memset(buf, 0, padded_len); + 68 2 : free(buf); + 69 2 : memset(prev, 0, AES_BLOCK); + 70 2 : return 0; + 71 2 : } + 72 : + 73 2 : int aes_cbc_decrypt(const uint8_t *in, size_t in_len, + 74 : uint8_t *out, size_t *out_len, + 75 : const uint8_t iv[AES_BLOCK], + 76 : decrypt_block_fn decrypt, const void *ctx) + 77 : { + 78 2 : if (!in || !out || !out_len || !iv || !decrypt) return -1; + 79 2 : if ((in_len % AES_BLOCK) != 0) return -2; + 80 : + 81 : uint8_t prev[AES_BLOCK]; + 82 2 : memcpy(prev, iv, AES_BLOCK); + 83 : + 84 8 : for (size_t off = 0; off < in_len; off += AES_BLOCK) { + 85 : uint8_t tmp[AES_BLOCK]; + 86 6 : decrypt(in + off, tmp, ctx); /* tmp = AES_DEC(Ci) */ + 87 6 : xor_block(out + off, tmp, prev); /* plaintext block = tmp XOR prev */ + 88 6 : memcpy(prev, in + off, AES_BLOCK); + 89 6 : } + 90 : + 91 : /* unpad in-place on out */ + 92 2 : size_t unpadded_len = 0; + 93 2 : int r = pkcs7_unpad(out, in_len, &unpadded_len); + 94 2 : if (r != 0) { + 95 : /* wipe and return error */ + 96 0 : memset(out, 0, in_len); + 97 0 : memset(prev, 0, AES_BLOCK); + 98 0 : return -3; + 99 : } + 100 : + 101 2 : *out_len = unpadded_len; + 102 2 : memset(prev, 0, AES_BLOCK); + 103 2 : return 0; + 104 2 : } ++ |
+
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| ccm_decrypt | + +6 | + + + +
| ccm_encrypt | + +6 | + + + +
| build_b0 | + +12 | + + + +
| format_aad | + +12 | + + + +
| build_ctr0 | + +18 | + + + +
| xor_block | + +60 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| build_b0 | + +12 | + + + +
| build_ctr0 | + +18 | + + + +
| ccm_decrypt | + +6 | + + + +
| ccm_encrypt | + +6 | + + + +
| format_aad | + +12 | + + + +
| xor_block | + +60 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : #include "ccm.h" + 2 : #include "ctr.h" + 3 : #include <string.h> + 4 : #include <stdlib.h> + 5 : #include <stdio.h> + 6 : + 7 : #define AES_BLK AES_BLOCK_SIZE + 8 : + 9 : /* XOR helper */ + 10 60 : static inline void xor_block(uint8_t out[AES_BLK], + 11 : const uint8_t a[AES_BLK], + 12 : const uint8_t b[AES_BLK]) { + 13 1020 : for (int i = 0; i < AES_BLK; i++) out[i] = a[i] ^ b[i]; + 14 60 : } + 15 : + 16 : /* Build B0 block (CCM §6.1) */ + 17 12 : static void build_b0(uint8_t b0[AES_BLK], size_t t, size_t n, size_t payload_len, + 18 : const uint8_t *nonce, int has_aad) { + 19 12 : size_t q = 15 - n; + 20 12 : uint8_t flags = 0; + 21 12 : if (has_aad) flags |= 0x40; + 22 12 : flags |= (uint8_t)(((t - 2) / 2) << 3); + 23 12 : flags |= (uint8_t)((q - 1) & 0x07); + 24 12 : b0[0] = flags; + 25 : + 26 12 : memcpy(b0 + 1, nonce, n); + 27 : + 28 : /* write payload length in q-byte big-endian */ + 29 84 : for (size_t i = 0; i < q; i++) { + 30 72 : b0[15 - i] = (uint8_t)(payload_len >> (8 * i)); + 31 72 : } + 32 12 : } + 33 : + 34 : /* Build initial counter block for CTR */ + 35 18 : static void build_ctr0(uint8_t ctr[AES_BLK], size_t n, const uint8_t *nonce) { + 36 18 : size_t q = 15 - n; + 37 18 : ctr[0] = (uint8_t)(q - 1); + 38 18 : memcpy(ctr + 1, nonce, n); + 39 18 : memset(ctr + 1 + n, 0, q); + 40 18 : } + 41 : + 42 : /* Format AAD - simplified for small 'a' to a two-octet length field L(a) */ + 43 12 : static size_t format_aad(uint8_t **out, size_t aad_len, const uint8_t *aad) { + 44 12 : if (aad_len == 0) return 0; + 45 : + 46 : /* In this implementation, we assume a < 2^16 - 2^8, so L(a) is 2 octets (NIST A.2.2). + 47 : * This covers the provided test vectors. */ + 48 12 : size_t len_field_size = 2; + 49 : + 50 12 : size_t total = len_field_size + aad_len; + 51 12 : size_t padded = ((total + AES_BLK - 1) / AES_BLK) * AES_BLK; + 52 12 : uint8_t *buf = (uint8_t*)calloc(padded, 1); + 53 12 : if (!buf) return 0; + 54 : + 55 : /* Write L(a) in 2-byte big-endian */ + 56 12 : buf[0] = (uint8_t)(aad_len >> 8); + 57 12 : buf[1] = (uint8_t)(aad_len & 0xff); + 58 : + 59 12 : memcpy(buf + len_field_size, aad, aad_len); + 60 12 : *out = buf; + 61 12 : return padded; + 62 12 : } + 63 : + 64 6 : int ccm_encrypt(const void *key_ctx, + 65 : block_encrypt_fn encrypt, + 66 : const uint8_t *nonce, size_t n, + 67 : const uint8_t *aad, size_t aad_len, + 68 : const uint8_t *plaintext, size_t payload_len, + 69 : uint8_t *ciphertext, size_t *ciphertext_len, + 70 : size_t t) + 71 : { + 72 6 : if (!encrypt || !nonce || !ciphertext || !ciphertext_len) return -1; + 73 6 : if (n < 7 || n > 13) return -2; + 74 6 : if (!(t == 4 || t == 6 || t == 8 || t == 10 || t == 12 || t == 14 || t == 16)) return -3; + 75 6 : if (payload_len > 0 && !plaintext) return -1; + 76 : + 77 : #ifdef CCM_DEBUG + 78 : CCM_LOG("Encrypting payload_len=%zu, aad_len=%zu, t=%zu", payload_len, aad_len, t); + 79 : #endif + 80 : + 81 : /* Step 1: Build B0 */ + 82 : uint8_t b0[AES_BLK]; + 83 6 : build_b0(b0, t, n, payload_len, nonce, aad_len > 0); + 84 : + 85 : /* Step 2: Format AAD */ + 86 6 : uint8_t *aad_formatted = NULL; + 87 6 : size_t aad_formatted_len = format_aad(&aad_formatted, aad_len, aad); + 88 6 : if (aad_len > 0 && aad_formatted_len == 0) return -1; + 89 : + 90 : /* Step 3: Build CBC-MAC input */ + 91 6 : size_t mac_len = AES_BLK + aad_formatted_len; + 92 6 : if (payload_len > 0) { + 93 6 : size_t padded_payload_len = ((payload_len + AES_BLK - 1) / AES_BLK) * AES_BLK; + 94 6 : mac_len += padded_payload_len; + 95 6 : } + 96 6 : uint8_t *mac_input = (uint8_t*)calloc(mac_len, 1); + 97 6 : if (!mac_input) { + 98 0 : free(aad_formatted); + 99 0 : return -1; + 100 : } + 101 : + 102 6 : size_t offset = 0; + 103 6 : memcpy(mac_input + offset, b0, AES_BLK); + 104 6 : offset += AES_BLK; + 105 6 : if (aad_formatted_len > 0) { + 106 6 : memcpy(mac_input + offset, aad_formatted, aad_formatted_len); + 107 6 : offset += aad_formatted_len; + 108 6 : } + 109 6 : if (payload_len > 0) { + 110 6 : memcpy(mac_input + offset, plaintext, payload_len); + 111 6 : } + 112 : + 113 : /* Step 4: CBC-MAC */ + 114 6 : uint8_t X[AES_BLK] = {0}; + 115 30 : for (size_t i = 0; i < mac_len; i += AES_BLK) { + 116 : uint8_t blk[AES_BLK]; + 117 24 : xor_block(blk, X, mac_input + i); + 118 24 : encrypt(blk, X, key_ctx); /* X = CIPH_K(blk) */ + 119 24 : } + 120 : + 121 : /* Step 5: CTR encrypt */ + 122 : uint8_t ctr[AES_BLK]; + 123 6 : build_ctr0(ctr, n, nonce); + 124 : uint8_t s0[AES_BLK]; + 125 6 : encrypt(ctr, s0, key_ctx); /* S0 = CIPH_K(Ctr0) */ + 126 : + 127 : /* Encrypt plaintext using CTR mode (uses Ctr1, Ctr2, ...) */ + 128 6 : if (payload_len > 0) { + 129 6 : ctr_increment(ctr); /* ctr now holds Ctr1 */ + 130 6 : aes_ctr_crypt(plaintext, ciphertext, payload_len, ctr, encrypt, key_ctx); + 131 6 : } + 132 : + 133 : /* Compute and append encrypted tag */ + 134 : uint8_t tag_buf[AES_BLK]; + 135 6 : xor_block(tag_buf, X, s0); /* T = T XOR S0 */ + 136 6 : memcpy(ciphertext + payload_len, tag_buf, t); + 137 6 : *ciphertext_len = payload_len + t; + 138 : + 139 6 : free(aad_formatted); + 140 6 : free(mac_input); + 141 : + 142 : #ifdef CCM_DEBUG + 143 : CCM_LOG("Encryption complete, ciphertext_len=%zu", *ciphertext_len); + 144 : #endif + 145 6 : return 0; + 146 6 : } + 147 : + 148 6 : int ccm_decrypt(const void *key_ctx, + 149 : block_encrypt_fn encrypt, + 150 : const uint8_t *nonce, size_t n, + 151 : const uint8_t *aad, size_t aad_len, + 152 : const uint8_t *ciphertext, size_t ciphertext_len, + 153 : uint8_t *plaintext, size_t *plaintext_len, + 154 : size_t t) + 155 : { + 156 6 : if (!encrypt || !nonce || !ciphertext || !plaintext || !plaintext_len) return -1; + 157 6 : if (ciphertext_len < t) return -1; + 158 6 : if (n < 7 || n > 13) return -2; + 159 6 : if (!(t == 4 || t == 6 || t == 8 || t == 10 || t == 12 || t == 14 || t == 16)) return -3; + 160 : + 161 6 : size_t payload_len = ciphertext_len - t; + 162 : + 163 : #ifdef CCM_DEBUG + 164 : CCM_LOG("Decrypting ciphertext_len=%zu, aad_len=%zu, t=%zu", ciphertext_len, aad_len, t); + 165 : #endif + 166 : + 167 : /* Step 1: Decrypt payload using CTR mode */ + 168 : uint8_t ctr[AES_BLK]; + 169 6 : build_ctr0(ctr, n, nonce); + 170 : + 171 6 : if (payload_len > 0) { + 172 6 : ctr_increment(ctr); /* ctr now holds Ctr1 */ + 173 6 : aes_ctr_crypt(ciphertext, plaintext, payload_len, ctr, encrypt, key_ctx); + 174 6 : } + 175 : + 176 : /* Step 2: Recompute CBC-MAC on decrypted plaintext */ + 177 : uint8_t b0[AES_BLK]; + 178 6 : build_b0(b0, t, n, payload_len, nonce, aad_len > 0); + 179 : + 180 6 : uint8_t *aad_formatted = NULL; + 181 6 : size_t aad_formatted_len = format_aad(&aad_formatted, aad_len, aad); + 182 6 : if (aad_len > 0 && aad_formatted_len == 0) return -1; + 183 : + 184 6 : size_t mac_len = AES_BLK + aad_formatted_len; + 185 6 : if (payload_len > 0) { + 186 6 : size_t padded_payload_len = ((payload_len + AES_BLK - 1) / AES_BLK) * AES_BLK; + 187 6 : mac_len += padded_payload_len; + 188 6 : } + 189 : + 190 6 : uint8_t *mac_input = (uint8_t*)calloc(mac_len, 1); + 191 6 : if (!mac_input) { + 192 0 : free(aad_formatted); + 193 0 : return -1; + 194 : } + 195 : + 196 6 : size_t offset = 0; + 197 6 : memcpy(mac_input + offset, b0, AES_BLK); + 198 6 : offset += AES_BLK; + 199 6 : if (aad_formatted_len > 0) { + 200 6 : memcpy(mac_input + offset, aad_formatted, aad_formatted_len); + 201 6 : offset += aad_formatted_len; + 202 6 : } + 203 6 : if (payload_len > 0) { + 204 6 : memcpy(mac_input + offset, plaintext, payload_len); + 205 6 : } + 206 : + 207 6 : uint8_t X[AES_BLK] = {0}; + 208 30 : for (size_t i = 0; i < mac_len; i += AES_BLK) { + 209 : uint8_t blk[AES_BLK]; + 210 24 : xor_block(blk, X, mac_input + i); + 211 24 : encrypt(blk, X, key_ctx); /* X = CIPH_K(blk) */ + 212 24 : } + 213 : + 214 : /* Step 3: Verify tag */ + 215 6 : build_ctr0(ctr, n, nonce); + 216 : uint8_t s0[AES_BLK]; + 217 6 : encrypt(ctr, s0, key_ctx); /* S0 = CIPH_K(Ctr0) */ + 218 : + 219 : uint8_t expected_tag[AES_BLK]; + 220 6 : xor_block(expected_tag, X, s0); + 221 : + 222 6 : const uint8_t *received_tag = ciphertext + payload_len; + 223 6 : int diff = 0; + 224 : /* Constant-time comparison */ + 225 42 : for (size_t i = 0; i < t; i++) { + 226 36 : diff |= (expected_tag[i] ^ received_tag[i]); + 227 36 : } + 228 : + 229 6 : free(aad_formatted); + 230 6 : free(mac_input); + 231 : + 232 6 : if (diff != 0) { + 233 : /* Zero out plaintext to prevent partial disclosure */ + 234 0 : memset(plaintext, 0, payload_len); + 235 : #ifdef CCM_DEBUG + 236 : CCM_LOG("Authentication failed"); + 237 : #endif + 238 0 : return -2; + 239 : } + 240 : + 241 6 : *plaintext_len = payload_len; + 242 : + 243 : #ifdef CCM_DEBUG + 244 : CCM_LOG("Decryption successful, plaintext_len=%zu", *plaintext_len); + 245 : #endif + 246 6 : return 0; + 247 6 : } ++ |
+
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| aes_cfb_decrypt | + +2 | + + + +
| aes_cfb_encrypt | + +2 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| aes_cfb_decrypt | + +2 | + + + +
| aes_cfb_encrypt | + +2 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : #include <stdint.h> + 2 : #include <string.h> + 3 : #include "../include/cfb.h" + 4 : #include "../include/aes_wrapper.h" // for aes_block_wrapper + 5 : #include "../include/key_expansion_128.h" + 6 : #include "../include/sbox.h" + 7 : + 8 2 : void aes_cfb_encrypt( + 9 : const uint8_t *plaintext, + 10 : uint8_t *ciphertext, + 11 : size_t length, + 12 : const uint8_t *iv, + 13 : const void *ctx + 14 : ) { + 15 : uint8_t buffer[16]; + 16 : uint8_t feedback[16]; + 17 : + 18 2 : memcpy(feedback, iv, 16); + 19 2 : aes_block_wrapper(feedback, buffer, &ctx); // encrypt IV + 20 : + 21 44 : for (size_t i = 0; i < length; i++) { + 22 42 : ciphertext[i] = plaintext[i] ^ buffer[i % 16]; + 23 42 : feedback[i % 16] = ciphertext[i]; + 24 : + 25 42 : if ((i % 16) == 15 && i + 1 < length) { + 26 2 : aes_block_wrapper(feedback, buffer, &ctx); + 27 2 : } + 28 42 : } + 29 2 : } + 30 : + 31 2 : void aes_cfb_decrypt( + 32 : const uint8_t *ciphertext, + 33 : uint8_t *plaintext, + 34 : size_t length, + 35 : const uint8_t *iv, + 36 : const void *ctx + 37 : ) { + 38 : uint8_t buffer[16]; + 39 : uint8_t feedback[16]; + 40 : + 41 2 : memcpy(feedback, iv, 16); + 42 2 : aes_block_wrapper(feedback, buffer, &ctx); // encrypt IV + 43 : + 44 44 : for (size_t i = 0; i < length; i++) { + 45 42 : plaintext[i] = ciphertext[i] ^ buffer[i % 16]; + 46 42 : feedback[i % 16] = ciphertext[i]; + 47 : + 48 42 : if ((i % 16) == 15 && i + 1 < length) { + 49 2 : aes_block_wrapper(feedback, buffer, &ctx); + 50 2 : } + 51 42 : } + 52 2 : } ++ |
+
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| pad_block | + +4 | + + + +
| aes_cmac | + +8 | + + + +
| generate_subkeys | + +8 | + + + +
| shift_left | + +16 | + + + +
| xor_block | + +34 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| aes_cmac | + +8 | + + + +
| generate_subkeys | + +8 | + + + +
| pad_block | + +4 | + + + +
| shift_left | + +16 | + + + +
| xor_block | + +34 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : #include "cmac.h" + 2 : #include <string.h> + 3 : #include <stdint.h> + 4 : #include <stdio.h> + 5 : + 6 : /* XOR two 16-byte blocks */ + 7 34 : static void xor_block(uint8_t out[16], const uint8_t a[16], const uint8_t b[16]) { + 8 578 : for (int i = 0; i < 16; i++) out[i] = a[i] ^ b[i]; + 9 34 : } + 10 : + 11 : /* Left shift a 16-byte block by 1 bit */ + 12 16 : static void shift_left(uint8_t out[16], const uint8_t in[16]) { + 13 16 : uint8_t carry = 0; + 14 272 : for (int i = 15; i >= 0; i--) { + 15 256 : uint8_t new_carry = (in[i] & 0x80) ? 1 : 0; + 16 256 : out[i] = (in[i] << 1) | carry; + 17 256 : carry = new_carry; + 18 256 : } + 19 16 : } + 20 : + 21 : /* Generate subkeys K1 and K2 according to NIST SP 800-38B */ + 22 8 : static void generate_subkeys(uint8_t K1[16], uint8_t K2[16], const void *ctx) { + 23 8 : uint8_t L[16] = {0}; + 24 8 : uint8_t zero[16] = {0}; + 25 : // Encrypt the zero block to get L + 26 8 : aes_block_wrapper(zero, L, ctx); + 27 : + 28 8 : const uint8_t Rb[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 29 : 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x87}; + 30 : + 31 : // K1 = L << 1. If MSB(L)=1, K1 XOR Rb + 32 8 : shift_left(K1, L); + 33 8 : if (L[0] & 0x80) { + 34 0 : xor_block(K1, K1, Rb); + 35 0 : } + 36 : + 37 : // K2 = K1 << 1. If MSB(K1)=1, K2 XOR Rb + 38 8 : shift_left(K2, K1); + 39 8 : if (K1[0] & 0x80) { + 40 8 : xor_block(K2, K2, Rb); + 41 8 : } + 42 8 : } + 43 : + 44 : /* Pad a block (0x80 followed by zeros) for partial/empty blocks */ + 45 4 : static void pad_block(uint8_t out[16], const uint8_t *in, size_t len) { + 46 4 : memset(out, 0, 16); + 47 4 : if (len > 0 && in != NULL) memcpy(out, in, len); + 48 4 : if (len < 16) out[len] = 0x80; + 49 4 : } + 50 : + 51 8 : void aes_cmac(const uint8_t *message, size_t length, uint8_t tag[16], const void *ctx) { + 52 : uint8_t K1[16], K2[16]; + 53 8 : generate_subkeys(K1, K2, ctx); + 54 : + 55 : // If length == 0, n_blocks = 1. If length = 36, n_blocks = 3. + 56 8 : size_t n_blocks = (length == 0) ? 1 : (length + 15) / 16; + 57 8 : uint8_t C[16] = {0}; // Current chaining block, C0 is all zeros + 58 : + 59 : // Calculate the length of the message that is NOT the final block. + 60 : // This is 0 if n_blocks=1. + 61 8 : size_t processed_len = (n_blocks - 1) * 16; + 62 : + 63 : // Case 1: Complete final block (L > 0 and L is a multiple of 16) -> use K1 + 64 8 : int last_is_complete = (length > 0) && (length % 16 == 0); + 65 : + 66 : // Process all full blocks except the last one + 67 18 : for (size_t i = 0; i < processed_len; i += 16) { + 68 : uint8_t Y[16]; + 69 10 : xor_block(Y, C, message + i); + 70 10 : aes_block_wrapper(Y, C, ctx); + 71 10 : } + 72 : + 73 : // Prepare the last block M_last (M_n XOR K1 or M_n* XOR K2) + 74 : uint8_t M_last[16]; + 75 : + 76 8 : if (last_is_complete) { + 77 : // Full block (e.g., L=32): M_last = M_n XOR K1. + 78 : // The last block starts at message + length - 16. + 79 4 : memcpy(M_last, message + length - 16, 16); + 80 4 : xor_block(M_last, M_last, K1); + 81 4 : } else { + 82 : // Partial block (e.g., L=36) or L=0: M_last = M_n* XOR K2. + 83 4 : size_t last_len = length % 16; // 4 for L=36, 0 for L=0 + 84 : + 85 4 : if (length == 0) { + 86 : // Empty message + 87 2 : pad_block(M_last, NULL, 0); + 88 2 : } else { + 89 : // Partial message: M_last starts at message + processed_len. + 90 2 : pad_block(M_last, message + processed_len, last_len); + 91 : } + 92 4 : xor_block(M_last, M_last, K2); + 93 : } + 94 : + 95 : // Process last block: T = E(C XOR M_last) + 96 : uint8_t Y_last[16]; + 97 8 : xor_block(Y_last, C, M_last); + 98 8 : aes_block_wrapper(Y_last, tag, ctx); + 99 8 : } ++ |
+
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| aes_ctr_crypt | + +165200 | + + + +
| ctr_increment | + +392060 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| aes_ctr_crypt | + +165200 | + + + +
| ctr_increment | + +392060 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : #include "ctr.h" + 2 : #include <string.h> + 3 : #include <stdint.h> + 4 : + 5 : /* Increment counter block: treat last 4 bytes as big-endian 32-bit counter and add 1. + 6 : * This is a common CTR layout: nonce || counter (32-bit). If you need a different + 7 : * scheme (e.g., 64-bit counter), modify this function accordingly. + 8 : */ + 9 392060 : void ctr_increment(uint8_t counter[CTR_BLOCK_SIZE]) { + 10 : /* increment last 4 bytes as big-endian integer */ + 11 393010 : for (int i = CTR_BLOCK_SIZE - 1; i >= CTR_BLOCK_SIZE - 4; --i) { + 12 393010 : if (++counter[i] != 0) { + 13 392060 : break; + 14 : } + 15 950 : } + 16 392060 : } + 17 : + 18 165200 : void aes_ctr_crypt(const uint8_t *in, uint8_t *out, size_t len, + 19 : const uint8_t counter[CTR_BLOCK_SIZE], + 20 : block_encrypt_fn encrypt, const void *rk) + 21 : { + 22 : uint8_t ctr[CTR_BLOCK_SIZE]; + 23 : uint8_t keystream[CTR_BLOCK_SIZE]; + 24 165200 : size_t processed = 0; + 25 : + 26 : /* copy initial counter so caller's buffer is not modified */ + 27 165200 : memcpy(ctr, counter, CTR_BLOCK_SIZE); + 28 : + 29 392064 : while (processed < len) { + 30 : /* generate keystream block = AES_encrypt(counter) */ + 31 226864 : encrypt(ctr, keystream, rk); + 32 : + 33 226864 : size_t chunk = CTR_BLOCK_SIZE; + 34 226864 : if (len - processed < CTR_BLOCK_SIZE) + 35 56668 : chunk = len - processed; + 36 : + 37 : /* XOR chunk bytes */ + 38 3401664 : for (size_t i = 0; i < chunk; ++i) { + 39 3174800 : out[processed + i] = in[processed + i] ^ keystream[i]; + 40 3174800 : } + 41 : + 42 : /* advance */ + 43 226864 : processed += chunk; + 44 226864 : ctr_increment(ctr); + 45 : } + 46 : + 47 : /* clear sensitive intermediate buffers */ + 48 165200 : memset(keystream, 0, sizeof keystream); + 49 165200 : memset(ctr, 0, sizeof ctr); + 50 165200 : } ++ |
+
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| aes_ecb_decrypt | + +2 | + + + +
| aes_ecb_encrypt | + +2 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| aes_ecb_decrypt | + +2 | + + + +
| aes_ecb_encrypt | + +2 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : #include <string.h> + 2 : #include "ecb.h" + 3 : + 4 2 : void aes_ecb_encrypt(const uint8_t *plaintext, uint8_t *ciphertext, + 5 : size_t length, const void *ctx) + 6 : { + 7 2 : size_t blocks = length / 16; + 8 4 : for (size_t i = 0; i < blocks; ++i) { + 9 2 : aes_block_wrapper(plaintext + i*16, ciphertext + i*16, ctx); + 10 2 : } + 11 2 : } + 12 : + 13 2 : void aes_ecb_decrypt(const uint8_t *ciphertext, uint8_t *plaintext, + 14 : size_t length, const void *ctx) + 15 : { + 16 2 : size_t blocks = length / 16; + 17 4 : for (size_t i = 0; i < blocks; ++i) { + 18 2 : aes_block_wrapper_dec(ciphertext + i*16, plaintext + i*16, ctx); + 19 2 : } + 20 2 : } ++ |
+
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| gcm_decrypt | + +80398 | + + + +
| gcm_encrypt | + +108602 | + + + +
| gcm_init | + +108602 | + + + +
| ghash | + +261382 | + + + +
| ghash_mult | + +1305382 | + + + +
| xor_block | + +1305382 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| gcm_decrypt | + +80398 | + + + +
| gcm_encrypt | + +108602 | + + + +
| gcm_init | + +108602 | + + + +
| ghash | + +261382 | + + + +
| ghash_mult | + +1305382 | + + + +
| xor_block | + +1305382 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : #include "gcm.h" + 2 : #include "ctr.h" + 3 : #include "sbox.h" + 4 : #include "key_expansion_128.h" + 5 : #include "key_expansion_192.h" + 6 : #include "key_expansion_256.h" + 7 : #include "aes_wrapper.h" + 8 : #include <string.h> + 9 : #include <stdio.h> + 10 : + 11 : /* XOR two 16-byte blocks */ + 12 1305382 : static void xor_block(uint8_t out[16], const uint8_t a[16], const uint8_t b[16]) { + 13 22191494 : for (int i = 0; i < 16; i++) out[i] = a[i] ^ b[i]; + 14 1305382 : } + 15 : + 16 : /* GHASH multiplication in GF(2^128) */ + 17 1305382 : static void ghash_mult(uint8_t out[16], const uint8_t X[16], const uint8_t H[16]) { + 18 1305382 : uint8_t Z[16] = {0}; + 19 1305382 : uint8_t V[16]; memcpy(V,H,16); + 20 : + 21 22191494 : for(int i=0;i<16;i++){ + 22 187975008 : for(int j=7;j>=0;j--){ + 23 1456153344 : if((X[i]>>j)&1) for(int k=0;k<16;k++) Z[k]^=V[k]; + 24 167088896 : int carry=0; + 25 2840511232 : for(int k=0;k<16;k++){ + 26 2673422336 : int tmp=V[k]; + 27 2673422336 : V[k]=(tmp>>1)|carry; + 28 2673422336 : carry=(tmp&1)?0x80:0; + 29 2673422336 : } + 30 167088896 : if(carry) V[0]^=0xe1; + 31 167088896 : } + 32 20886112 : } + 33 1305382 : memcpy(out,Z,16); + 34 1305382 : } + 35 : + 36 : /* GHASH over arbitrary data */ + 37 261382 : void ghash(uint8_t out[16], const uint8_t *aad, size_t aad_len, + 38 : const uint8_t *c, size_t c_len, const uint8_t H[16]) { + 39 261382 : uint8_t Y[16] = {0}; + 40 : size_t i; + 41 : + 42 : /* Process AAD */ + 43 639382 : for (i=0;i+16<=aad_len;i+=16){ + 44 378000 : xor_block(Y,Y,aad+i); + 45 378000 : ghash_mult(Y,Y,H); + 46 378000 : } + 47 261382 : if (i<aad_len){ + 48 75600 : uint8_t tmp[16]={0}; + 49 75600 : memcpy(tmp,aad+i,aad_len-i); + 50 75600 : xor_block(Y,Y,tmp); + 51 75600 : ghash_mult(Y,Y,H); + 52 75600 : } + 53 : + 54 : /* Process ciphertext */ + 55 749472 : for (i=0;i+16<=c_len;i+=16){ + 56 488090 : xor_block(Y,Y,c+i); + 57 488090 : ghash_mult(Y,Y,H); + 58 488090 : } + 59 261382 : if (i<c_len){ + 60 102310 : uint8_t tmp[16]={0}; + 61 102310 : memcpy(tmp,c+i,c_len-i); + 62 102310 : xor_block(Y,Y,tmp); + 63 102310 : ghash_mult(Y,Y,H); + 64 102310 : } + 65 : + 66 : /* Length block */ + 67 261382 : uint8_t len_block[16]={0}; + 68 261382 : uint64_t aad_bits=aad_len*8; + 69 261382 : uint64_t c_bits=c_len*8; + 70 2352438 : for(int j=0;j<8;j++){ + 71 2091056 : len_block[7-j]=(aad_bits>>(8*j))&0xFF; + 72 2091056 : len_block[15-j]=(c_bits>>(8*j))&0xFF; + 73 2091056 : } + 74 261382 : xor_block(Y,Y,len_block); + 75 261382 : ghash_mult(Y,Y,H); + 76 : + 77 261382 : memcpy(out,Y,16); + 78 261382 : } + 79 : + 80 : /* Initialize GCM context - returns 0 on success, -1 on error */ + 81 108602 : int gcm_init(struct gcm_ctx *ctx, const uint8_t *key, size_t key_len, + 82 : const uint8_t *iv, size_t iv_len){ + 83 : + 84 108602 : initialize_aes_sbox(ctx->sbox); + 85 : + 86 108602 : if(key_len == 16) { + 87 36228 : aes_key_expansion_128(key, ctx->round_keys, ctx->sbox); + 88 108602 : } else if(key_len == 24) { + 89 36142 : aes_key_expansion_192(key, ctx->round_keys, ctx->sbox); + 90 72374 : } else if(key_len == 32) { + 91 36232 : aes_key_expansion_256(key, ctx->round_keys, ctx->sbox); + 92 36232 : } else { + 93 0 : return -1; // Unsupported key length + 94 : } + 95 : + 96 108602 : ctx->aes.round_keys = ctx->round_keys; + 97 108602 : ctx->aes.sbox = ctx->sbox; + 98 108602 : ctx->aes.key_len = key_len; + 99 : + 100 : /* H = AES(K,0^128) */ + 101 108602 : uint8_t zero[16] = {0}; + 102 108602 : aes_block_wrapper(zero, ctx->H, &ctx->aes); + 103 : + 104 : /* IV -> J0 */ + 105 108602 : if(iv_len == 12){ + 106 36220 : memcpy(ctx->J0, iv, 12); + 107 36220 : memset(ctx->J0 + 12, 0, 4); // Zero out all 4 bytes + 108 36220 : ctx->J0[15] = 0x01; // Then set the last byte to 1 + 109 36220 : } else { + 110 : /* GHASH IV */ + 111 72382 : ghash(ctx->J0, NULL, 0, iv, iv_len, ctx->H); + 112 : } + 113 : + 114 108602 : return 0; // Success + 115 108602 : } + 116 : + 117 : /* Encrypt with AES-GCM */ + 118 108602 : void gcm_encrypt(struct gcm_ctx *ctx, const uint8_t *plaintext, size_t len, + 119 : const uint8_t *aad, size_t aad_len, + 120 : uint8_t *ciphertext, uint8_t *tag, size_t tag_len){ + 121 : + 122 108602 : if(tag_len>16) tag_len=16; + 123 : + 124 108602 : uint8_t counter[16]; memcpy(counter,ctx->J0,16); + 125 108602 : ctr_increment(counter); + 126 : + 127 108602 : aes_ctr_crypt(plaintext,ciphertext,len,counter,aes_block_wrapper,&ctx->aes); + 128 : + 129 : uint8_t ghash_out[16]; + 130 108602 : ghash(ghash_out,aad,aad_len,ciphertext,len,ctx->H); + 131 : + 132 : uint8_t S[16]; + 133 108602 : aes_block_wrapper(ctx->J0,S,&ctx->aes); + 134 : + 135 1380706 : for(size_t i=0;i<tag_len;i++) tag[i]=ghash_out[i]^S[i]; + 136 108602 : } + 137 : + 138 : /* Decrypt with AES-GCM */ + 139 80398 : int gcm_decrypt(struct gcm_ctx *ctx, const uint8_t *ciphertext, size_t len, + 140 : const uint8_t *aad, size_t aad_len, + 141 : const uint8_t *tag, size_t tag_len, + 142 : uint8_t *plaintext){ + 143 : + 144 80398 : if(tag_len>16) tag_len=16; + 145 : + 146 : uint8_t ghash_out[16]; + 147 80398 : ghash(ghash_out,aad,aad_len,ciphertext,len,ctx->H); + 148 : + 149 : uint8_t S[16]; + 150 80398 : aes_block_wrapper(ctx->J0,S,&ctx->aes); + 151 : + 152 : uint8_t computed_tag[16]; + 153 1022294 : for(size_t i=0;i<tag_len;i++) computed_tag[i]=ghash_out[i]^S[i]; + 154 : + 155 80398 : if(memcmp(tag,computed_tag,tag_len)!=0) { + 156 23816 : memset(plaintext, 0, len); + 157 23816 : return -1; + 158 : } + 159 : + 160 56582 : uint8_t counter[16]; memcpy(counter,ctx->J0,16); + 161 56582 : ctr_increment(counter); + 162 : + 163 56582 : aes_ctr_crypt(ciphertext,plaintext,len,counter,aes_block_wrapper,&ctx->aes); + 164 : + 165 56582 : return 0; + 166 80398 : } ++ |
+
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| gmac_compute | + +37918 | + + + +
| gmac_init | + +37918 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| gmac_compute | + +37918 | + + + +
| gmac_init | + +37918 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : #include "gmac.h" + 2 : #include <string.h> + 3 : + 4 : /* Initialize GMAC context */ + 5 37918 : int gmac_init(struct gmac_ctx *ctx, + 6 : const uint8_t *key, size_t key_len, + 7 : const uint8_t *iv, size_t iv_len) { + 8 37918 : return gcm_init(&ctx->gcm, key, key_len, iv, iv_len); + 9 : } + 10 : + 11 : /* Compute GMAC tag (wraps GCM with empty plaintext) */ + 12 37918 : void gmac_compute(struct gmac_ctx *ctx, + 13 : const uint8_t *aad, size_t aad_len, + 14 : uint8_t *tag, size_t tag_len) { + 15 : // GMAC is just GCM with empty plaintext (len=0) + 16 : // We can pass NULL for both plaintext and ciphertext since len=0 + 17 37918 : gcm_encrypt(&ctx->gcm, NULL, 0, aad, aad_len, NULL, tag, tag_len); + 18 37918 : } ++ |
+
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| + | + | + | + | + | + | + | ||
| File |
+ Line Coverage |
+ Function Coverage |
+ ||||||
| Rate | +Total | +Hit | +Rate | +Total | +Hit | +|||
| key_expansion_128.c | +
+ |
+ 100.0 % | +26 | +26 | +100.0 % | +1 | +1 | +|
| key_expansion_192.c | +
+ |
+ 100.0 % | +27 | +27 | +100.0 % | +1 | +1 | +|
| aes_wrapper.c | +
+ |
+ 80.0 % | +20 | +16 | +100.0 % | +2 | +2 | +|
| cfb.c | +
+ |
+ 100.0 % | +22 | +22 | +100.0 % | +2 | +2 | +|
| ctr.c | +
+ |
+ 100.0 % | +22 | +22 | +100.0 % | +2 | +2 | +|
| ecb.c | +
+ |
+ 100.0 % | +12 | +12 | +100.0 % | +2 | +2 | +|
| gmac.c | +
+ |
+ 100.0 % | +5 | +5 | +100.0 % | +2 | +2 | +|
| ofb.c | +
+ |
+ 100.0 % | +17 | +17 | +100.0 % | +2 | +2 | +|
| sbox.c | +
+ |
+ 100.0 % | +18 | +18 | +100.0 % | +2 | +2 | +|
| key_expansion_256.c | +
+ |
+ 100.0 % | +38 | +38 | +100.0 % | +3 | +3 | +|
| cbc.c | +
+ |
+ 94.8 % | +58 | +55 | +100.0 % | +5 | +5 | +|
| cmac.c | +
+ |
+ 96.2 % | +53 | +51 | +100.0 % | +5 | +5 | +|
| xts.c | +
+ |
+ 100.0 % | +47 | +47 | +100.0 % | +5 | +5 | +|
| ccm.c | +
+ |
+ 95.6 % | +135 | +129 | +100.0 % | +6 | +6 | +|
| gcm.c | +
+ |
+ 99.0 % | +98 | +97 | +100.0 % | +6 | +6 | +|
| aes_256.c | +
+ |
+ 100.0 % | +110 | +110 | +100.0 % | +10 | +10 | +|
| aes_128.c | +
+ |
+ 100.0 % | +126 | +126 | +100.0 % | +11 | +11 | +|
| aes_192.c | +
+ |
+ 100.0 % | +126 | +126 | +100.0 % | +11 | +11 | +|
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| + | + | + | + | + | + | + | ||
| File |
+ Line Coverage |
+ Function Coverage |
+ ||||||
| Rate | +Total | +Hit | +Rate | +Total | +Hit | +|||
| aes_wrapper.c | +
+ |
+ 80.0 % | +20 | +16 | +100.0 % | +2 | +2 | +|
| cbc.c | +
+ |
+ 94.8 % | +58 | +55 | +100.0 % | +5 | +5 | +|
| ccm.c | +
+ |
+ 95.6 % | +135 | +129 | +100.0 % | +6 | +6 | +|
| cmac.c | +
+ |
+ 96.2 % | +53 | +51 | +100.0 % | +5 | +5 | +|
| gcm.c | +
+ |
+ 99.0 % | +98 | +97 | +100.0 % | +6 | +6 | +|
| gmac.c | +
+ |
+ 100.0 % | +5 | +5 | +100.0 % | +2 | +2 | +|
| ecb.c | +
+ |
+ 100.0 % | +12 | +12 | +100.0 % | +2 | +2 | +|
| ofb.c | +
+ |
+ 100.0 % | +17 | +17 | +100.0 % | +2 | +2 | +|
| sbox.c | +
+ |
+ 100.0 % | +18 | +18 | +100.0 % | +2 | +2 | +|
| cfb.c | +
+ |
+ 100.0 % | +22 | +22 | +100.0 % | +2 | +2 | +|
| ctr.c | +
+ |
+ 100.0 % | +22 | +22 | +100.0 % | +2 | +2 | +|
| key_expansion_128.c | +
+ |
+ 100.0 % | +26 | +26 | +100.0 % | +1 | +1 | +|
| key_expansion_192.c | +
+ |
+ 100.0 % | +27 | +27 | +100.0 % | +1 | +1 | +|
| key_expansion_256.c | +
+ |
+ 100.0 % | +38 | +38 | +100.0 % | +3 | +3 | +|
| xts.c | +
+ |
+ 100.0 % | +47 | +47 | +100.0 % | +5 | +5 | +|
| aes_256.c | +
+ |
+ 100.0 % | +110 | +110 | +100.0 % | +10 | +10 | +|
| aes_128.c | +
+ |
+ 100.0 % | +126 | +126 | +100.0 % | +11 | +11 | +|
| aes_192.c | +
+ |
+ 100.0 % | +126 | +126 | +100.0 % | +11 | +11 | +|
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| + | + | + | + | + | + | + | ||
| File |
+ Line Coverage |
+ Function Coverage |
+ ||||||
| Rate | +Total | +Hit | +Rate | +Total | +Hit | +|||
| aes_128.c | +
+ |
+ 100.0 % | +126 | +126 | +100.0 % | +11 | +11 | +|
| aes_192.c | +
+ |
+ 100.0 % | +126 | +126 | +100.0 % | +11 | +11 | +|
| aes_256.c | +
+ |
+ 100.0 % | +110 | +110 | +100.0 % | +10 | +10 | +|
| aes_wrapper.c | +
+ |
+ 80.0 % | +20 | +16 | +100.0 % | +2 | +2 | +|
| cbc.c | +
+ |
+ 94.8 % | +58 | +55 | +100.0 % | +5 | +5 | +|
| ccm.c | +
+ |
+ 95.6 % | +135 | +129 | +100.0 % | +6 | +6 | +|
| cfb.c | +
+ |
+ 100.0 % | +22 | +22 | +100.0 % | +2 | +2 | +|
| cmac.c | +
+ |
+ 96.2 % | +53 | +51 | +100.0 % | +5 | +5 | +|
| ctr.c | +
+ |
+ 100.0 % | +22 | +22 | +100.0 % | +2 | +2 | +|
| ecb.c | +
+ |
+ 100.0 % | +12 | +12 | +100.0 % | +2 | +2 | +|
| gcm.c | +
+ |
+ 99.0 % | +98 | +97 | +100.0 % | +6 | +6 | +|
| gmac.c | +
+ |
+ 100.0 % | +5 | +5 | +100.0 % | +2 | +2 | +|
| key_expansion_128.c | +
+ |
+ 100.0 % | +26 | +26 | +100.0 % | +1 | +1 | +|
| key_expansion_192.c | +
+ |
+ 100.0 % | +27 | +27 | +100.0 % | +1 | +1 | +|
| key_expansion_256.c | +
+ |
+ 100.0 % | +38 | +38 | +100.0 % | +3 | +3 | +|
| ofb.c | +
+ |
+ 100.0 % | +17 | +17 | +100.0 % | +2 | +2 | +|
| sbox.c | +
+ |
+ 100.0 % | +18 | +18 | +100.0 % | +2 | +2 | +|
| xts.c | +
+ |
+ 100.0 % | +47 | +47 | +100.0 % | +5 | +5 | +|
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| aes_key_expansion_128 | + +36284 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| aes_key_expansion_128 | + +36284 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : #include "key_expansion_128.h" + 2 : + 3 : static uint8_t rcon[11] = { + 4 : 0x00, // rcon[0] unused + 5 : 0x01, 0x02, 0x04, 0x08, + 6 : 0x10, 0x20, 0x40, 0x80, + 7 : 0x1B, 0x36 + 8 : }; + 9 : + 10 36284 : void aes_key_expansion_128(const uint8_t key[16], uint8_t round_keys[176], const uint8_t sbox[256]) { + 11 : // First 16 bytes are the original key + 12 616828 : for (int i = 0; i < 16; i++) { + 13 580544 : round_keys[i] = key[i]; + 14 580544 : } + 15 : + 16 : uint8_t temp[4]; + 17 36284 : int bytes_generated = 16; + 18 36284 : int rcon_idx = 1; + 19 : + 20 1487644 : while (bytes_generated < 176) { + 21 : // Last 4 bytes of previous key part + 22 7256800 : for (int i = 0; i < 4; i++) { + 23 5805440 : temp[i] = round_keys[bytes_generated - 4 + i]; + 24 5805440 : } + 25 : + 26 1451360 : if (bytes_generated % 16 == 0) { + 27 : // Rotate + 28 362840 : uint8_t t = temp[0]; + 29 362840 : temp[0] = temp[1]; + 30 362840 : temp[1] = temp[2]; + 31 362840 : temp[2] = temp[3]; + 32 362840 : temp[3] = t; + 33 : + 34 : // Apply S-box + 35 1814200 : for (int i = 0; i < 4; i++) { + 36 1451360 : temp[i] = sbox[temp[i]]; + 37 1451360 : } + 38 : + 39 : // XOR with rcon + 40 362840 : temp[0] ^= rcon[rcon_idx++]; + 41 362840 : } + 42 : + 43 : // XOR with 16 bytes earlier + 44 7256800 : for (int i = 0; i < 4; i++) { + 45 5805440 : round_keys[bytes_generated] = round_keys[bytes_generated - 16] ^ temp[i]; + 46 5805440 : bytes_generated++; + 47 5805440 : } + 48 : } + 49 36284 : } ++ |
+
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| aes_key_expansion_192 | + +36146 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| aes_key_expansion_192 | + +36146 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : #include <stdint.h> + 2 : #include "key_expansion_192.h" + 3 : #include "sbox.h" + 4 : + 5 : // AES-192 Key Expansion + 6 : // Input: 24 bytes (192 bits) + 7 : // Output: 208 bytes (13 round keys * 16 bytes) + 8 36146 : void aes_key_expansion_192(const uint8_t key[24], uint8_t round_keys[208], const uint8_t sbox[256]) { + 9 36146 : const uint8_t rcon[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; + 10 : + 11 : // Copy original key + 12 903650 : for (int i = 0; i < 24; i++) { + 13 867504 : round_keys[i] = key[i]; + 14 867504 : } + 15 : + 16 : // Generate remaining key material + 17 : // AES-192 needs 52 words (208 bytes) total + 18 : // We have 6 words already, need 46 more + 19 36146 : int bytes_generated = 24; + 20 36146 : int rcon_iteration = 0; + 21 : + 22 1698862 : while (bytes_generated < 208) { + 23 : uint8_t temp[4]; + 24 : + 25 : // Copy last 4 bytes of previous block + 26 8313580 : for (int i = 0; i < 4; i++) { + 27 6650864 : temp[i] = round_keys[bytes_generated - 4 + i]; + 28 6650864 : } + 29 : + 30 : // Every 6 words (24 bytes), apply core schedule + 31 1662716 : if (bytes_generated % 24 == 0) { + 32 : // RotWord + 33 289168 : uint8_t tmp = temp[0]; + 34 289168 : temp[0] = temp[1]; + 35 289168 : temp[1] = temp[2]; + 36 289168 : temp[2] = temp[3]; + 37 289168 : temp[3] = tmp; + 38 : + 39 : // SubWord + 40 1445840 : for (int i = 0; i < 4; i++) { + 41 1156672 : temp[i] = sbox[temp[i]]; + 42 1156672 : } + 43 : + 44 : // XOR with Rcon + 45 289168 : temp[0] ^= rcon[rcon_iteration++]; + 46 289168 : } + 47 : + 48 : // XOR with word from 6 positions back (24 bytes) + 49 8313580 : for (int i = 0; i < 4; i++) { + 50 6650864 : round_keys[bytes_generated] = round_keys[bytes_generated - 24] ^ temp[i]; + 51 6650864 : bytes_generated++; + 52 6650864 : } + 53 : } + 54 36146 : } ++ |
+
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| aes_key_expansion_256 | + +36236 | + + + +
| rot_word | + +253652 | + + + +
| sub_word | + +471068 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| aes_key_expansion_256 | + +36236 | + + + +
| rot_word | + +253652 | + + + +
| sub_word | + +471068 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : #include "key_expansion_256.h" + 2 : #include "aes_defs.h" // AES256_KEY_SIZE, AES256_EXPANDED_KEY_SIZE + 3 : #include <stdint.h> + 4 : + 5 : // AES-256 uses 8-word key, 14 rounds → 60 words total + 6 : // Rcon values + 7 : static const uint8_t rcon[15] = { + 8 : 0x00, // rcon[0] unused + 9 : 0x01, 0x02, 0x04, 0x08, + 10 : 0x10, 0x20, 0x40, 0x80, + 11 : 0x1B, 0x36, 0x6C, 0xD8, 0xAB + 12 : }; + 13 : + 14 : // Rotate a 4-byte word left + 15 253652 : static void rot_word(uint8_t w[4]) { + 16 253652 : uint8_t tmp = w[0]; + 17 253652 : w[0] = w[1]; + 18 253652 : w[1] = w[2]; + 19 253652 : w[2] = w[3]; + 20 253652 : w[3] = tmp; + 21 253652 : } + 22 : + 23 : // Apply S-box to 4-byte word + 24 471068 : static void sub_word(uint8_t w[4], const uint8_t sbox[256]) { + 25 2355340 : for (int i = 0; i < 4; i++) { + 26 1884272 : w[i] = sbox[w[i]]; + 27 1884272 : } + 28 471068 : } + 29 : + 30 36236 : void aes_key_expansion_256(const uint8_t key[AES256_KEY_SIZE], + 31 : uint8_t round_keys[AES256_EXPANDED_KEY_SIZE], + 32 : const uint8_t sbox[256]) + 33 : { + 34 36236 : int Nk = 8; // number of 32-bit words in key + 35 36236 : int Nr = 14; // number of rounds + 36 36236 : int Nb = 4; // number of words per block (AES standard) + 37 : + 38 : // Copy original key (32 bytes) into first 8 words + 39 1195788 : for (int i = 0; i < Nk * 4; i++) { + 40 1159552 : round_keys[i] = key[i]; + 41 1159552 : } + 42 : + 43 : uint8_t temp[4]; + 44 36236 : int bytes_generated = Nk * 4; // 32 + 45 36236 : int rcon_idx = 1; + 46 : + 47 1920508 : while (bytes_generated < Nb * (Nr + 1) * 4) { // 4*(Nr+1)*Nb = 240 + 48 : // Copy previous word into temp + 49 9421360 : for (int i = 0; i < 4; i++) { + 50 7537088 : temp[i] = round_keys[bytes_generated - 4 + i]; + 51 7537088 : } + 52 : + 53 1884272 : int word_index = bytes_generated / 4; + 54 : + 55 1884272 : if (word_index % Nk == 0) { + 56 253652 : rot_word(temp); + 57 253652 : sub_word(temp, sbox); + 58 253652 : temp[0] ^= rcon[rcon_idx++]; + 59 1884272 : } else if (Nk > 6 && word_index % Nk == 4) { + 60 217416 : sub_word(temp, sbox); + 61 217416 : } + 62 : + 63 : // XOR with word Nk positions earlier + 64 9421360 : for (int i = 0; i < 4; i++) { + 65 7537088 : round_keys[bytes_generated] = round_keys[bytes_generated - Nk * 4] ^ temp[i]; + 66 7537088 : bytes_generated++; + 67 7537088 : } + 68 : } + 69 36236 : } ++ |
+
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| aes_ofb_decrypt | + +2 | + + + +
| aes_ofb_encrypt | + +4 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| aes_ofb_decrypt | + +2 | + + + +
| aes_ofb_encrypt | + +4 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : #include "ofb.h" + 2 : #include <string.h> + 3 : #include "aes_wrapper.h" // for aes_block_wrapper + 4 : + 5 4 : void aes_ofb_encrypt( + 6 : const uint8_t *plaintext, + 7 : uint8_t *ciphertext, + 8 : size_t length, + 9 : const uint8_t iv[16], + 10 : const void *ctx + 11 : ) { + 12 : uint8_t feedback[16]; + 13 : uint8_t keystream[16]; + 14 4 : size_t processed = 0; + 15 : + 16 4 : memcpy(feedback, iv, 16); + 17 : + 18 20 : while (processed < length) { + 19 16 : aes_block_wrapper(feedback, keystream, ctx); + 20 : + 21 16 : size_t chunk = 16; + 22 16 : if (length - processed < 16) chunk = length - processed; + 23 : + 24 272 : for (size_t i = 0; i < chunk; ++i) + 25 256 : ciphertext[processed + i] = plaintext[processed + i] ^ keystream[i]; + 26 : + 27 16 : memcpy(feedback, keystream, 16); + 28 16 : processed += chunk; + 29 : } + 30 : + 31 4 : memset(feedback, 0, 16); + 32 4 : memset(keystream, 0, 16); + 33 4 : } + 34 : + 35 2 : void aes_ofb_decrypt( + 36 : const uint8_t *ciphertext, + 37 : uint8_t *plaintext, + 38 : size_t length, + 39 : const uint8_t iv[16], + 40 : const void *ctx + 41 : ) { + 42 : // OFB decryption is identical to encryption + 43 2 : aes_ofb_encrypt(ciphertext, plaintext, length, iv, ctx); + 44 2 : } ++ |
+
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| initialize_inverse_sbox | + +54 | + + + +
| initialize_aes_sbox | + +108642 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| initialize_aes_sbox | + +108642 | + + + +
| initialize_inverse_sbox | + +54 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : #include "../include/sbox.h" + 2 : #include <stdint.h> + 3 : #include <stdio.h> + 4 : + 5 : #define ROTL8(x,shift) ((uint8_t) (((x) << (shift)) | ((x) >> (8 - (shift))))) + 6 : + 7 108642 : void initialize_aes_sbox(uint8_t sbox[256]) { + 8 108642 : uint8_t p = 1, q = 1; + 9 : + 10 108642 : do { + 11 27703710 : p = p ^ (p << 1) ^ (p & 0x80 ? 0x1B : 0); + 12 : + 13 27703710 : q ^= q << 1; + 14 27703710 : q ^= q << 2; + 15 27703710 : q ^= q << 4; + 16 27703710 : q ^= (q & 0x80 ? 0x09 : 0); + 17 : + 18 27703710 : uint8_t xformed = q ^ ROTL8(q,1) ^ ROTL8(q,2) ^ ROTL8(q,3) ^ ROTL8(q,4); + 19 27703710 : sbox[p] = xformed ^ 0x63; + 20 27703710 : } while (p != 1); + 21 : + 22 108642 : sbox[0] = 0x63; + 23 108642 : } + 24 : + 25 54 : void initialize_inverse_sbox(const uint8_t sbox[256], uint8_t inv_sbox[256]) { + 26 13878 : for (int i = 0; i < 256; i++) { + 27 13824 : inv_sbox[sbox[i]] = (uint8_t)i; + 28 13824 : } + 29 54 : } ++ |
+
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| xts_decrypt | + +10 | + + + +
| encode_data_unit_be64 | + +20 | + + + +
| xts_encrypt | + +20 | + + + +
| multiply_by_x | + +72 | + + + +
| xor16 | + +144 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| encode_data_unit_be64 | + +20 | + + + +
| multiply_by_x | + +72 | + + + +
| xor16 | + +144 | + + + +
| xts_decrypt | + +10 | + + + +
| xts_encrypt | + +20 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : #include "xts.h" + 2 : #include <string.h> + 3 : + 4 : /* -------------------------------------------------------------------------*/ + 5 : /* local helpers */ + 6 : + 7 : /* XOR 16 bytes: out = a ^ b */ + 8 144 : static inline void xor16(const uint8_t a[16], const uint8_t b[16], uint8_t out[16]) { + 9 2448 : for (int i = 0; i < 16; ++i) out[i] = a[i] ^ b[i]; + 10 144 : } + 11 : + 12 : /* + 13 : * multiply_by_x: multiply 128-bit tweak (MSB in byte 0) by x in GF(2^128) + 14 : * Reduction polynomial: x^128 + x^7 + x^2 + x + 1 -> reduction constant 0x87 + 15 : */ + 16 72 : static void multiply_by_x(uint8_t tweak[16]) { + 17 72 : uint8_t carry = 0; + 18 1224 : for (int i = 15; i >= 0; --i) { + 19 1152 : uint8_t next_carry = (tweak[i] & 0x80) ? 1 : 0; + 20 1152 : tweak[i] = (uint8_t)((tweak[i] << 1) | carry); + 21 1152 : carry = next_carry; + 22 1152 : } + 23 72 : if (carry) tweak[15] ^= 0x87; + 24 72 : } + 25 : + 26 : /* + 27 : * encode_data_unit_be64: places 64-bit data_unit into tweak_plain[16] as a + 28 : * 128-bit big-endian integer with high 64 bits zero and low 64 bits = data_unit. + 29 : */ + 30 20 : static void encode_data_unit_be64(uint8_t tweak_plain[16], uint64_t data_unit) { + 31 20 : memset(tweak_plain, 0, 8); + 32 180 : for (int i = 0; i < 8; ++i) { + 33 160 : tweak_plain[8 + 7 - i] = (uint8_t)(data_unit & 0xFF); + 34 160 : data_unit >>= 8; + 35 160 : } + 36 20 : } + 37 : + 38 : /* -------------------------------------------------------------------------*/ + 39 : /* XTS encryption */ + 40 : + 41 20 : int xts_encrypt(aes_block_fn aes_enc, const void *key1_ctx, + 42 : aes_block_fn aes_tweak, const void *key2_ctx, + 43 : uint64_t data_unit, + 44 : const uint8_t *plaintext, size_t pt_len, uint8_t *ciphertext) + 45 : { + 46 20 : if (!aes_enc || !aes_tweak || !plaintext || !ciphertext) return XTS_ERR_ARG; + 47 20 : if (pt_len < 16 || pt_len % 16 != 0) return XTS_ERR_INVALID; + 48 : + 49 10 : size_t n_blocks = pt_len / 16; + 50 : + 51 : uint8_t tweak[16], tweak_plain[16]; + 52 10 : encode_data_unit_be64(tweak_plain, data_unit); + 53 10 : aes_tweak(tweak_plain, tweak, key2_ctx); + 54 : + 55 46 : for (size_t i = 0; i < n_blocks; ++i) { + 56 : uint8_t tmp[16], out[16]; + 57 36 : xor16(plaintext + i*16, tweak, tmp); + 58 36 : aes_enc(tmp, out, key1_ctx); + 59 36 : xor16(out, tweak, ciphertext + i*16); + 60 36 : multiply_by_x(tweak); + 61 36 : } + 62 : + 63 10 : return XTS_OK; + 64 20 : } + 65 : + 66 : /* -------------------------------------------------------------------------*/ + 67 : /* XTS decryption */ + 68 : + 69 10 : int xts_decrypt(aes_block_fn aes_dec, const void *key1_ctx, + 70 : aes_block_fn aes_tweak, const void *key2_ctx, + 71 : uint64_t data_unit, + 72 : const uint8_t *ciphertext, size_t ct_len, uint8_t *plaintext) + 73 : { + 74 10 : if (!aes_dec || !aes_tweak || !plaintext || !ciphertext) return XTS_ERR_ARG; + 75 10 : if (ct_len < 16 || ct_len % 16 != 0) return XTS_ERR_INVALID; + 76 : + 77 10 : size_t n_blocks = ct_len / 16; + 78 : + 79 : uint8_t tweak[16], tweak_plain[16]; + 80 10 : encode_data_unit_be64(tweak_plain, data_unit); + 81 10 : aes_tweak(tweak_plain, tweak, key2_ctx); + 82 : + 83 46 : for (size_t i = 0; i < n_blocks; ++i) { + 84 : uint8_t tmp[16], out[16]; + 85 36 : xor16(ciphertext + i*16, tweak, tmp); + 86 36 : aes_dec(tmp, out, key1_ctx); + 87 36 : xor16(out, tweak, plaintext + i*16); + 88 36 : multiply_by_x(tweak); + 89 36 : } + 90 : + 91 10 : return XTS_OK; + 92 10 : } ++ |
+
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| + | + | + | + | + | + | + | ||
| File |
+ Line Coverage |
+ Function Coverage |
+ ||||||
| Rate | +Total | +Hit | +Rate | +Total | +Hit | +|||
| test_gcm.c | +
+ |
+ 81.6 % | +125 | +102 | +83.3 % | +6 | +5 | +|
| test_gmac.c | +
+ |
+ 78.4 % | +116 | +91 | +83.3 % | +6 | +5 | +|
| test_aes_128.c | +
+ |
+ 93.8 % | +16 | +15 | +100.0 % | +1 | +1 | +|
| test_aes_192.c | +
+ |
+ 86.7 % | +45 | +39 | +100.0 % | +1 | +1 | +|
| test_aes_256.c | +
+ |
+ 86.7 % | +45 | +39 | +100.0 % | +1 | +1 | +|
| test_cfb.c | +
+ |
+ 88.9 % | +18 | +16 | +100.0 % | +1 | +1 | +|
| test_ctr.c | +
+ |
+ 90.9 % | +22 | +20 | +100.0 % | +1 | +1 | +|
| test_ecb.c | +
+ |
+ 84.6 % | +26 | +22 | +100.0 % | +1 | +1 | +|
| test_ofb.c | +
+ |
+ 84.6 % | +26 | +22 | +100.0 % | +1 | +1 | +|
| test_cbc.c | +
+ |
+ 80.6 % | +31 | +25 | +100.0 % | +2 | +2 | +|
| test_ccm.c | +
+ |
+ 86.7 % | +45 | +39 | +100.0 % | +2 | +2 | +|
| test_cmac.c | +
+ |
+ 92.9 % | +28 | +26 | +100.0 % | +2 | +2 | +|
| test_xts.c | +
+ |
+ 78.7 % | +47 | +37 | +100.0 % | +2 | +2 | +|
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| + | + | + | + | + | + | + | ||
| File |
+ Line Coverage |
+ Function Coverage |
+ ||||||
| Rate | +Total | +Hit | +Rate | +Total | +Hit | +|||
| test_gmac.c | +
+ |
+ 78.4 % | +116 | +91 | +83.3 % | +6 | +5 | +|
| test_xts.c | +
+ |
+ 78.7 % | +47 | +37 | +100.0 % | +2 | +2 | +|
| test_cbc.c | +
+ |
+ 80.6 % | +31 | +25 | +100.0 % | +2 | +2 | +|
| test_gcm.c | +
+ |
+ 81.6 % | +125 | +102 | +83.3 % | +6 | +5 | +|
| test_ecb.c | +
+ |
+ 84.6 % | +26 | +22 | +100.0 % | +1 | +1 | +|
| test_ofb.c | +
+ |
+ 84.6 % | +26 | +22 | +100.0 % | +1 | +1 | +|
| test_aes_192.c | +
+ |
+ 86.7 % | +45 | +39 | +100.0 % | +1 | +1 | +|
| test_aes_256.c | +
+ |
+ 86.7 % | +45 | +39 | +100.0 % | +1 | +1 | +|
| test_ccm.c | +
+ |
+ 86.7 % | +45 | +39 | +100.0 % | +2 | +2 | +|
| test_cfb.c | +
+ |
+ 88.9 % | +18 | +16 | +100.0 % | +1 | +1 | +|
| test_ctr.c | +
+ |
+ 90.9 % | +22 | +20 | +100.0 % | +1 | +1 | +|
| test_cmac.c | +
+ |
+ 92.9 % | +28 | +26 | +100.0 % | +2 | +2 | +|
| test_aes_128.c | +
+ |
+ 93.8 % | +16 | +15 | +100.0 % | +1 | +1 | +|
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| + | + | + | + | + | + | + | ||
| File |
+ Line Coverage |
+ Function Coverage |
+ ||||||
| Rate | +Total | +Hit | +Rate | +Total | +Hit | +|||
| test_aes_128.c | +
+ |
+ 93.8 % | +16 | +15 | +100.0 % | +1 | +1 | +|
| test_aes_192.c | +
+ |
+ 86.7 % | +45 | +39 | +100.0 % | +1 | +1 | +|
| test_aes_256.c | +
+ |
+ 86.7 % | +45 | +39 | +100.0 % | +1 | +1 | +|
| test_cbc.c | +
+ |
+ 80.6 % | +31 | +25 | +100.0 % | +2 | +2 | +|
| test_ccm.c | +
+ |
+ 86.7 % | +45 | +39 | +100.0 % | +2 | +2 | +|
| test_cfb.c | +
+ |
+ 88.9 % | +18 | +16 | +100.0 % | +1 | +1 | +|
| test_cmac.c | +
+ |
+ 92.9 % | +28 | +26 | +100.0 % | +2 | +2 | +|
| test_ctr.c | +
+ |
+ 90.9 % | +22 | +20 | +100.0 % | +1 | +1 | +|
| test_ecb.c | +
+ |
+ 84.6 % | +26 | +22 | +100.0 % | +1 | +1 | +|
| test_gcm.c | +
+ |
+ 81.6 % | +125 | +102 | +83.3 % | +6 | +5 | +|
| test_gmac.c | +
+ |
+ 78.4 % | +116 | +91 | +83.3 % | +6 | +5 | +|
| test_ofb.c | +
+ |
+ 84.6 % | +26 | +22 | +100.0 % | +1 | +1 | +|
| test_xts.c | +
+ |
+ 78.7 % | +47 | +37 | +100.0 % | +2 | +2 | +|
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| main | + +1 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| main | + +1 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : #include <stdio.h> + 2 : #include <stdint.h> + 3 : #include <string.h> + 4 : #include "../include/aes_128.h" + 5 : #include "../include/key_expansion_128.h" + 6 : #include "../include/sbox.h" + 7 : + 8 1 : int main(void) { + 9 1 : uint8_t key[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + 10 : uint8_t round_keys[176]; + 11 : uint8_t sbox[256]; + 12 1 : uint8_t block[16] = "Hello AES Block!"; + 13 : uint8_t enc[16], dec[16]; + 14 : + 15 1 : initialize_aes_sbox(sbox); + 16 1 : aes_key_expansion_128(key, round_keys, sbox); + 17 : + 18 1 : aes128_encrypt_block(block, enc, round_keys, sbox); + 19 1 : aes128_decrypt_block(enc, dec, round_keys, sbox); + 20 : + 21 1 : if(memcmp(block, dec, 16) == 0) { + 22 1 : printf("AES core round-trip OK\n"); + 23 1 : } else { + 24 0 : printf("AES core FAILED\n"); + 25 : } + 26 : + 27 1 : printf("Plaintext: %s\n", block); + 28 1 : printf("Ciphertext: "); + 29 17 : for(int i=0;i<16;i++) printf("%02x", enc[i]); + 30 1 : printf("\n"); + 31 : + 32 1 : return 0; + 33 : } ++ |
+
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| main | + +1 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| main | + +1 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : #include <stdio.h> + 2 : #include <stdint.h> + 3 : #include <string.h> + 4 : #include "../include/aes_192.h" + 5 : #include "../include/key_expansion_192.h" + 6 : #include "../include/sbox.h" + 7 : + 8 1 : int main(void) { + 9 : // 192-bit key (24 bytes) + 10 1 : uint8_t key[24] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23}; + 11 : uint8_t round_keys[208]; // 13 round keys * 16 bytes + 12 : uint8_t sbox[256]; + 13 1 : uint8_t block[16] = "Hello AES Block!"; + 14 : uint8_t enc[16], dec[16]; + 15 : + 16 1 : initialize_aes_sbox(sbox); + 17 1 : aes_key_expansion_192(key, round_keys, sbox); + 18 : + 19 1 : printf("=== AES-192 Test ===\n"); + 20 1 : printf("Key length: 192 bits (24 bytes)\n"); + 21 1 : printf("Rounds: 12\n\n"); + 22 : + 23 1 : aes192_encrypt_block(block, enc, round_keys, sbox); + 24 1 : aes192_decrypt_block(enc, dec, round_keys, sbox); + 25 : + 26 1 : if(memcmp(block, dec, 16) == 0) { + 27 1 : printf("✓ AES-192 core round-trip OK\n"); + 28 1 : } else { + 29 0 : printf("✗ AES-192 core FAILED\n"); + 30 0 : return 1; + 31 : } + 32 : + 33 1 : printf("\nPlaintext: %s\n", block); + 34 1 : printf("Ciphertext: "); + 35 17 : for(int i=0; i<16; i++) printf("%02x", enc[i]); + 36 1 : printf("\n"); + 37 1 : printf("Decrypted: %s\n", dec); + 38 : + 39 : // Test with known NIST test vector for AES-192 + 40 1 : printf("\n=== NIST Test Vector ===\n"); + 41 1 : uint8_t nist_key[24] = { + 42 : 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, + 43 : 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, + 44 : 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b + 45 : }; + 46 1 : uint8_t nist_pt[16] = { + 47 : 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 48 : 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a + 49 : }; + 50 1 : uint8_t nist_expected_ct[16] = { + 51 : 0xbd, 0x33, 0x4f, 0x1d, 0x6e, 0x45, 0xf2, 0x5f, + 52 : 0xf7, 0x12, 0xa2, 0x14, 0x57, 0x1f, 0xa5, 0xcc + 53 : }; + 54 : uint8_t nist_ct[16], nist_dec[16]; + 55 : + 56 1 : aes_key_expansion_192(nist_key, round_keys, sbox); + 57 1 : aes192_encrypt_block(nist_pt, nist_ct, round_keys, sbox); + 58 1 : aes192_decrypt_block(nist_ct, nist_dec, round_keys, sbox); + 59 : + 60 1 : printf("Expected CT: "); + 61 17 : for(int i=0; i<16; i++) printf("%02x", nist_expected_ct[i]); + 62 1 : printf("\nComputed CT: "); + 63 17 : for(int i=0; i<16; i++) printf("%02x", nist_ct[i]); + 64 1 : printf("\n"); + 65 : + 66 1 : if(memcmp(nist_ct, nist_expected_ct, 16) == 0) { + 67 1 : printf("✓ NIST test vector PASSED\n"); + 68 1 : } else { + 69 0 : printf("✗ NIST test vector FAILED\n"); + 70 0 : return 1; + 71 : } + 72 : + 73 1 : if(memcmp(nist_pt, nist_dec, 16) == 0) { + 74 1 : printf("✓ NIST decryption PASSED\n"); + 75 1 : } else { + 76 0 : printf("✗ NIST decryption FAILED\n"); + 77 0 : return 1; + 78 : } + 79 : + 80 1 : printf("\n=== All AES-192 tests passed! ===\n"); + 81 1 : return 0; + 82 1 : } ++ |
+
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| main | + +1 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| main | + +1 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : #include <stdio.h> + 2 : #include <stdint.h> + 3 : #include <string.h> + 4 : #include "../include/aes_256.h" + 5 : #include "../include/key_expansion_256.h" + 6 : #include "../include/sbox.h" + 7 : + 8 1 : int main(void) { + 9 : // 256-bit key (32 bytes) + 10 1 : uint8_t key[32] = { + 11 : 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 12 : 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 + 13 : }; + 14 : uint8_t round_keys[240]; // 15 round keys * 16 bytes + 15 : uint8_t sbox[256]; + 16 1 : uint8_t block[16] = "Hello AES Block!"; + 17 : uint8_t enc[16], dec[16]; + 18 : + 19 1 : initialize_aes_sbox(sbox); + 20 1 : aes_key_expansion_256(key, round_keys, sbox); + 21 : + 22 1 : printf("=== AES-256 Test ===\n"); + 23 1 : printf("Key length: 256 bits (32 bytes)\n"); + 24 1 : printf("Rounds: 14\n\n"); + 25 : + 26 1 : aes256_encrypt_block(block, enc, round_keys, sbox); + 27 1 : aes256_decrypt_block(enc, dec, round_keys, sbox); + 28 : + 29 1 : if(memcmp(block, dec, 16) == 0) { + 30 1 : printf("AES-256 core round-trip OK\n"); + 31 1 : } else { + 32 0 : printf("AES-256 core FAILED\n"); + 33 0 : return 1; + 34 : } + 35 : + 36 1 : printf("\nPlaintext: %s\n", block); + 37 1 : printf("Ciphertext: "); + 38 17 : for(int i=0; i<16; i++) printf("%02x", enc[i]); + 39 1 : printf("\n"); + 40 1 : printf("Decrypted: %s\n", dec); + 41 : + 42 : // Test with known NIST test vector for AES-256 + 43 1 : printf("\n=== NIST Test Vector ===\n"); + 44 1 : uint8_t nist_key[32] = { + 45 : 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, + 46 : 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 47 : 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, + 48 : 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 + 49 : }; + 50 1 : uint8_t nist_pt[16] = { + 51 : 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 52 : 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a + 53 : }; + 54 1 : uint8_t nist_expected_ct[16] = { + 55 : 0xf3, 0xee, 0xd1, 0xbd, 0xb5, 0xd2, 0xa0, 0x3c, + 56 : 0x06, 0x4b, 0x5a, 0x7e, 0x3d, 0xb1, 0x81, 0xf8 + 57 : }; + 58 : uint8_t nist_ct[16], nist_dec[16]; + 59 : + 60 1 : aes_key_expansion_256(nist_key, round_keys, sbox); + 61 1 : aes256_encrypt_block(nist_pt, nist_ct, round_keys, sbox); + 62 1 : aes256_decrypt_block(nist_ct, nist_dec, round_keys, sbox); + 63 : + 64 1 : printf("Expected CT: "); + 65 17 : for(int i=0; i<16; i++) printf("%02x", nist_expected_ct[i]); + 66 1 : printf("\nComputed CT: "); + 67 17 : for(int i=0; i<16; i++) printf("%02x", nist_ct[i]); + 68 1 : printf("\n"); + 69 : + 70 1 : if(memcmp(nist_ct, nist_expected_ct, 16) == 0) { + 71 1 : printf("NIST test vector PASSED\n"); + 72 1 : } else { + 73 0 : printf("NIST test vector FAILED\n"); + 74 0 : return 1; + 75 : } + 76 : + 77 1 : if(memcmp(nist_pt, nist_dec, 16) == 0) { + 78 1 : printf("NIST decryption PASSED\n"); + 79 1 : } else { + 80 0 : printf("NIST decryption FAILED\n"); + 81 0 : return 1; + 82 : } + 83 : + 84 1 : printf("\n=== All AES-256 tests passed! ===\n"); + 85 1 : return 0; + 86 1 : } ++ |
+
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| main | + +1 | + + + +
| print_hex | + +1 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| main | + +1 | + + + +
| print_hex | + +1 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : #include <stdio.h> + 2 : #include <stdint.h> + 3 : #include <string.h> + 4 : + 5 : #include "../include/cbc.h" + 6 : #include "../include/aes_wrapper.h" + 7 : #include "../include/aes_128.h" + 8 : #include "../include/key_expansion_128.h" + 9 : #include "../include/sbox.h" + 10 : + 11 : /* helper to print hex */ + 12 1 : static void print_hex(const uint8_t *buf, size_t len) { + 13 49 : for (size_t i = 0; i < len; ++i) printf("%02x", buf[i]); + 14 1 : printf("\n"); + 15 1 : } + 16 : + 17 1 : int main(void) { + 18 1 : uint8_t key[16] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 19 : 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; + 20 : uint8_t round_keys[176]; + 21 : uint8_t sbox[256]; + 22 1 : initialize_aes_sbox(sbox); + 23 1 : aes_key_expansion_128(key, round_keys, sbox); + 24 : + 25 1 : struct aes_ctx ctx = { .round_keys = round_keys, .sbox = sbox, .key_len = 16}; + 26 : + 27 1 : const uint8_t pt[] = "Hello AES-CBC, this is 37 bytes long.."; + 28 1 : size_t pt_len = strlen((const char*)pt); + 29 : + 30 1 : uint8_t ciphertext[256] = {0}; + 31 1 : size_t ct_len = 0; + 32 1 : uint8_t recovered[256] = {0}; + 33 1 : size_t rec_len = 0; + 34 : + 35 1 : uint8_t iv[16] = {0x00,0x01,0x02,0x03, 0x04,0x05,0x06,0x07, + 36 : 0x08,0x09,0x0a,0x0b, 0x0c,0x0d,0x0e,0x0f}; + 37 : + 38 1 : if (aes_cbc_encrypt(pt, pt_len, ciphertext, &ct_len, iv, aes_block_wrapper, &ctx) != 0) { + 39 0 : fprintf(stderr, "CBC encrypt failed\n"); + 40 0 : return 2; + 41 : } + 42 : + 43 1 : if (aes_cbc_decrypt(ciphertext, ct_len, recovered, &rec_len, iv, aes_block_wrapper_dec, &ctx) != 0) { + 44 0 : fprintf(stderr, "CBC decrypt failed\n"); + 45 0 : return 3; + 46 : } + 47 : + 48 1 : if (rec_len != pt_len || memcmp(pt, recovered, pt_len) != 0) { + 49 0 : fprintf(stderr, "CBC round-trip FAILED\n"); + 50 0 : return 4; + 51 : } + 52 : + 53 1 : printf("CBC round-trip OK — plaintext recovered correctly.\n"); + 54 1 : printf("Plaintext: '%s'\n", (char*)pt); + 55 1 : printf("Ciphertext (hex): "); + 56 1 : print_hex(ciphertext, ct_len); + 57 : + 58 1 : return 0; + 59 1 : } ++ |
+
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| main | + +1 | + + + +
| run_vector | + +3 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| main | + +1 | + + + +
| run_vector | + +3 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : #include <stdio.h> + 2 : #include <string.h> + 3 : #include "ccm.h" + 4 : #include "aes_wrapper.h" + 5 : #include "aes_128.h" + 6 : #include "key_expansion_128.h" + 7 : #include "sbox.h" + 8 : #include "test_ccm.h" + 9 : + 10 3 : static int run_vector(struct aes_ctx *ctx, + 11 : const uint8_t *nonce, size_t n, + 12 : const uint8_t *aad, size_t aad_len, + 13 : const uint8_t *pt, size_t pt_len, + 14 : const uint8_t *expected_ct, size_t ct_len, + 15 : size_t tag_len) + 16 : { + 17 3 : uint8_t ciphertext[256] = {0}; + 18 3 : size_t ciphertext_len = 0; + 19 : + 20 3 : int ret = ccm_encrypt( + 21 3 : (const uint8_t *)ctx, // pass pointer to aes_ctx + 22 : aes_block_wrapper, + 23 3 : nonce, n, + 24 3 : aad, aad_len, + 25 3 : pt, pt_len, + 26 3 : ciphertext, &ciphertext_len, + 27 3 : tag_len + 28 : ); + 29 : + 30 3 : if (ret != 0) { printf("[-] Encryption failed\n"); return 0; } + 31 : + 32 3 : if (ciphertext_len != ct_len || memcmp(ciphertext, expected_ct, ct_len) != 0) { + 33 0 : printf("[-] Ciphertext mismatch\n"); return 0; + 34 : } + 35 : + 36 3 : uint8_t decrypted[256] = {0}; + 37 3 : size_t decrypted_len = 0; + 38 : + 39 3 : ret = ccm_decrypt( + 40 3 : (const uint8_t *)ctx, + 41 : aes_block_wrapper, + 42 3 : nonce, n, + 43 3 : aad, aad_len, + 44 3 : ciphertext, ciphertext_len, + 45 3 : decrypted, &decrypted_len, + 46 3 : tag_len + 47 : ); + 48 : + 49 3 : if (ret != 0) { printf("[-] Decryption failed\n"); return 0; } + 50 : + 51 3 : if (decrypted_len != pt_len || memcmp(decrypted, pt, pt_len) != 0) { + 52 0 : printf("[-] Plaintext mismatch\n"); return 0; + 53 : } + 54 : + 55 3 : return 1; + 56 3 : } + 57 : + 58 1 : int main(void) + 59 : { + 60 : uint8_t round_keys[176]; + 61 : uint8_t sbox[256]; + 62 1 : initialize_aes_sbox(sbox); + 63 1 : aes_key_expansion_128(CCM_KEY, round_keys, sbox); + 64 : + 65 1 : struct aes_ctx ctx = { .round_keys = round_keys, .sbox = sbox, .key_len = 16}; + 66 : + 67 1 : int pass = 1; + 68 : + 69 1 : printf("[TEST] CCM Example 1\n"); + 70 1 : if (!run_vector(&ctx, + 71 : CCM_EX1_NONCE, CCM_EX1_NONCE_LEN, + 72 : CCM_EX1_AAD, CCM_EX1_AAD_LEN, + 73 : CCM_EX1_P, CCM_EX1_P_LEN, + 74 : CCM_EX1_C, CCM_EX1_C_LEN, + 75 0 : CCM_EX1_TAG_LEN)) pass = 0; + 76 : + 77 1 : printf("[TEST] CCM Example 2\n"); + 78 1 : if (!run_vector(&ctx, + 79 : CCM_EX2_NONCE, CCM_EX2_NONCE_LEN, + 80 : CCM_EX2_AAD, CCM_EX2_AAD_LEN, + 81 : CCM_EX2_P, CCM_EX2_P_LEN, + 82 : CCM_EX2_C, CCM_EX2_C_LEN, + 83 0 : CCM_EX2_TAG_LEN)) pass = 0; + 84 : + 85 1 : printf("[TEST] CCM Example 3\n"); + 86 1 : if (!run_vector(&ctx, + 87 : CCM_EX3_NONCE, CCM_EX3_NONCE_LEN, + 88 : CCM_EX3_AAD, CCM_EX3_AAD_LEN, + 89 : CCM_EX3_P, CCM_EX3_P_LEN, + 90 : CCM_EX3_C, CCM_EX3_C_LEN, + 91 0 : CCM_EX3_TAG_LEN)) pass = 0; + 92 : + 93 1 : if (pass) + 94 1 : printf("[+] CCM tests PASSED\n"); + 95 : else + 96 0 : printf("[-] CCM tests FAILED\n"); + 97 : + 98 1 : return pass ? 0 : 1; + 99 : } ++ |
+
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| main | + +1 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| main | + +1 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : #include <stdio.h> + 2 : #include <stdint.h> + 3 : #include <string.h> + 4 : #include "../include/cfb.h" + 5 : #include "../include/aes_wrapper.h" + 6 : #include "../include/key_expansion_128.h" + 7 : #include "../include/sbox.h" + 8 : + 9 1 : int main(void) { + 10 1 : uint8_t key[16] = {0}; + 11 1 : uint8_t iv[16] = {0}; + 12 1 : uint8_t plaintext[] = "CFB mode test message"; + 13 1 : size_t len = strlen((char*)plaintext); + 14 : + 15 1 : uint8_t ciphertext[64] = {0}; + 16 1 : uint8_t decrypted[64] = {0}; + 17 : + 18 : uint8_t round_keys[176]; + 19 : uint8_t sbox[256]; + 20 : + 21 : //initialize the sbox + 22 1 : initialize_aes_sbox(sbox); + 23 : + 24 : // Expand the key for encryption + 25 1 : aes_key_expansion_128(key, round_keys, sbox); + 26 : + 27 1 : struct aes_ctx ctx = { .round_keys = round_keys, .sbox = sbox, .key_len = 16}; + 28 : + 29 1 : aes_cfb_encrypt(plaintext, ciphertext, len, iv, &ctx); + 30 1 : aes_cfb_decrypt(ciphertext, decrypted, len, iv, &ctx); + 31 : + 32 1 : if (memcmp(plaintext, decrypted, len) == 0) { + 33 1 : printf("[+] CFB test passed: %s\n", decrypted); + 34 1 : return 0; + 35 : } else { + 36 0 : printf("[-] CFB test failed!\n"); + 37 0 : return 1; + 38 : } + 39 1 : } ++ |
+
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| main | + +1 | + + + +
| check_result | + +4 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| check_result | + +4 | + + + +
| main | + +1 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : #include <stdio.h> + 2 : #include <stdint.h> + 3 : #include <string.h> + 4 : + 5 : #include "../include/cmac.h" + 6 : #include "../include/aes_wrapper.h" + 7 : #include "../include/aes_128.h" + 8 : #include "../include/key_expansion_128.h" + 9 : #include "../include/sbox.h" + 10 : + 11 : /* Compare and print result; returns 1 if failure, 0 if OK */ + 12 4 : static int check_result(const char *label, const uint8_t *got, const uint8_t *exp, size_t len) { + 13 4 : if (memcmp(got, exp, len) == 0) { + 14 4 : printf("[+] %s OK\n", label); + 15 4 : return 0; + 16 : } else { + 17 0 : printf("[-] %s FAILED\n", label); + 18 0 : return 1; + 19 : } + 20 4 : } + 21 : + 22 1 : int main(void) { + 23 1 : uint8_t key[16] = { + 24 : 0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6, + 25 : 0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c + 26 : }; + 27 : uint8_t round_keys[176]; + 28 : uint8_t sbox[256]; + 29 1 : initialize_aes_sbox(sbox); + 30 1 : aes_key_expansion_128(key, round_keys, sbox); + 31 1 : struct aes_ctx ctx = { .round_keys = round_keys, .sbox = sbox, .key_len = 16}; + 32 : + 33 : struct { + 34 : const char *name; + 35 : uint8_t *msg; + 36 : size_t length; + 37 : uint8_t *exp_tag; + 38 3 : } tests[] = { + 39 2 : {"Example 1", NULL, 0, + 40 1 : (uint8_t[]){0xbb,0x1d,0x69,0x29,0xe9,0x59,0x37,0x28, + 41 : 0x7f,0xa3,0x7d,0x12,0x9b,0x75,0x67,0x46}}, + 42 2 : {"Example 2", (uint8_t[]){0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96, + 43 : 0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a}, 16, + 44 1 : (uint8_t[]){0x07,0x0a,0x16,0xb4,0x6b,0x4d,0x41,0x44, + 45 : 0xf7,0x9b,0xdd,0x9d,0xd0,0x4a,0x28,0x7c}}, + 46 2 : {"Example 3", (uint8_t[]){0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96, + 47 : 0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a, + 48 : 0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c, + 49 : 0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51, + 50 : 0x30,0xc8,0x1c,0x46,0xa3,0x5c,0xe4,0x11}, 40, + 51 1 : (uint8_t[]){0xdf,0xa6,0x67,0x47,0xde,0x9a,0xe6,0x30, + 52 : 0x30,0xca,0x32,0x61,0x14,0x97,0xc8,0x27}}, + 53 2 : {"Example 4", (uint8_t[]){0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96, + 54 : 0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a, + 55 : 0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c, + 56 : 0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51, + 57 : 0x30,0xc8,0x1c,0x46,0xa3,0x5c,0xe4,0x11, + 58 : 0xe5,0xfb,0xc1,0x19,0x1a,0x0a,0x52,0xef, + 59 : 0xf6,0x9f,0x24,0x45,0xdf,0x4f,0x9b,0x17, + 60 : 0xad,0x2b,0x41,0x7b,0xe6,0x6c,0x37,0x10}, 64, + 61 1 : (uint8_t[]){0x51,0xf0,0xbe,0xbf,0x7e,0x3b,0x9d,0x92, + 62 : 0xfc,0x49,0x74,0x17,0x79,0x36,0x3c,0xfe}} + 63 : }; + 64 : + 65 1 : int failed = 0; + 66 : + 67 5 : for (size_t i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + 68 4 : uint8_t tag[16] = {0}; + 69 4 : aes_cmac(tests[i].msg, tests[i].length, tag, &ctx); + 70 4 : failed |= check_result(tests[i].name, tag, tests[i].exp_tag, 16); + 71 4 : } + 72 : + 73 1 : return failed ? 1 : 0; + 74 : } ++ |
+
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| main | + +1 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| main | + +1 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : #include <stdio.h> + 2 : #include <stdint.h> + 3 : #include <string.h> + 4 : + 5 : #include "../include/ctr.h" + 6 : #include "../include/aes_wrapper.h" + 7 : #include "../include/aes_128.h" + 8 : #include "../include/key_expansion_128.h" + 9 : #include "../include/sbox.h" + 10 : + 11 : + 12 1 : int main(void) { + 13 1 : uint8_t key[16] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 14 : 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; + 15 : uint8_t round_keys[176]; + 16 : uint8_t sbox[256]; + 17 1 : initialize_aes_sbox(sbox); + 18 : + 19 1 : aes_key_expansion_128(key, round_keys, sbox); + 20 : + 21 1 : struct aes_ctx ctx = { .round_keys = round_keys, .sbox = sbox, .key_len = 16}; + 22 : + 23 1 : const uint8_t pt[] = "The quick brown fox jumps over 13 lazy dogs!"; + 24 1 : size_t len = strlen((const char*)pt); + 25 : + 26 1 : uint8_t ciphertext[256] = {0}; + 27 1 : uint8_t recovered[256] = {0}; + 28 : + 29 1 : uint8_t iv[16] = {0x00,0x01,0x02,0x03, 0x04,0x05,0x06,0x07, + 30 : 0x08,0x09,0x0a,0x0b, 0x00,0x00,0x00,0x01}; + 31 : + 32 1 : aes_ctr_crypt(pt, ciphertext, len, iv, aes_block_wrapper, &ctx); + 33 1 : aes_ctr_crypt(ciphertext, recovered, len, iv, aes_block_wrapper, &ctx); + 34 : + 35 1 : if (memcmp(pt, recovered, len) != 0) { + 36 0 : fprintf(stderr, "CTR round-trip FAILED\n"); + 37 0 : return 2; + 38 : } + 39 : + 40 1 : printf("CTR round-trip OK — plaintext recovered correctly.\n"); + 41 1 : printf("Plaintext: '%s'\n", (const char*)pt); + 42 1 : printf("Ciphertext (hex): "); + 43 45 : for (size_t i = 0; i < len; ++i) printf("%02x", ciphertext[i]); + 44 1 : printf("\n"); + 45 : + 46 1 : return 0; + 47 1 : } ++ |
+
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| main | + +1 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| main | + +1 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : #include <stdio.h> + 2 : #include <stdint.h> + 3 : #include <string.h> + 4 : + 5 : #include "../include/ecb.h" + 6 : #include "../include/aes_wrapper.h" + 7 : #include "../include/aes_128.h" + 8 : #include "../include/key_expansion_128.h" + 9 : #include "../include/sbox.h" + 10 : + 11 1 : int main(void) { + 12 : // NIST SP 800-38A AES-128 ECB test vector + 13 1 : const uint8_t key[16] = { + 14 : 0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6, + 15 : 0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c + 16 : }; + 17 : + 18 1 : const uint8_t plaintext[16] = { + 19 : 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96, + 20 : 0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a + 21 : }; + 22 : + 23 1 : const uint8_t expected_ciphertext[16] = { + 24 : 0x3a,0xd7,0x7b,0xb4,0x0d,0x7a,0x36,0x60, + 25 : 0xa8,0x9e,0xca,0xf3,0x24,0x66,0xef,0x97 + 26 : }; + 27 : + 28 : uint8_t round_keys[176]; + 29 : uint8_t sbox[256]; + 30 1 : initialize_aes_sbox(sbox); + 31 1 : aes_key_expansion_128(key, round_keys, sbox); + 32 : + 33 1 : struct aes_ctx ctx = { .round_keys = round_keys, .sbox = sbox, .key_len = 16}; + 34 : + 35 1 : uint8_t ciphertext[16] = {0}; + 36 1 : uint8_t decrypted[16] = {0}; + 37 : + 38 : // Encrypt + 39 1 : aes_ecb_encrypt(plaintext, ciphertext, 16, &ctx); + 40 : + 41 : // Decrypt + 42 1 : aes_ecb_decrypt(ciphertext, decrypted, 16, &ctx); + 43 : + 44 : // Verify encryption matches NIST vector + 45 1 : if (memcmp(ciphertext, expected_ciphertext, 16) != 0) { + 46 0 : fprintf(stderr, "ECB encryption FAILED\n"); + 47 0 : return 1; + 48 : } + 49 : + 50 : // Verify decryption matches plaintext + 51 1 : if (memcmp(decrypted, plaintext, 16) != 0) { + 52 0 : fprintf(stderr, "ECB decryption FAILED\n"); + 53 0 : return 2; + 54 : } + 55 : + 56 1 : printf("ECB round-trip OK — plaintext recovered correctly.\n"); + 57 1 : printf("Plaintext: "); + 58 17 : for (size_t i = 0; i < 16; ++i) printf("%02x", plaintext[i]); + 59 1 : printf("\n"); + 60 : + 61 1 : printf("Ciphertext (hex): "); + 62 17 : for (size_t i = 0; i < 16; ++i) printf("%02x", ciphertext[i]); + 63 1 : printf("\n"); + 64 : + 65 1 : return 0; + 66 1 : } ++ |
+
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| log_hex | + +0 | + + + +
| main | + +1 | + + + +
| parse_vector | + +47256 | + + + +
| parse_hex | + +271592 | + + + +
| strip_trailing | + +444180 | + + + +
| hex_to_byte | + +7404562 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| hex_to_byte | + +7404562 | + + + +
| log_hex | + +0 | + + + +
| main | + +1 | + + + +
| parse_hex | + +271592 | + + + +
| parse_vector | + +47256 | + + + +
| strip_trailing | + +444180 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : #include <stdio.h> + 2 : #include <stdlib.h> + 3 : #include <string.h> + 4 : #include <stdint.h> + 5 : #include <ctype.h> + 6 : #include "gcm.h" + 7 : + 8 : #define MAX_BYTES 8192 + 9 : #define MAX_LINE 8192 + 10 : + 11 : struct gcm_vector { + 12 : uint8_t key[MAX_BYTES], iv[MAX_BYTES]; + 13 : uint8_t pt[MAX_BYTES], aad[MAX_BYTES]; + 14 : uint8_t ct[MAX_BYTES], tag[MAX_BYTES]; + 15 : size_t key_len, iv_len, pt_len, aad_len, ct_len, tag_len; + 16 : int is_fail; + 17 : }; + 18 : + 19 : /* Convert two hex chars to a byte */ + 20 7404562 : static uint8_t hex_to_byte(const char *hex) { + 21 7404562 : uint8_t hi = (uint8_t)((isdigit(hex[0]) ? hex[0]-'0' : tolower(hex[0])-'a'+10) & 0xF); + 22 7404562 : uint8_t lo = (uint8_t)((isdigit(hex[1]) ? hex[1]-'0' : tolower(hex[1])-'a'+10) & 0xF); + 23 7404562 : return (hi << 4) | lo; + 24 : } + 25 : + 26 : /* Strip trailing whitespace */ + 27 444180 : static void strip_trailing(char *line) { + 28 444180 : size_t len = strlen(line); + 29 1358491 : while (len > 0 && isspace((unsigned char)line[len-1])) { + 30 914311 : line[len-1] = 0; + 31 914311 : len--; + 32 : } + 33 444180 : } + 34 : + 35 : /* Parse hex string into bytes */ + 36 271592 : static size_t parse_hex(const char *hex_str, uint8_t *out) { + 37 271592 : size_t out_pos = 0; + 38 271592 : size_t len = strlen(hex_str); + 39 : + 40 7676154 : for (size_t i = 0; i < len; i++) { + 41 7404562 : if (!isxdigit((unsigned char)hex_str[i])) continue; + 42 7404562 : if (i + 1 < len && isxdigit((unsigned char)hex_str[i+1])) { + 43 7404562 : out[out_pos++] = hex_to_byte(&hex_str[i]); + 44 7404562 : i++; + 45 7404562 : } + 46 7404562 : } + 47 271592 : return out_pos; + 48 : } + 49 : + 50 : /* Parse a single vector from a .rsp file */ + 51 47256 : static int parse_vector(FILE *f, struct gcm_vector *v) { + 52 : char line[MAX_LINE]; + 53 47256 : int has_key = 0; + 54 : + 55 47256 : memset(v, 0, sizeof(*v)); + 56 : + 57 444192 : while (fgets(line, sizeof(line), f)) { + 58 444180 : strip_trailing(line); + 59 444180 : if (line[0] == 0 || line[0] == '#') continue; + 60 : + 61 393744 : if (strncasecmp(line, "FAIL", 4) == 0) { + 62 11908 : v->is_fail = 1; + 63 11908 : continue; + 64 : } + 65 : + 66 381836 : char *eq = strchr(line, '='); + 67 381836 : if (!eq) continue; + 68 : + 69 381836 : *eq = 0; + 70 381836 : char *name = line; + 71 381836 : char *value = eq + 1; + 72 : + 73 381836 : while (*name && isspace((unsigned char)*name)) name++; + 74 381836 : char *name_end = name + strlen(name) - 1; + 75 763672 : while (name_end > name && isspace((unsigned char)*name_end)) *name_end-- = 0; + 76 737721 : while (*value && isspace((unsigned char)*value)) value++; + 77 : + 78 381836 : if (strcasecmp(name, "Count") == 0) { + 79 47250 : if (has_key) { + 80 47244 : fseek(f, -(long)(strlen(line) + strlen(value) + 2), SEEK_CUR); + 81 47244 : return 1; + 82 : } + 83 334592 : } else if (strcasecmp(name, "Key") == 0) { + 84 47250 : v->key_len = parse_hex(value, v->key); + 85 47250 : has_key = 1; + 86 334586 : } else if (strcasecmp(name, "IV") == 0) { + 87 47250 : v->iv_len = parse_hex(value, v->iv); + 88 287336 : } else if (strcasecmp(name, "PT") == 0) { + 89 35342 : v->pt_len = parse_hex(value, v->pt); + 90 240086 : } else if (strcasecmp(name, "AAD") == 0) { + 91 47250 : v->aad_len = parse_hex(value, v->aad); + 92 204744 : } else if (strcasecmp(name, "CT") == 0) { + 93 47250 : v->ct_len = parse_hex(value, v->ct); + 94 157494 : } else if (strcasecmp(name, "Tag") == 0) { + 95 47250 : v->tag_len = parse_hex(value, v->tag); + 96 47250 : } + 97 : } + 98 : + 99 12 : return has_key; + 100 47256 : } + 101 : + 102 : /* Write hex data to file with label */ + 103 0 : static void log_hex(FILE *log, const char *label, const uint8_t *data, size_t len) { + 104 0 : fprintf(log, "%s = ", label); + 105 0 : for (size_t i = 0; i < len; i++) fprintf(log, "%02X", data[i]); + 106 0 : fprintf(log, "\n"); + 107 0 : } + 108 : + 109 1 : int main(void) { + 110 1 : const char *files[] = { + 111 : "gcmtestvectors/gcmDecrypt128.rsp", + 112 : "gcmtestvectors/gcmDecrypt192.rsp", + 113 : "gcmtestvectors/gcmDecrypt256.rsp", + 114 : "gcmtestvectors/gcmEncryptExtIV128.rsp", + 115 : "gcmtestvectors/gcmEncryptExtIV192.rsp", + 116 : "gcmtestvectors/gcmEncryptExtIV256.rsp" + 117 : }; + 118 : + 119 : struct gcm_vector v; + 120 : struct gcm_ctx ctx; + 121 1 : int total_vectors = 0, total_passed = 0, total_skipped = 0; + 122 : + 123 1 : FILE *log = fopen("log/failed_vectors.log", "w"); + 124 1 : if (!log) { perror("log/failed_vectors.log"); return 1; } + 125 : + 126 7 : for (size_t fidx = 0; fidx < sizeof(files)/sizeof(files[0]); fidx++) { + 127 6 : FILE *fp = fopen(files[fidx], "r"); + 128 6 : if (!fp) { perror(files[fidx]); continue; } + 129 : + 130 6 : int vector_count = 0, passed = 0, skipped = 0; + 131 : + 132 47256 : while (parse_vector(fp, &v)) { + 133 47250 : vector_count++; + 134 47250 : total_vectors++; + 135 : + 136 47250 : if (v.is_fail) { + 137 : uint8_t decrypted[MAX_BYTES]; + 138 11908 : int res = gcm_decrypt(&ctx, v.ct, v.ct_len, v.aad, v.aad_len, v.tag, v.tag_len, decrypted); + 139 11908 : if (res != 0) { + 140 11908 : passed++; + 141 11908 : total_passed++; + 142 11908 : } + 143 11908 : continue; + 144 : } + 145 : + 146 35342 : if (v.key_len != 16 && v.key_len != 24 && v.key_len != 32) { + 147 0 : skipped++; + 148 0 : total_skipped++; + 149 0 : continue; + 150 : } + 151 : + 152 35342 : gcm_init(&ctx, v.key, v.key_len, v.iv, v.iv_len); + 153 : + 154 : uint8_t ciphertext[MAX_BYTES], computed_tag[16]; + 155 35342 : gcm_encrypt(&ctx, v.pt, v.pt_len, v.aad, v.aad_len, ciphertext, computed_tag, v.tag_len); + 156 : + 157 35342 : int ok = 1; + 158 35342 : if (v.ct_len > 0 && memcmp(ciphertext, v.ct, v.ct_len) != 0) ok = 0; + 159 35342 : if (v.tag_len > 0 && memcmp(computed_tag, v.tag, v.tag_len) != 0) ok = 0; + 160 : + 161 : uint8_t decrypted[MAX_BYTES]; + 162 35342 : if (v.ct_len > 0) { + 163 28291 : if (gcm_decrypt(&ctx, ciphertext, v.ct_len, v.aad, v.aad_len, v.tag, v.tag_len, decrypted) != 0) + 164 0 : ok = 0; + 165 28291 : else if (memcmp(decrypted, v.pt, v.pt_len) != 0) + 166 0 : ok = 0; + 167 28291 : } + 168 : + 169 35342 : if (!ok) { + 170 : // Log the failing vector with expected vs actual + 171 0 : fprintf(log, "# Failure (Count=%d) in %s\n", vector_count, files[fidx]); + 172 0 : log_hex(log, "Key", v.key, v.key_len); + 173 0 : log_hex(log, "IV", v.iv, v.iv_len); + 174 0 : if (v.pt_len) log_hex(log, "PT", v.pt, v.pt_len); + 175 0 : if (v.ct_len) log_hex(log, "CT", ciphertext, v.ct_len); + 176 0 : if (v.tag_len) { + 177 0 : log_hex(log, "Tag_expected", v.tag, v.tag_len); + 178 0 : log_hex(log, "Tag_actual", computed_tag, v.tag_len); + 179 0 : } + 180 0 : fprintf(log, "Decrypted = "); + 181 0 : for (size_t i = 0; i < v.pt_len; i++) fprintf(log, "%02X", decrypted[i]); + 182 0 : fprintf(log, "\n\n"); + 183 0 : } else { + 184 35342 : passed++; + 185 35342 : total_passed++; + 186 : } + 187 : } + 188 : + 189 6 : fclose(fp); + 190 6 : int failed = vector_count - passed - skipped; + 191 6 : printf("%-45s %5d total | %5d passed | %5d failed | %5d skipped\n", + 192 6 : files[fidx], vector_count, passed, failed, skipped); + 193 6 : } + 194 : + 195 1 : fclose(log); + 196 : + 197 1 : printf("\n========================================\n"); + 198 1 : printf("Total: %d | Passed: %d | Failed: %d | Skipped: %d\n", + 199 1 : total_vectors, total_passed, total_vectors - total_passed - total_skipped, total_skipped); + 200 : + 201 1 : return (total_vectors == total_passed) ? 0 : 1; + 202 1 : } ++ |
+
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| log_hex | + +0 | + + + +
| main | + +1 | + + + +
| parse_vector | + +47256 | + + + +
| parse_hex | + +224342 | + + + +
| strip_trailing | + +444180 | + + + +
| hex_to_byte | + +5552550 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| hex_to_byte | + +5552550 | + + + +
| log_hex | + +0 | + + + +
| main | + +1 | + + + +
| parse_hex | + +224342 | + + + +
| parse_vector | + +47256 | + + + +
| strip_trailing | + +444180 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : #include <stdio.h> + 2 : #include <stdlib.h> + 3 : #include <string.h> + 4 : #include <stdint.h> + 5 : #include <ctype.h> + 6 : #include "gmac.h" + 7 : + 8 : #define MAX_BYTES 8192 + 9 : #define MAX_LINE 8192 + 10 : + 11 : struct gmac_vector { + 12 : uint8_t key[MAX_BYTES], iv[MAX_BYTES]; + 13 : uint8_t aad[MAX_BYTES]; + 14 : uint8_t tag[MAX_BYTES]; + 15 : size_t key_len, iv_len, aad_len, tag_len; + 16 : int has_plaintext; + 17 : int is_fail; // Added: indicates this vector should fail authentication + 18 : }; + 19 : + 20 : /* Convert two hex chars to a byte */ + 21 5552550 : static uint8_t hex_to_byte(const char *hex) { + 22 5552550 : uint8_t hi = (uint8_t)((isdigit(hex[0]) ? hex[0]-'0' : tolower(hex[0])-'a'+10) & 0xF); + 23 5552550 : uint8_t lo = (uint8_t)((isdigit(hex[1]) ? hex[1]-'0' : tolower(hex[1])-'a'+10) & 0xF); + 24 5552550 : return (hi << 4) | lo; + 25 : } + 26 : + 27 : /* Strip trailing whitespace */ + 28 444180 : static void strip_trailing(char *line) { + 29 444180 : size_t len = strlen(line); + 30 1358491 : while (len > 0 && isspace((unsigned char)line[len-1])) { + 31 914311 : line[len-1] = 0; + 32 914311 : len--; + 33 : } + 34 444180 : } + 35 : + 36 : /* Parse hex string into bytes */ + 37 224342 : static size_t parse_hex(const char *hex_str, uint8_t *out) { + 38 224342 : size_t out_pos = 0; + 39 224342 : size_t len = strlen(hex_str); + 40 6570504 : for (size_t i = 0; i < len; i++) { + 41 6346162 : if (!isxdigit((unsigned char)hex_str[i])) continue; + 42 6346162 : if (i + 1 < len && isxdigit((unsigned char)hex_str[i+1])) { + 43 6346162 : if (out) out[out_pos] = hex_to_byte(&hex_str[i]); + 44 6346162 : out_pos++; + 45 6346162 : i++; + 46 6346162 : } + 47 6346162 : } + 48 224342 : return out_pos; + 49 : } + 50 : + 51 : /* Parse a single vector from a .rsp file */ + 52 47256 : static int parse_vector(FILE *f, struct gmac_vector *v) { + 53 : char line[MAX_LINE]; + 54 47256 : int has_key = 0; + 55 47256 : memset(v, 0, sizeof(*v)); + 56 : + 57 444192 : while (fgets(line, sizeof(line), f)) { + 58 444180 : strip_trailing(line); + 59 444180 : if (line[0] == 0 || line[0] == '#') continue; + 60 : + 61 : // Check for FAIL marker + 62 393744 : if (strncasecmp(line, "FAIL", 4) == 0) { + 63 11908 : v->is_fail = 1; + 64 11908 : continue; + 65 : } + 66 : + 67 381836 : char *eq = strchr(line, '='); + 68 381836 : if (!eq) continue; + 69 : + 70 381836 : *eq = 0; + 71 381836 : char *name = line; + 72 381836 : char *value = eq + 1; + 73 : + 74 381836 : while (*name && isspace((unsigned char)*name)) name++; + 75 381836 : char *name_end = name + strlen(name) - 1; + 76 763672 : while (name_end > name && isspace((unsigned char)*name_end)) *name_end-- = 0; + 77 737721 : while (*value && isspace((unsigned char)*value)) value++; + 78 : + 79 381836 : if (strcasecmp(name, "Count") == 0) { + 80 47250 : if (has_key) { + 81 47244 : fseek(f, -(long)(strlen(line) + strlen(value) + 2), SEEK_CUR); + 82 47244 : return 1; + 83 : } + 84 334592 : } else if (strcasecmp(name, "Key") == 0) { + 85 47250 : v->key_len = parse_hex(value, v->key); + 86 47250 : has_key = 1; + 87 334586 : } else if (strcasecmp(name, "IV") == 0) { + 88 47250 : v->iv_len = parse_hex(value, v->iv); + 89 287336 : } else if (strcasecmp(name, "PT") == 0) { + 90 35342 : size_t pt_len = parse_hex(value, NULL); + 91 35342 : v->has_plaintext = (pt_len > 0); + 92 240086 : } else if (strcasecmp(name, "AAD") == 0) { + 93 47250 : v->aad_len = parse_hex(value, v->aad); + 94 204744 : } else if (strcasecmp(name, "Tag") == 0) { + 95 47250 : v->tag_len = parse_hex(value, v->tag); + 96 47250 : } + 97 : } + 98 : + 99 12 : return has_key; + 100 47256 : } + 101 : + 102 : /* Write hex data to file with label */ + 103 0 : static void log_hex(FILE *log, const char *label, const uint8_t *data, size_t len) { + 104 0 : fprintf(log, "%s = ", label); + 105 0 : for (size_t i = 0; i < len; i++) fprintf(log, "%02X", data[i]); + 106 0 : fprintf(log, "\n"); + 107 0 : } + 108 : + 109 1 : int main(void) { + 110 1 : const char *files[] = { + 111 : "gcmtestvectors/gcmDecrypt128.rsp", + 112 : "gcmtestvectors/gcmDecrypt192.rsp", + 113 : "gcmtestvectors/gcmDecrypt256.rsp", + 114 : "gcmtestvectors/gcmEncryptExtIV128.rsp", + 115 : "gcmtestvectors/gcmEncryptExtIV192.rsp", + 116 : "gcmtestvectors/gcmEncryptExtIV256.rsp" + 117 : }; + 118 : + 119 : struct gmac_vector v; + 120 : struct gmac_ctx ctx; + 121 1 : int total_vectors = 0, total_passed = 0, total_skipped = 0; + 122 : + 123 1 : FILE *log = fopen("log/failed_gmac.log", "w"); + 124 1 : if (!log) { perror("log/failed_gmac.log"); return 1; } + 125 : + 126 7 : for (size_t fidx = 0; fidx < sizeof(files)/sizeof(files[0]); fidx++) { + 127 6 : FILE *fp = fopen(files[fidx], "r"); + 128 6 : if (!fp) { perror(files[fidx]); continue; } + 129 : + 130 6 : int vector_count = 0, passed = 0, skipped = 0; + 131 : + 132 47256 : while (parse_vector(fp, &v)) { + 133 : // Only consider vectors with PTlen == 0 (no plaintext = GMAC mode) + 134 47250 : if (v.has_plaintext) continue; + 135 : + 136 18959 : vector_count++; + 137 18959 : total_vectors++; + 138 : + 139 18959 : if (v.key_len != 16 && v.key_len != 24 && v.key_len != 32) { + 140 0 : skipped++; + 141 0 : total_skipped++; + 142 0 : continue; + 143 : } + 144 : + 145 18959 : if (gmac_init(&ctx, v.key, v.key_len, v.iv, v.iv_len) != 0) { + 146 0 : skipped++; + 147 0 : total_skipped++; + 148 0 : continue; + 149 : } + 150 : + 151 : uint8_t computed_tag[16]; + 152 18959 : gmac_compute(&ctx, v.aad, v.aad_len, computed_tag, v.tag_len); + 153 : + 154 18959 : int tags_match = (memcmp(computed_tag, v.tag, v.tag_len) == 0); + 155 : + 156 : // For FAIL vectors: pass if tags DON'T match (expected behavior) + 157 : // For normal vectors: pass if tags DO match + 158 18959 : int test_passed = v.is_fail ? !tags_match : tags_match; + 159 : + 160 18959 : if (!test_passed) { + 161 : // Log the failing vector + 162 0 : fprintf(log, "# Failure (Count=%d) in %s%s\n", + 163 0 : vector_count, files[fidx], v.is_fail ? " [FAIL vector]" : ""); + 164 0 : log_hex(log, "Key", v.key, v.key_len); + 165 0 : log_hex(log, "IV", v.iv, v.iv_len); + 166 0 : if (v.aad_len) log_hex(log, "AAD", v.aad, v.aad_len); + 167 0 : if (v.tag_len) { + 168 0 : log_hex(log, "Tag_expected", v.tag, v.tag_len); + 169 0 : log_hex(log, "Tag_actual", computed_tag, v.tag_len); + 170 0 : } + 171 0 : if (v.is_fail) { + 172 0 : fprintf(log, "ERROR: FAIL vector produced matching tag (should mismatch)\n"); + 173 0 : } + 174 0 : fprintf(log, "\n"); + 175 0 : } else { + 176 18959 : passed++; + 177 18959 : total_passed++; + 178 : } + 179 : } + 180 : + 181 6 : fclose(fp); + 182 6 : int failed = vector_count - passed - skipped; + 183 6 : printf("%-45s %5d total | %5d passed | %5d failed | %5d skipped\n", + 184 6 : files[fidx], vector_count, passed, failed, skipped); + 185 6 : } + 186 : + 187 1 : fclose(log); + 188 : + 189 1 : printf("\n========================================\n"); + 190 1 : printf("Total: %d | Passed: %d | Failed: %d | Skipped: %d\n", + 191 1 : total_vectors, total_passed, total_vectors - total_passed - total_skipped, total_skipped); + 192 : + 193 1 : return (total_vectors == total_passed + total_skipped) ? 0 : 1; + 194 1 : } ++ |
+
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| main | + +1 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| main | + +1 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : #include <stdio.h> + 2 : #include <stdint.h> + 3 : #include <string.h> + 4 : + 5 : #include "../include/ofb.h" + 6 : #include "../include/aes_wrapper.h" + 7 : #include "../include/aes_128.h" + 8 : #include "../include/key_expansion_128.h" + 9 : #include "../include/sbox.h" + 10 : + 11 1 : int main(void) { + 12 1 : const uint8_t key[16] = { + 13 : 0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6, + 14 : 0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c + 15 : }; + 16 : + 17 1 : const uint8_t iv[16] = { + 18 : 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 19 : 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f + 20 : }; + 21 : + 22 1 : const uint8_t plaintext[64] = { + 23 : 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96, + 24 : 0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a, + 25 : 0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c, + 26 : 0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51, + 27 : 0x30,0xc8,0x1c,0x46,0xa3,0x5c,0xe4,0x11, + 28 : 0xe5,0xfb,0xc1,0x19,0x1a,0x0a,0x52,0xef, + 29 : 0xf6,0x9f,0x24,0x45,0xdf,0x4f,0x9b,0x17, + 30 : 0xad,0x2b,0x41,0x7b,0xe6,0x6c,0x37,0x10 + 31 : }; + 32 : + 33 1 : const uint8_t expected_ciphertext[64] = { + 34 : 0x3b,0x3f,0xd9,0x2e,0xb7,0x2d,0xad,0x20, + 35 : 0x33,0x34,0x49,0xf8,0xe8,0x3c,0xfb,0x4a, + 36 : 0x77,0x89,0x50,0x8d,0x16,0x91,0x8f,0x03, + 37 : 0xf5,0x3c,0x52,0xda,0xc5,0x4e,0xd8,0x25, + 38 : 0x97,0x40,0x05,0x1e,0x9c,0x5f,0xec,0xf6, + 39 : 0x43,0x44,0xf7,0xa8,0x22,0x60,0xed,0xcc, + 40 : 0x30,0x4c,0x65,0x28,0xf6,0x59,0xc7,0x78, + 41 : 0x66,0xa5,0x10,0xd9,0xc1,0xd6,0xae,0x5e + 42 : }; + 43 : + 44 : uint8_t round_keys[176]; + 45 : uint8_t sbox[256]; + 46 1 : initialize_aes_sbox(sbox); + 47 1 : aes_key_expansion_128(key, round_keys, sbox); + 48 1 : struct aes_ctx ctx = { .round_keys = round_keys, .sbox = sbox, .key_len = 16}; + 49 : + 50 1 : uint8_t ciphertext[64] = {0}; + 51 1 : uint8_t decrypted[64] = {0}; + 52 : + 53 : // Encrypt + 54 1 : aes_ofb_encrypt(plaintext, ciphertext, sizeof(plaintext), iv, &ctx); + 55 : + 56 1 : if (memcmp(ciphertext, expected_ciphertext, sizeof(ciphertext)) != 0) { + 57 0 : fprintf(stderr, "OFB encryption FAILED\n"); + 58 0 : return 1; + 59 : } + 60 : + 61 : // Decrypt (same operation) + 62 1 : aes_ofb_decrypt(ciphertext, decrypted, sizeof(ciphertext), iv, &ctx); + 63 : + 64 1 : if (memcmp(decrypted, plaintext, sizeof(decrypted)) != 0) { + 65 0 : fprintf(stderr, "OFB decryption FAILED\n"); + 66 0 : return 2; + 67 : } + 68 : + 69 1 : printf("OFB round-trip OK — plaintext recovered correctly.\n"); + 70 : + 71 1 : printf("Ciphertext (hex): "); + 72 65 : for (size_t i = 0; i < sizeof(ciphertext); ++i) { + 73 64 : printf("%02x", ciphertext[i]); + 74 64 : } + 75 1 : printf("\n"); + 76 : + 77 1 : return 0; + 78 1 : } ++ |
+
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| main | + +1 | + + + +
| test_roundtrip | + +10 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
| Function Name |
+
+ Hit count |
+
+
+
+
| main | + +1 | + + + +
| test_roundtrip | + +10 | + + + +
| Generated by: LCOV version 2.3.2-1 |
| LCOV - code coverage report | ||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||
+Line data Source code+ + 1 : /* + 2 : * Basic unit test for XTS module. + 3 : * + 4 : */ + 5 : + 6 : #include <stdio.h> + 7 : #include <string.h> + 8 : #include <stdint.h> + 9 : #include "../include/xts.h" + 10 : #include "../include/aes_wrapper.h" + 11 : #include "../include/key_expansion_128.h" + 12 : #include "../include/sbox.h" + 13 : + 14 : static const uint8_t key1[16] = { + 15 : 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 16 : 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F + 17 : }; + 18 : static const uint8_t key2[16] = { + 19 : 0x0F,0x0E,0x0D,0x0C,0x0B,0x0A,0x09,0x08, + 20 : 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00 + 21 : }; + 22 : + 23 10 : static int test_roundtrip(const uint8_t *pt, size_t len, uint64_t data_unit) { + 24 : uint8_t ct[1024], out[1024]; + 25 10 : memset(ct, 0, sizeof(ct)); + 26 10 : memset(out, 0, sizeof(out)); + 27 : + 28 : uint8_t sbox[256]; + 29 10 : initialize_aes_sbox(sbox); + 30 : + 31 : uint8_t round_keys1[176], round_keys2[176]; + 32 10 : aes_key_expansion_128(key1, round_keys1, sbox); + 33 10 : aes_key_expansion_128(key2, round_keys2, sbox); + 34 : + 35 10 : struct aes_ctx ctx_k1 = { round_keys1, sbox, 16 }; + 36 10 : struct aes_ctx ctx_k2 = { round_keys2, sbox, 16 }; + 37 : + 38 10 : int r = xts_encrypt((aes_block_fn)aes_block_wrapper, &ctx_k1, + 39 : (aes_block_fn)aes_block_wrapper, &ctx_k2, + 40 10 : data_unit, pt, len, ct); + 41 10 : if (r != XTS_OK) return r; + 42 : + 43 5 : r = xts_decrypt((aes_block_fn)aes_block_wrapper_dec, &ctx_k1, + 44 : (aes_block_fn)aes_block_wrapper, &ctx_k2, + 45 5 : data_unit, ct, len, out); + 46 5 : if (r != XTS_OK) return r; + 47 : + 48 5 : if (memcmp(pt, out, len) != 0) return -1; + 49 5 : return 1; + 50 10 : } + 51 : + 52 1 : int main(void) { + 53 : uint8_t buf[256]; + 54 257 : for (size_t i = 0; i < sizeof(buf); ++i) buf[i] = (uint8_t)i; + 55 : + 56 1 : size_t lengths[] = {1, 7, 15, 16, 17, 31, 32, 33, 48, 63, 64, 65, 128}; + 57 1 : int all_ok = 1; + 58 : + 59 14 : for (size_t i = 0; i < sizeof(lengths)/sizeof(lengths[0]); ++i) { + 60 13 : size_t len = lengths[i]; + 61 13 : uint64_t du = 42 + i; + 62 13 : printf("Test length=%zu, data_unit=%llu... ", len, (unsigned long long)du); + 63 : + 64 13 : if (len < 16) { + 65 3 : printf("SKIPPED (<16 bytes)\n"); + 66 3 : continue; + 67 : } + 68 : + 69 10 : int r = test_roundtrip(buf, len, du); + 70 10 : if (r == 1) { + 71 10 : printf("OK\n"); + 72 10 : } else if (r == XTS_ERR_INVALID) { + 73 0 : printf("INVALID LENGTH\n"); + 74 0 : all_ok = 0; + 75 0 : } else if (r == -1) { + 76 0 : printf("ROUNDTRIP MISMATCH\n"); + 77 0 : all_ok = 0; + 78 0 : } else { + 79 0 : printf("FAILED (code=%d)\n", r); + 80 0 : all_ok = 0; + 81 : } + 82 10 : } + 83 : + 84 1 : if (all_ok) { + 85 1 : printf("All XTS roundtrip tests passed.\n"); + 86 1 : return 0; + 87 : } else { + 88 0 : printf("Some XTS roundtrip tests failed.\n"); + 89 0 : return 2; + 90 : } + 91 1 : } ++ |
+
| Generated by: LCOV version 2.3.2-1 |