├── .github ├── .cSpellWords.txt ├── CODEOWNERS ├── CONTRIBUTING.md ├── memory_statistics_config.json ├── pull_request_template.md └── workflows │ ├── ci.yml │ ├── doxygen.yml │ └── release.yml ├── .gitignore ├── .gitmodules ├── .lgtm.yml ├── CHANGELOG.md ├── LICENSE ├── MISRA.md ├── README.md ├── SECURITY.md ├── coreSntpFilePaths.cmake ├── cspell.config.yaml ├── docs └── doxygen │ ├── code_examples │ └── example_sntp_client_posix.c │ ├── config.doxyfile │ ├── images │ ├── Dependency_Architecture_Diagram.png │ └── Ntp_To_Unix_Time.png │ ├── include │ └── size_table.md │ ├── layout.xml │ ├── pages.dox │ ├── porting.dox │ └── style.css ├── manifest.yml ├── source ├── core_sntp_client.c ├── core_sntp_serializer.c └── include │ ├── core_sntp_client.h │ ├── core_sntp_config_defaults.h │ └── core_sntp_serializer.h ├── test ├── CMakeLists.txt ├── cbmc │ ├── .gitignore │ ├── include │ │ ├── README.md │ │ ├── core_sntp_cbmc_state.h │ │ ├── core_sntp_config.h │ │ └── core_sntp_stubs.h │ ├── proofs │ │ ├── Makefile-project-defines │ │ ├── Makefile-project-targets │ │ ├── Makefile-project-testing │ │ ├── Makefile-template-defines │ │ ├── Makefile.common │ │ ├── README.md │ │ ├── Sntp_CalculatePollInterval │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ ├── Sntp_CalculatePollInterval_harness.c │ │ │ ├── cbmc-proof.txt │ │ │ └── cbmc-viewer.json │ │ ├── Sntp_ConvertToUnixTime │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ ├── Sntp_ConvertToUnixTime_harness.c │ │ │ ├── cbmc-proof.txt │ │ │ └── cbmc-viewer.json │ │ ├── Sntp_DeserializeResponse │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ ├── Sntp_DeserializeResponse_harness.c │ │ │ ├── cbmc-proof.txt │ │ │ └── cbmc-viewer.json │ │ ├── Sntp_Init │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ ├── Sntp_Init_harness.c │ │ │ ├── cbmc-proof.txt │ │ │ └── cbmc-viewer.json │ │ ├── Sntp_ReceiveTimeResponse │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ ├── Sntp_ReceiveTimeResponse_harness.c │ │ │ ├── cbmc-proof.txt │ │ │ └── cbmc-viewer.json │ │ ├── Sntp_SendTimeRequest │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ ├── Sntp_SendTimeRequest_harness.c │ │ │ ├── cbmc-proof.txt │ │ │ └── cbmc-viewer.json │ │ ├── Sntp_SerializeRequest │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ ├── Sntp_SerializeRequest_harness.c │ │ │ ├── cbmc-proof.txt │ │ │ └── cbmc-viewer.json │ │ ├── lib │ │ │ ├── __init__.py │ │ │ ├── print_tool_versions.py │ │ │ └── summarize.py │ │ └── run-cbmc-proofs.py │ ├── sources │ │ ├── README.md │ │ └── core_sntp_cbmc_state.c │ └── stubs │ │ ├── README.md │ │ └── core_sntp_stubs.c └── unit-test │ ├── CMakeLists.txt │ ├── cmock_build.cmake │ ├── core_sntp_client_utest.c │ ├── core_sntp_config.h │ ├── core_sntp_serializer_utest.c │ └── unity_build.cmake └── tools ├── cmock ├── coverage.cmake ├── create_test.cmake └── project.yml └── coverity ├── README.md └── misra.config /.github/.cSpellWords.txt: -------------------------------------------------------------------------------- 1 | CBMC 2 | CMAC 3 | CMOCK 4 | CMock 5 | CRYP 6 | Cbmc 7 | Cmock 8 | Coverity 9 | DCMOCK 10 | DNDEBUG 11 | DUNITTEST 12 | MISRA 13 | Misra 14 | RSTR 15 | SNTP 16 | Sntp 17 | TRNG 18 | cbmc 19 | converttounixtime 20 | coverity 21 | ctest 22 | fracs 23 | lcov 24 | ldms 25 | lums 26 | misra 27 | nondet 28 | sinclude 29 | sntp 30 | utest 31 | xlarge 32 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Each line is a file pattern followed by one or more owners. 2 | 3 | # These owners will be the default owners for everything in 4 | # the repo. Unless a later match takes precedence, 5 | # @global-owner1 and @global-owner2 will be requested for 6 | # review when someone opens a pull request. 7 | * @FreeRTOS/pr-bar-raiser 8 | 9 | # Order is important; the last matching pattern takes the most 10 | # precedence. When someone opens a pull request that only 11 | # modifies JS files, only @js-owner and not the global 12 | # owner(s) will be requested for a review. 13 | # *.c FreeRTOS/pr-bar-raiser 14 | 15 | # You can also use email addresses if you prefer. They'll be 16 | # used to look up users just like we do for commit author 17 | # emails. 18 | # *.go docs@example.com 19 | 20 | # In this example, @doctocat owns any files in the build/logs 21 | # directory at the root of the repository and any of its 22 | # subdirectories. 23 | # /build/logs/ @doctocat 24 | 25 | # The `docs/*` pattern will match files like 26 | # `docs/getting-started.md` but not further nested files like 27 | # `docs/build-app/troubleshooting.md`. 28 | # docs/* docs@example.com 29 | 30 | # In this example, @octocat owns any file in an apps directory 31 | # anywhere in your repository. 32 | # apps/ @octocat 33 | 34 | # In this example, @doctocat owns any file in the `/docs` 35 | # directory in the root of your repository and any of its 36 | # subdirectories. 37 | # /docs/ @doctocat -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check [existing open](https://github.com/FreeRTOS/backoffAlgorithm/issues), or [recently closed](https://github.com/FreeRTOS/backoffAlgorithm/issues?q=is%3Aissue+is%3Aclosed), issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *main* branch. 27 | 1. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 1. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 1. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 1. Ensure that your contributions conform to the [style guide](https://docs.aws.amazon.com/embedded-csdk/202011.00/lib-ref/docs/doxygen/output/html/guide_developer_styleguide.html). 35 | 1. Format your code with uncrustify, using the config available in [FreeRTOS/CI-CD-Github-Actions](https://github.com/FreeRTOS/CI-CD-Github-Actions/blob/main/formatting/uncrustify.cfg). 36 | 1. Ensure local tests pass. 37 | 1. Commit to your fork using clear commit messages. 38 | 1. Send us a pull request, answering any default questions in the pull request interface. 39 | 1. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 40 | 41 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 42 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 43 | 44 | 45 | ## Finding contributions to work on 46 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels ((enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any ['help wanted'](https://github.com/FreeRTOS/backoffAlgorithm/labels?q=help+wanted) issues is a great place to start. 47 | 48 | 49 | ## Code of Conduct 50 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 51 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 52 | opensource-codeofconduct@amazon.com with any additional questions or comments. 53 | 54 | 55 | ## Security issue notifications 56 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](https://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 57 | 58 | 59 | ## Licensing 60 | 61 | See the [LICENSE](../LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 62 | 63 | We may ask you to sign a [Contributor License Agreement (CLA)](https://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes. 64 | -------------------------------------------------------------------------------- /.github/memory_statistics_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib_name" : "coreSNTP", 3 | "src": [ 4 | "source/core_sntp_client.c", 5 | "source/core_sntp_serializer.c" 6 | ], 7 | "include": [ 8 | "source/include" 9 | ], 10 | "compiler_flags": [ 11 | "SNTP_DO_NOT_USE_CUSTOM_CONFIG" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | Description 2 | ----------- 3 | 4 | 5 | Test Steps 6 | ----------- 7 | 8 | 9 | Checklist: 10 | ---------- 11 | 12 | 13 | - [ ] I have tested my changes. No regression in existing tests. 14 | - [ ] I have modified and/or added unit-tests to cover the code changes in this Pull Request. 15 | 16 | Related Issue 17 | ----------- 18 | 19 | 20 | By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. 21 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI Checks 2 | on: 3 | push: 4 | branches: ["**"] 5 | pull_request: 6 | branches: [main] 7 | workflow_dispatch: 8 | 9 | jobs: 10 | build-check: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Clone This Repo 14 | uses: actions/checkout@v3 15 | 16 | - name: Build Library in Debug mode 17 | run: | 18 | cmake -S test -B build/ \ 19 | -G "Unix Makefiles" \ 20 | -DCMAKE_BUILD_TYPE=Debug \ 21 | -DCMAKE_C_FLAGS='-O0 -Wall -Wextra -Werror -Wformat -Wformat-security -Warray-bounds' 22 | make -C build/ coverity_analysis -j8 23 | 24 | - name: Build Library in Release mode 25 | run: | 26 | rm -rf ./build 27 | cmake -S test -B build/ -G "Unix Makefiles" \ 28 | -DCMAKE_BUILD_TYPE=Release \ 29 | -DCMAKE_C_FLAGS='-Wall -Wextra -Werror -DNDEBUG -Wformat -Wformat-security -Warray-bounds' 30 | make -C build/ coverity_analysis -j8 31 | 32 | build-code-example: 33 | runs-on: ubuntu-latest 34 | steps: 35 | - name: Clone This Repo 36 | uses: actions/checkout@v3 37 | 38 | - name: Build Code Example used in Doxygen 39 | run: | 40 | cmake -S test -B Build -DBUILD_CODE_EXAMPLE=ON 41 | make -C Build code_example_posix -j8 42 | 43 | unittest-with-sanitizer: 44 | runs-on: ubuntu-latest 45 | steps: 46 | - name: Clone This Repo 47 | uses: actions/checkout@v3 48 | - name: Build Library and Unit Tests with Sanitizer 49 | run: | 50 | CFLAGS="-O0 -Wall -Wexta -Werror" 51 | CFLAGS+=" -D_FORTIFY_SOURCE=2" 52 | CFLAGS+=" -Wformat" 53 | CLFAGS+=" -Wformat-security" 54 | CFLAGS+=" -Warray-bounds" 55 | CFLAGS+=" -fsanitize=address,undefined" 56 | CFLAGS+=" -fsanitize=pointer-compare -fsanitize=pointer-subtract" 57 | CFLAGS+=" -fsanitize-recover=undefined" 58 | CFLAGS+=" -fsanitize-address-use-after-scope" 59 | CFLAGS+=" -fsanitize-undefined-trap-on-error" 60 | CFLAGS=" -fstack-protector-all -DLOGGING_LEVEL_DEBUG=1" 61 | cmake -S test -B build/ \ 62 | -G "Unix Makefiles" \ 63 | -DCMAKE_BUILD_TYPE=Debug \ 64 | -DUNITTEST=ON \ 65 | -DCMAKE_C_FLAGS="${CFLAGS}" 66 | make -C build all -j8 67 | 68 | - name: Run unit tests with sanitizer 69 | run: | 70 | cd build 71 | ctest -E system --output-on-failure 72 | cd .. 73 | 74 | unittest-for-coverage: 75 | runs-on: ubuntu-latest 76 | steps: 77 | - name: Clone This Repo 78 | uses: actions/checkout@v3 79 | 80 | - name: Build 81 | run: | 82 | # Build with logging enabled. 83 | sudo apt-get install -y lcov 84 | cmake -S test -B build/ \ 85 | -G "Unix Makefiles" \ 86 | -DCMAKE_BUILD_TYPE=Debug \ 87 | -DUNITTEST=ON \ 88 | -DCMAKE_C_FLAGS='--coverage -Wall -Wextra -Werror -DNDEBUG -Wno-error=pedantic -Wno-variadic-macros -DLOGGING_LEVEL_DEBUG=1' 89 | make -C build/ all 90 | 91 | - name: Test 92 | run: | 93 | cd build/ 94 | ctest -E system --output-on-failure 95 | cd .. 96 | 97 | - name: Run Coverage 98 | run: | 99 | make -C build/ coverage 100 | lcov --rc branch_coverage=1 -r build/coverage.info -o build/coverage.info 101 | lcov --rc branch_coverage=1 --summary build/coverage.info 102 | 103 | - name: Check Coverage 104 | uses: FreeRTOS/CI-CD-Github-Actions/coverage-cop@main 105 | with: 106 | coverage-file: ./build/coverage.info 107 | 108 | complexity: 109 | runs-on: ubuntu-latest 110 | steps: 111 | - uses: actions/checkout@v3 112 | - name: Check complexity 113 | uses: FreeRTOS/CI-CD-Github-Actions/complexity@main 114 | with: 115 | path: ./ 116 | 117 | spell-check: 118 | runs-on: ubuntu-latest 119 | steps: 120 | - name: Clone This Repo 121 | uses: actions/checkout@v3 122 | - name: Run spellings check 123 | uses: FreeRTOS/CI-CD-Github-Actions/spellings@main 124 | with: 125 | path: ./ 126 | 127 | formatting: 128 | runs-on: ubuntu-latest 129 | steps: 130 | - uses: actions/checkout@v3 131 | - name: Check formatting 132 | uses: FreeRTOS/CI-CD-Github-Actions/formatting@main 133 | with: 134 | path: ./ 135 | exclude-dirs: .git, test/unit-test/CMock 136 | 137 | git-secrets: 138 | runs-on: ubuntu-latest 139 | steps: 140 | - uses: actions/checkout@v3 141 | - name: Checkout awslabs/git-secrets 142 | uses: actions/checkout@v3 143 | with: 144 | repository: awslabs/git-secrets 145 | ref: master 146 | path: git-secrets 147 | - name: Install git-secrets 148 | run: cd git-secrets && sudo make install && cd .. 149 | - name: Run git-secrets 150 | run: | 151 | git-secrets --register-aws 152 | git-secrets --scan 153 | 154 | link-verifier: 155 | runs-on: ubuntu-latest 156 | steps: 157 | - uses: actions/checkout@v3 158 | - name: Check Links 159 | env: 160 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 161 | uses: FreeRTOS/CI-CD-Github-Actions/link-verifier@main 162 | 163 | verify-manifest: 164 | runs-on: ubuntu-latest 165 | steps: 166 | - uses: actions/checkout@v3 167 | with: 168 | submodules: true 169 | fetch-depth: 0 170 | 171 | # At time of writing the gitmodules are set not to pull 172 | # Even when using fetch submodules. Need to run this command 173 | # To force it to grab them. 174 | - name: Perform Recursive Clone 175 | shell: bash 176 | run: git submodule update --checkout --init --recursive 177 | 178 | - name: Run manifest verifier 179 | uses: FreeRTOS/CI-CD-GitHub-Actions/manifest-verifier@main 180 | with: 181 | path: ./ 182 | fail-on-incorrect-version: true 183 | 184 | doxygen: 185 | runs-on: ubuntu-latest 186 | steps: 187 | - uses: actions/checkout@v3 188 | - name: Run doxygen build 189 | uses: FreeRTOS/CI-CD-Github-Actions/doxygen@main 190 | with: 191 | path: ./ 192 | 193 | memory_statistics: 194 | runs-on: ubuntu-latest 195 | steps: 196 | - uses: actions/checkout@v3 197 | - name: Install Python3 198 | uses: actions/setup-python@v3 199 | with: 200 | python-version: "3.8" 201 | - name: Measure sizes 202 | uses: FreeRTOS/CI-CD-Github-Actions/memory_statistics@main 203 | with: 204 | config: .github/memory_statistics_config.json 205 | check_against: docs/doxygen/include/size_table.md 206 | 207 | proof_ci: 208 | if: ${{ github.event.pull_request }} || ${{ github.event.workflow }} 209 | runs-on: ubuntu-latest 210 | steps: 211 | - name: Set up CBMC runner 212 | uses: FreeRTOS/CI-CD-Github-Actions/set_up_cbmc_runner@main 213 | with: 214 | cbmc_version: "6.1.1" 215 | - name: Run CBMC 216 | uses: FreeRTOS/CI-CD-Github-Actions/run_cbmc@main 217 | with: 218 | proofs_dir: test/cbmc/proofs 219 | -------------------------------------------------------------------------------- /.github/workflows/doxygen.yml: -------------------------------------------------------------------------------- 1 | name: Doxygen Generation 2 | on: 3 | push: 4 | branches: [main] 5 | workflow_dispatch: 6 | jobs: 7 | doxygen-generation: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Doxygen generation 11 | uses: FreeRTOS/CI-CD-Github-Actions/doxygen-generation@main 12 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release automation 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | commit_id: 7 | description: 'Commit ID to tag and create a release for' 8 | required: true 9 | version_number: 10 | description: 'Release Version Number (Eg, v1.0.0)' 11 | required: true 12 | delete_existing_tag_release: 13 | description: 'Is this a re-release of existing tag/release? (Default: false)' 14 | default: 'false' 15 | required: false 16 | jobs: 17 | clean-existing-tag-and-release: 18 | if: ${{ github.event.inputs.delete_existing_tag_release == 'true' }} 19 | runs-on: ubuntu-latest 20 | env: 21 | VERSION_NUM: ${{ github.event.inputs.version_number }} 22 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 23 | steps: 24 | - name: Checkout code 25 | uses: actions/checkout@v4 26 | - name: Check if tag exists 27 | run: | 28 | git fetch origin 29 | if git tag --list $VERSION_NUM 30 | then 31 | echo "Deleting existing tag for $VERSION_NUM" 32 | git push origin --delete tags/$VERSION_NUM 33 | fi 34 | - name: Check if release exists 35 | run: | 36 | sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-key 23F3D4EA75716059 37 | sudo apt-add-repository https://cli.github.com/packages 38 | sudo apt update 39 | sudo apt-get install gh 40 | if gh release list | grep $VERSION_NUM 41 | then 42 | echo "Deleting existing release for $VERSION_NUM" 43 | gh release delete --yes $VERSION_NUM 44 | fi 45 | tag-commit: 46 | if: ${{ ( github.event.inputs.delete_existing_tag_release == 'true' && success() ) || ( github.event.inputs.delete_existing_tag_release == 'false' && always() ) }} 47 | needs: clean-existing-tag-and-release 48 | name: Generate SBOM and tag commit 49 | runs-on: ubuntu-latest 50 | steps: 51 | - name: Checkout code 52 | uses: actions/checkout@v4 53 | with: 54 | ref: ${{ github.event.inputs.commit_id }} 55 | - name: Configure git identity 56 | env: 57 | ACTOR: ${{ github.actor }} 58 | run: | 59 | git config --global user.name "$ACTOR" 60 | git config --global user.email "$ACTOR"@users.noreply.github.com 61 | - name: create a new branch that references commit id 62 | env: 63 | VERSION_NUMBER: ${{ github.event.inputs.version_number }} 64 | COMMIT_ID: ${{ github.event.inputs.commit_id }} 65 | run: git checkout -b "$VERSION_NUMBER" "$COMMIT_ID" 66 | - name: Generate SBOM 67 | uses: FreeRTOS/CI-CD-Github-Actions/sbom-generator@main 68 | with: 69 | repo_path: ./ 70 | source_path: ./source 71 | - name: commit SBOM file 72 | env: 73 | VERSION_NUMBER: ${{ github.event.inputs.version_number }} 74 | run: | 75 | git add . 76 | git commit -m 'Update SBOM' 77 | git push -u origin "$VERSION_NUMBER" 78 | - name: Tag Commit and Push to remote 79 | env: 80 | VERSION_NUMBER: ${{ github.event.inputs.version_number }} 81 | run: | 82 | git tag "$VERSION_NUMBER" -a -m "coreSNTP Library $VERSION_NUMBER" 83 | git push origin --tags 84 | - name: Verify tag on remote 85 | env: 86 | VERSION_NUMBER: ${{ github.event.inputs.version_number }} 87 | COMMIT_ID: ${{ github.event.inputs.commit_id }} 88 | run: | 89 | git tag -d "$VERSION_NUMBER" 90 | git remote update 91 | git checkout tags/$"$VERSION_NUMBER" 92 | git diff "$COMMIT_ID" tags/"$VERSION_NUMBER" 93 | create-zip: 94 | if: ${{ ( github.event.inputs.delete_existing_tag_release == 'true' && success() ) || ( github.event.inputs.delete_existing_tag_release == 'false' && always() ) }} 95 | needs: tag-commit 96 | name: Create ZIP and verify package for release asset. 97 | runs-on: ubuntu-latest 98 | steps: 99 | - name: Install ZIP tools 100 | run: sudo apt-get install zip unzip 101 | - name: Checkout code 102 | uses: actions/checkout@v4 103 | with: 104 | ref: ${{ github.event.inputs.commit_id }} 105 | path: coreSNTP 106 | submodules: recursive 107 | - name: Checkout disabled submodules 108 | run: | 109 | cd coreSNTP 110 | git submodule update --init --checkout --recursive 111 | - name: 112 | env: 113 | VERSION_NUMBER: ${{ github.event.inputs.version_number }} 114 | run: | 115 | zip -r coreSNTP-"$VERSION_NUMBER".zip coreSNTP -x "*.git*" 116 | ls ./ 117 | - name: Validate created ZIP 118 | env: 119 | VERSION_NUMBER: ${{ github.event.inputs.version_number }} 120 | run: | 121 | mkdir zip-check 122 | mv coreSNTP-"$VERSION_NUMBER".zip zip-check 123 | cd zip-check 124 | unzip coreSNTP-"$VERSION_NUMBER".zip -d coreSNTP-"$VERSION_NUMBER" 125 | ls coreSNTP-"$VERSION_NUMBER" 126 | diff -r -x "*.git*" coreSNTP-"$VERSION_NUMBER"/coreSNTP/ ../coreSNTP/ 127 | cd ../ 128 | - name: Build 129 | env: 130 | VERSION_NUMBER: ${{ github.event.inputs.version_number }} 131 | run: | 132 | cd zip-check/coreSNTP-"$VERSION_NUMBER"/coreSNTP 133 | sudo apt-get install -y lcov 134 | cmake -S test -B build/ \ 135 | -G "Unix Makefiles" \ 136 | -DCMAKE_BUILD_TYPE=Debug \ 137 | -DBUILD_UNIT_TESTS=ON \ 138 | -DCMAKE_C_FLAGS='--coverage -Wall -Wextra -DNDEBUG' 139 | make -C build/ all 140 | - name: Test 141 | env: 142 | VERSION_NUMBER: ${{ github.event.inputs.version_number }} 143 | run: | 144 | cd zip-check/coreSNTP-"$VERSION_NUMBER"/coreSNTP/build/ 145 | ctest -E system --output-on-failure 146 | cd .. 147 | - name: Create artifact of ZIP 148 | uses: actions/upload-artifact@v4 149 | with: 150 | name: coreSNTP-${{ github.event.inputs.version_number }}.zip 151 | path: zip-check/coreSNTP-${{ github.event.inputs.version_number }}.zip 152 | deploy-doxygen: 153 | needs: tag-commit 154 | if: ${{ ( github.event.inputs.delete_existing_tag_release == 'true' && success() ) || ( github.event.inputs.delete_existing_tag_release == 'false' && always() ) }} 155 | name: Deploy doxygen documentation 156 | runs-on: ubuntu-latest 157 | steps: 158 | - name: Doxygen generation 159 | uses: FreeRTOS/CI-CD-Github-Actions/doxygen-generation@main 160 | with: 161 | ref: ${{ github.event.inputs.version_number }} 162 | add_release: "true" 163 | create-release: 164 | needs: 165 | - create-zip 166 | - deploy-doxygen 167 | if: ${{ ( github.event.inputs.delete_existing_tag_release == 'true' && success() ) || ( github.event.inputs.delete_existing_tag_release == 'false' && always() ) }} 168 | name: Create Release and Upload Release Asset 169 | runs-on: ubuntu-latest 170 | steps: 171 | - name: Create Release 172 | id: create_release 173 | uses: actions/create-release@v1 174 | env: 175 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 176 | with: 177 | tag_name: ${{ github.event.inputs.version_number }} 178 | release_name: ${{ github.event.inputs.version_number }} 179 | body: Release ${{ github.event.inputs.version_number }} of the coreSNTP Library. 180 | draft: false 181 | prerelease: false 182 | - name: Download ZIP artifact 183 | uses: actions/download-artifact@v4 184 | with: 185 | name: coreSNTP-${{ github.event.inputs.version_number }}.zip 186 | - name: Upload Release Asset 187 | id: upload-release-asset 188 | uses: actions/upload-release-asset@v1 189 | env: 190 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 191 | with: 192 | upload_url: ${{ steps.create_release.outputs.upload_url }} 193 | asset_path: ./coreSNTP-${{ github.event.inputs.version_number }}.zip 194 | asset_name: coreSNTP-${{ github.event.inputs.version_number }}.zip 195 | asset_content_type: application/zip 196 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore documentation output. 2 | **/docs/**/output/* 3 | 4 | # Ignore CMake build directory. 5 | build/ 6 | 7 | # Ignore build artifacts. 8 | *.o 9 | 10 | # Ignore code coverage artifacts. 11 | *.gcda 12 | *.gcno 13 | *.gcov 14 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "test/unit-test/CMock"] 2 | path = test/unit-test/CMock 3 | url = https://github.com/ThrowTheSwitch/CMock 4 | update = none 5 | -------------------------------------------------------------------------------- /.lgtm.yml: -------------------------------------------------------------------------------- 1 | path_classifiers: 2 | library: 3 | - exclude: / 4 | extraction: 5 | # Provide build configuration for the C files. 6 | cpp: 7 | prepare: 8 | packages: 9 | - g++ 10 | after_prepare: 11 | - export CFLAGS='-Isource/include -Wall -Wextra -Werror -Wformat -Wformat-security -Warray-bounds -DSNTP_DO_NOT_USE_CUSTOM_CONFIG' 12 | index: 13 | build_command: 14 | - g++ $CFLAGS -c source/core_sntp_client.c source/core_sntp_serializer.c 15 | 16 | csharp: 17 | after_prepare: 18 | - false 19 | go: 20 | after_prepare: 21 | - false 22 | java: 23 | after_prepare: 24 | - false 25 | javascript: 26 | after_prepare: 27 | - false 28 | python: 29 | after_prepare: 30 | - false 31 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog for coreSNTP Library 2 | 3 | ## v1.3.1 (June 2024) 4 | 5 | ### Changes 6 | - Fix doxygen deployment on Github. 7 | 8 | ## v1.3.0 (May 2024) 9 | 10 | ### Changes 11 | - [#85](https://github.com/FreeRTOS/coreSNTP/pull/85) Fix MISRA C 2012 deviations. 12 | - [#83](https://github.com/FreeRTOS/coreSNTP/pull/83) Include all SntpStatus_t values in Sntp_StatusToStr. 13 | - [#81](https://github.com/FreeRTOS/coreSNTP/pull/81) Logging Print Formatter Fix. 14 | 15 | ## v1.2.0 (October 2022) 16 | 17 | ### Changes 18 | - [#63](https://github.com/FreeRTOS/coreSNTP/pull/63) Move user config includes from header to C files. 19 | - [#61](https://github.com/FreeRTOS/coreSNTP/pull/61) MISRA C:2012 compliance update 20 | - [#60](https://github.com/FreeRTOS/coreSNTP/pull/60) Update CBMC Starter kit 21 | - [#57](https://github.com/FreeRTOS/coreSNTP/pull/57) Loop Invariant Update 22 | 23 | ## v1.1.0 (November 2021) 24 | 25 | ### Changes 26 | - [#52](https://github.com/FreeRTOS/coreSNTP/pull/52) Change license from MIT-0 to MIT. 27 | - [#47](https://github.com/FreeRTOS/coreSNTP/pull/47) Update doxygen version used for documentation to 1.9.2. 28 | 29 | ## v1.0.0 (July 2021) 30 | 31 | This is the first release of an coreSNTP client library in this repository. 32 | 33 | This library implements an SNTP client for the [SNTPv4 specification](https://tools.ietf.org/html/rfc4330). It is optimized for resource-constrained devices, and does not allocate any memory. 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /MISRA.md: -------------------------------------------------------------------------------- 1 | # MISRA Compliance 2 | 3 | The coreSNTP library files conform to the [MISRA C:2012](https://www.misra.org.uk) 4 | guidelines, with some noted exceptions. Compliance is checked with Coverity static analysis. 5 | The specific deviations, suppressed inline, are listed below. 6 | 7 | Additionally, [MISRA configuration file](https://github.com/FreeRTOS/coreSNTP/blob/main/tools/coverity/misra.config) contains the project wide deviations. 8 | 9 | ### Suppressed with Coverity Comments 10 | To find the violation references in the source files run grep on the source code 11 | with ( Assuming rule 11.5 violation; with justification in point 1 ): 12 | ``` 13 | grep 'MISRA Ref 11.5.1' . -rI 14 | ``` 15 | #### Rule 11.5 16 | _Ref 11.5.1_ 17 | - MISRA C-2012 Rule 11.5 Allow casts from `void *`. The library casts the byte 18 | array information received network to a `SntpPacket_t *` for parsing SNTP packet. 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## coreSNTP Library 2 | 3 | **[API Documentation Pages for current and previous releases of this library can be found here](https://freertos.github.io/coreSNTP/)** 4 | 5 | This repository contains the coreSNTP library, a client library to use Simple 6 | Network Time Protocol (SNTP) to synchronize device clocks with internet time. 7 | This library implements the SNTPv4 specification defined in 8 | [RFC 4330](https://tools.ietf.org/html/rfc4330). 9 | 10 | An SNTP client can request time from both NTP and SNTP servers. According to the 11 | SNTPv4 specification, "_To an NTP or SNTP server, NTP and SNTP clients are 12 | indistinguishable; to an NTP or SNTP client, NTP and SNTP servers are 13 | indistinguishable._", thereby, allowing SNTP clients to request time from NTP 14 | servers. 15 | 16 | This library has gone through code quality checks including verification that no 17 | function has a 18 | [GNU Complexity](https://www.gnu.org/software/complexity/manual/complexity.html) 19 | score over 10, and checks against deviations from mandatory rules in the 20 | [MISRA coding standard](https://www.misra.org.uk). Deviations from the MISRA 21 | C:2012 guidelines are documented under [MISRA Deviations](MISRA.md). This 22 | library has also undergone both static code analysis from 23 | [Coverity static analysis](https://scan.coverity.com/), and validation of memory 24 | safety through the 25 | [CBMC automated reasoning tool](https://www.cprover.org/cbmc/). 26 | 27 | See memory requirements for this library 28 | [here](./docs/doxygen/include/size_table.md). 29 | 30 | **coreSNTP v1.3.1 31 | [source code](https://github.com/FreeRTOS/coreSNTP/tree/v1.3.1/source) is part 32 | of the 33 | [FreeRTOS 202406.00 LTS](https://github.com/FreeRTOS/FreeRTOS-LTS/tree/202406.00-LTS) 34 | release.** 35 | 36 | ### Documentation 37 | 38 | The API reference documentation for the coreSNTP library version released in 39 | [FreeRTOS/FreeRTOS](https://github.com/FreeRTOS/FreeRTOS) can be viewed from the 40 | [freertos.org website](https://freertos.org/coresntp/index.html). 41 | 42 | ## Cloning this repository 43 | 44 | This repo uses 45 | [Git Submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules) to bring 46 | in dependent components. 47 | 48 | To clone using HTTPS: 49 | 50 | ```sh 51 | git clone https://github.com/FreeRTOS/coreSNTP.git --recurse-submodules 52 | ``` 53 | 54 | Using SSH: 55 | 56 | ```sh 57 | git clone git@github.com:FreeRTOS/coreSNTP.git --recurse-submodules 58 | ``` 59 | 60 | If you have downloaded the repo without using the `--recurse-submodules` 61 | argument, you need to run: 62 | 63 | ```sh 64 | git submodule update --init --recursive 65 | ``` 66 | 67 | ## Building the library 68 | 69 | You can build the coreSNTP source files that are in the [source](source/) 70 | directory, and add [source/include](source/include) to your compiler's include 71 | path. 72 | 73 | If using CMake, the [coreSntpFilePaths.cmake](coreSntpFilePaths.cmake) file 74 | contains the above information of the source files and the header include path 75 | from this repository. 76 | 77 | ## Reference Example 78 | 79 | A reference example of using the coreSNTP library can be viewed in the 80 | `FreeRTOS/FreeRTOS` repository 81 | [here](https://github.com/FreeRTOS/FreeRTOS/tree/main/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator). 82 | The demo application showcases use of the library in order to create an SNTP 83 | client for periodic time synchronization of the system clock. 84 | 85 | ## Building Unit Tests 86 | 87 | The unit tests for the library use CMock/Unity unit testing framework. 88 | 89 | ### Checkout CMock Submodule 90 | 91 | To build unit tests, the submodule dependency of CMock is required. Use the 92 | following command to clone the submodule: 93 | 94 | ``` 95 | git submodule update --checkout --init --recursive test/unit-test/CMock 96 | ``` 97 | 98 | ### Unit Test Platform Prerequisites 99 | 100 | - For running unit tests 101 | - **C90 compiler** like gcc 102 | - **CMake 3.13.0 or later** 103 | - **Ruby 2.0.0 or later** is additionally required for the CMock test 104 | framework (that we use). 105 | - For running the coverage target, **gcov** and **lcov** are additionally 106 | required. 107 | 108 | ### Steps to build **Unit Tests** 109 | 110 | 1. Go to the root directory of this repository. (Make sure that the **CMock** 111 | submodule is cloned as described [above](#checkout-cmock-submodule)) 112 | 113 | 1. Run the _cmake_ command: `cmake -S test -B build -DUNITTEST=ON` 114 | 115 | 1. Run this command to build the library and unit tests: `make -C build all` 116 | 117 | 1. The generated test executables will be present in `build/bin/tests` folder. 118 | 119 | 1. Run `cd build && ctest` to execute all tests and view the test run summary. 120 | 121 | ## CBMC proofs 122 | 123 | To learn more about CBMC and proofs specifically, review the training material 124 | [here](https://model-checking.github.io/cbmc-training). 125 | 126 | The `test/cbmc/proofs` directory contains CBMC proofs. 127 | 128 | In order to run these proofs you will need to install CBMC and other tools by 129 | following the instructions 130 | [here](https://model-checking.github.io/cbmc-training/installation.html). 131 | 132 | ## Generating documentation 133 | 134 | The Doxygen references were created using Doxygen version 1.9.6. To generate the 135 | Doxygen pages, please run the following command from the root of this 136 | repository: 137 | 138 | ```sh 139 | doxygen docs/doxygen/config.doxyfile 140 | ``` 141 | 142 | ## Contributing 143 | 144 | See [CONTRIBUTING.md](./.github/CONTRIBUTING.md) for information on 145 | contributing. 146 | 147 | ## License 148 | 149 | This library is licensed under the MIT License. See the [LICENSE](LICENSE) file. 150 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | ## Reporting a Vulnerability 2 | 3 | If you discover a potential security issue in this project, we ask that you notify AWS/Amazon Security 4 | via our [vulnerability reporting page](https://aws.amazon.com/security/vulnerability-reporting/) or directly via email to aws-security@amazon.com. 5 | Please do **not** create a public github issue. 6 | -------------------------------------------------------------------------------- /coreSntpFilePaths.cmake: -------------------------------------------------------------------------------- 1 | # This file is to add source files and include directories 2 | # into variables so that it can be reused from different repositories 3 | # in their Cmake based build system by including this file. 4 | # 5 | # Files specific to the repository such as test runner, platform tests 6 | # are not added to the variables. 7 | 8 | # coreSNTP library source files. 9 | set( CORE_SNTP_SOURCES 10 | "${CMAKE_CURRENT_LIST_DIR}/source/core_sntp_serializer.c" 11 | "${CMAKE_CURRENT_LIST_DIR}/source/core_sntp_client.c" ) 12 | 13 | # coreSNTP library Public Include directories. 14 | set( CORE_SNTP_INCLUDE_PUBLIC_DIRS 15 | "${CMAKE_CURRENT_LIST_DIR}/source/include" ) 16 | -------------------------------------------------------------------------------- /cspell.config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | $schema: https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json 3 | version: '0.2' 4 | # Allows things like stringLength 5 | allowCompoundWords: true 6 | 7 | # Read files not to spell check from the git ignore 8 | useGitignore: true 9 | 10 | # Language settings for C 11 | languageSettings: 12 | - caseSensitive: false 13 | enabled: true 14 | languageId: c 15 | locale: "*" 16 | 17 | # Add a dictionary, and the path to the word list 18 | dictionaryDefinitions: 19 | - name: freertos-words 20 | path: '.github/.cSpellWords.txt' 21 | addWords: true 22 | 23 | dictionaries: 24 | - freertos-words 25 | 26 | # Paths and files to ignore 27 | ignorePaths: 28 | - 'dependency' 29 | - 'docs' 30 | - 'ThirdParty' 31 | - 'History.txt' 32 | -------------------------------------------------------------------------------- /docs/doxygen/code_examples/example_sntp_client_posix.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "core_sntp_client.h" 11 | 12 | /* @[code_example_sntpdnsresolve] */ 13 | /* Example POSIX implementation of SntpDnsReolve_t interface. */ 14 | static bool resolveDns( const SntpServerInfo_t * pServerAddr, 15 | uint32_t * pIpV4Addr ) 16 | { 17 | bool status = false; 18 | int32_t dnsStatus = -1; 19 | struct addrinfo hints; 20 | struct addrinfo * pListHead = NULL; 21 | 22 | hints.ai_family = AF_UNSPEC; 23 | 24 | hints.ai_socktype = ( int32_t ) SOCK_STREAM; 25 | hints.ai_protocol = IPPROTO_TCP; 26 | 27 | dnsStatus = getaddrinfo( pServerAddr->pServerName, NULL, &hints, &pListHead ); 28 | 29 | if( dnsStatus == 0 ) 30 | { 31 | struct sockaddr_in * pAddrInfo = ( struct sockaddr_in * ) pListHead->ai_addr; 32 | inet_ntop( pAddrInfo->sin_family, 33 | &pAddrInfo->sin_addr, 34 | ( int8_t * ) pIpV4Addr, 35 | INET_ADDRSTRLEN ); 36 | 37 | status = true; 38 | } 39 | 40 | freeaddrinfo( pListHead ); 41 | 42 | return status; 43 | } 44 | /* @[code_example_sntpdnsresolve] */ 45 | 46 | /* @[code_example_networkcontext] */ 47 | /* Example definition of NetworkContext_t for UDP socket operations. */ 48 | struct NetworkContext 49 | { 50 | int udpSocket; 51 | }; 52 | /* @[code_example_networkcontext] */ 53 | 54 | /* @[code_example_udptransport_sendto] */ 55 | /* Example POSIX implementation of the UdpTransportSendTo_t function of UDP transport interface. */ 56 | static int32_t UdpTransport_Send( NetworkContext_t * pNetworkContext, 57 | uint32_t serverAddr, 58 | uint16_t serverPort, 59 | const void * pBuffer, 60 | uint16_t bytesToSend ) 61 | { 62 | int32_t bytesSent = -1, pollStatus = 1; 63 | struct pollfd pollFds; 64 | 65 | pollFds.events = POLLOUT | POLLPRI; 66 | pollFds.revents = 0; 67 | pollFds.fd = pNetworkContext->udpSocket; 68 | 69 | /* Check if there is data to read from the socket. */ 70 | pollStatus = poll( &pollFds, 1, 0 ); 71 | 72 | if( pollStatus > 0 ) 73 | { 74 | struct sockaddr_in addrInfo; 75 | addrInfo.sin_family = AF_INET; 76 | addrInfo.sin_port = htons( serverPort ); 77 | addrInfo.sin_addr.s_addr = htonl( serverAddr ); 78 | 79 | bytesSent = sendto( pNetworkContext->udpSocket, 80 | pBuffer, 81 | bytesToSend, 0, 82 | ( const struct sockaddr * ) &addrInfo, 83 | sizeof( addrInfo ) ); 84 | } 85 | else if( pollStatus == 0 ) 86 | { 87 | bytesSent = 0; 88 | } 89 | 90 | return bytesSent; 91 | } 92 | /* @[code_example_udptransport_sendto] */ 93 | 94 | /* @[code_example_udptransport_recvfrom] */ 95 | /* Example POSIX implementation of the UdpTransportRecvFrom_t function of UDP transport interface. */ 96 | static int32_t UdpTransport_Recv( NetworkContext_t * pNetworkContext, 97 | uint32_t serverAddr, 98 | uint16_t serverPort, 99 | void * pBuffer, 100 | uint16_t bytesToRecv ) 101 | { 102 | int32_t bytesReceived = -1, pollStatus = 1; 103 | struct pollfd pollFds; 104 | 105 | pollFds.events = POLLIN | POLLPRI; 106 | pollFds.revents = 0; 107 | pollFds.fd = pNetworkContext->udpSocket; 108 | 109 | /* Check if there is data to read from the socket. */ 110 | pollStatus = poll( &pollFds, 1, 0 ); 111 | 112 | if( pollStatus > 0 ) 113 | { 114 | struct sockaddr_in addrInfo; 115 | addrInfo.sin_family = AF_INET; 116 | addrInfo.sin_port = htons( serverPort ); 117 | addrInfo.sin_addr.s_addr = htonl( serverAddr ); 118 | socklen_t addrLen = sizeof( addrInfo ); 119 | 120 | bytesReceived = recvfrom( pNetworkContext->udpSocket, pBuffer, 121 | bytesToRecv, 0, 122 | ( struct sockaddr * ) &addrInfo, 123 | &addrLen ); 124 | } 125 | else if( pollStatus == 0 ) 126 | { 127 | bytesReceived = 0; 128 | } 129 | 130 | return bytesReceived; 131 | } 132 | /* @[code_example_udptransport_recvfrom] */ 133 | 134 | /* @[code_example_sntpsettime] */ 135 | /* Example implementation of the SntpSetTime_t interface for POSIX platforms. */ 136 | static void sntpClient_SetTime( const SntpServerInfo_t * pTimeServer, 137 | const SntpTimestamp_t * pServerTime, 138 | int64_t clockOffsetMs, 139 | SntpLeapSecondInfo_t leapSecondInfo ) 140 | { 141 | /* @[code_example_sntp_converttounixtime] */ 142 | uint32_t unixSecs; 143 | uint32_t unixMs; 144 | SntpStatus_t status = Sntp_ConvertToUnixTime( pServerTime, &unixSecs, &unixMs ); 145 | 146 | /* @[code_example_sntp_converttounixtime] */ 147 | assert( status == SntpSuccess ); 148 | 149 | struct timespec serverTime = 150 | { 151 | .tv_sec = unixSecs, 152 | .tv_nsec = unixMs * 1000 153 | }; 154 | 155 | clock_settime( CLOCK_REALTIME, &serverTime ); 156 | } 157 | /* @[code_example_sntpsettime] */ 158 | 159 | /* @[code_example_sntpgettime] */ 160 | /* Example implementation of the SntpGetTime_t interface for POSIX platforms. */ 161 | static void sntpClient_GetTime( SntpTimestamp_t * pCurrentTime ) 162 | { 163 | struct timespec currTime; 164 | 165 | ( void ) clock_gettime( CLOCK_REALTIME, &currTime ); 166 | 167 | pCurrentTime->seconds = currTime.tv_sec; 168 | pCurrentTime->fractions = ( currTime.tv_nsec / 1000 ) * SNTP_FRACTION_VALUE_PER_MICROSECOND; 169 | } 170 | /* @[code_example_sntpgettime] */ 171 | 172 | /* Configuration constants for the example SNTP client. */ 173 | 174 | /* Following Time Servers are used for illustrating the usage of library API. 175 | * The library can be configured to use ANY time server, whether publicly available 176 | * time service like NTP Pool or a privately owned NTP server. */ 177 | #define TEST_TIME_SERVER_1 "0.pool.ntp.org" 178 | #define TEST_TIME_SERVER_2 "1.pool.ntp.org" 179 | 180 | #define SERVER_RESPONSE_TIMEOUT_MS 3000 181 | #define TIME_REQUEST_SEND_WAIT_TIME_MS 2000 182 | #define TIME_REQUEST_RECEIVE_WAIT_TIME_MS 1000 183 | 184 | #define SYSTEM_CLOCK_FREQUENCY_TOLERANCE_PPM 500 185 | #define SYSTEM_CLOCK_DESIRED_ACCURACY_MS 300 186 | 187 | int main( void ) 188 | { 189 | /* @[code_example_sntp_init] */ 190 | /* Memory for network buffer. */ 191 | uint8_t networkBuffer[ SNTP_PACKET_BASE_SIZE ]; 192 | 193 | /* Create UDP socket. */ 194 | NetworkContext_t udpContext; 195 | 196 | udpContext.udpSocket = socket( AF_INET, SOCK_DGRAM, 0 ); 197 | 198 | /* Setup list of time servers. */ 199 | SntpServerInfo_t pTimeServers[] = 200 | { 201 | { 202 | .port = SNTP_DEFAULT_SERVER_PORT, 203 | .pServerName = TEST_TIME_SERVER_1, 204 | .serverNameLen = strlen( TEST_TIME_SERVER_1 ) 205 | }, 206 | { 207 | .port = SNTP_DEFAULT_SERVER_PORT, 208 | .pServerName = TEST_TIME_SERVER_2, 209 | .serverNameLen = strlen( TEST_TIME_SERVER_2 ) 210 | } 211 | }; 212 | 213 | /* Set the UDP transport interface object. */ 214 | UdpTransportInterface_t udpTransportIntf; 215 | 216 | udpTransportIntf.pUserContext = &udpContext; 217 | udpTransportIntf.sendTo = UdpTransport_Send; 218 | udpTransportIntf.recvFrom = UdpTransport_Recv; 219 | 220 | /* Context variable. */ 221 | SntpContext_t context; 222 | 223 | /* Initialize context. */ 224 | SntpStatus_t status = Sntp_Init( &context, 225 | pTimeServers, 226 | sizeof( pTimeServers ) / sizeof( SntpServerInfo_t ), 227 | SERVER_RESPONSE_TIMEOUT_MS, 228 | networkBuffer, 229 | SNTP_PACKET_BASE_SIZE, 230 | resolveDns, 231 | sntpClient_GetTime, 232 | sntpClient_SetTime, 233 | &udpTransportIntf, 234 | NULL ); 235 | 236 | assert( status == SntpSuccess ); 237 | /* @[code_example_sntp_init] */ 238 | 239 | /* Calculate the polling interval period for the SNTP client. */ 240 | /* @[code_example_sntp_calculatepollinterval] */ 241 | uint32_t pollingIntervalPeriod; 242 | 243 | status = Sntp_CalculatePollInterval( SYSTEM_CLOCK_FREQUENCY_TOLERANCE_PPM, 244 | SYSTEM_CLOCK_DESIRED_ACCURACY_MS, 245 | &pollingIntervalPeriod ); 246 | /* @[code_example_sntp_calculatepollinterval] */ 247 | assert( status == SntpSuccess ); 248 | 249 | /* Loop of SNTP client for period time synchronization. */ 250 | /* @[code_example_sntp_send_receive] */ 251 | while( 1 ) 252 | { 253 | status = Sntp_SendTimeRequest( &context, 254 | rand() % UINT32_MAX, 255 | TIME_REQUEST_SEND_WAIT_TIME_MS ); 256 | assert( status == SntpSuccess ); 257 | 258 | do 259 | { 260 | status = Sntp_ReceiveTimeResponse( &context, TIME_REQUEST_RECEIVE_WAIT_TIME_MS ); 261 | } while( status == SntpNoResponseReceived ); 262 | 263 | assert( status == SntpSuccess ); 264 | 265 | /* Delay of poll interval period before next time synchronization. */ 266 | sleep( pollingIntervalPeriod ); 267 | } 268 | 269 | /* @[code_example_sntp_send_receive] */ 270 | 271 | return EXIT_SUCCESS; 272 | } 273 | -------------------------------------------------------------------------------- /docs/doxygen/images/Dependency_Architecture_Diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreeRTOS/coreSNTP/1cbb9a46d0223e4cea621167c38dc8a4aabaa476/docs/doxygen/images/Dependency_Architecture_Diagram.png -------------------------------------------------------------------------------- /docs/doxygen/images/Ntp_To_Unix_Time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreeRTOS/coreSNTP/1cbb9a46d0223e4cea621167c38dc8a4aabaa476/docs/doxygen/images/Ntp_To_Unix_Time.png -------------------------------------------------------------------------------- /docs/doxygen/include/size_table.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
Code Size of coreSNTP (example generated with GCC for ARM Cortex-M)
File
With -O1 Optimization
With -Os Optimization
core_sntp_client.c
1.7K
1.3K
core_sntp_serializer.c
1.0K
0.7K
Total estimates
2.7K
2.0K
26 | -------------------------------------------------------------------------------- /docs/doxygen/layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | -------------------------------------------------------------------------------- /docs/doxygen/pages.dox: -------------------------------------------------------------------------------- 1 | /** 2 | @mainpage Overview 3 | @anchor sntp 4 | @brief coreSNTP Library 5 | 6 | The coreSNTP library provides a client for the Simple Network Time Protocol (SNTP) to allow devices to synchronize their system clocks with internet time. This library implements the SNTPv4 specification defined in [RFC 4330](https://tools.ietf.org/html/rfc4330). 7 |

8 | An SNTP client can request time from both NTP and SNTP servers. According to the SNTPv4 specification, 9 | > To an NTP or SNTP server, NTP and SNTP clients are indistinguishable; to an NTP or SNTP client, NTP and SNTP servers are indistinguishable. 10 | [RFC4330](https://tools.ietf.org/html/rfc4330)
11 | 12 | This library is optimized for resource constrained embedded devices. Features of this library include: 13 | - Fully synchronous API, to allow applications to completely manage their concurrency and multi-threading method. 14 | - Operations on fixed buffers, so that applications may control their memory allocation strategy. 15 | - Flexibility to develop an application with either: 16 | - The serializer/de-serializer API which allows complete control over the operations of the SNTP client. 17 | OR 18 | - The client API that handles operations of communicating over the network, performing authentication, and handling rejected server responses. 19 |

20 | 21 | @section sntp_memory_requirements Memory Requirements 22 | @brief Memory requirements of the coreSNTP library. 23 | 24 | @include{doc} size_table.md 25 | 26 | @section sntp_design Design 27 | @brief coreSNTP Library Design 28 | 29 |

30 | 31 | The coreSNTP library provides 2 API layers: 32 | 1. Serializer/Deserializer and Utilities - This layer provides functionality for serializing SNTP time requests and deserializing SNTP response packets, as well as some utility functions helpful in setting up an SNTP client in an application. 33 | 2. Client - This layer provides **managed** functionality for network operations including DNS resolution, sending and receiving SNTP packets over UDP, authenticating servers for security (if enabled), and handling of 34 | server rejection of time requests. 35 | **Note**: This client API layer performs network and authentication operations through user-defined implementation of interfaces exposed by the library. 36 | 37 | Following is the architecture diagram of the library. It showcases the 2 tiers of the library and the interfaces on which the **Managed Client** layer depends on. 38 | 39 | \image html Dependency_Architecture_Diagram.png 40 | 41 | @section mqtt_interfaces Interfaces and Callbacks 42 | 43 | As visible in the above architecture diagram, the Managed Client API layer depends on the following interfaces that are user-defined for platform-specific operations: 44 | - [DNS Resolve Interface](@ref SntpResolveDns_t) - This allows library to resolve DNS addresses of time servers by the application. 45 | - [UDP Transport Interface](@ref UdpTransportInterface_t) - This allows library to send and receive SNTP packets over network UDP layer to communicate with SNTP/NTP servers. 46 | - [Get Time Interface](@ref SntpGetTime_t) - This allows library to obtain system time for tracking timeouts as well as creating SNTP time requests. 47 | - [Set Time Interface](@ref SntpSetTime_t) - This allows library to notify application about updating system time with the latest time provided by server as well as the system clock drift calculated by library. 48 | - [Authentication Interface](@ref SntpAuthenticationInterface_t) (Optional) - This allows library to perform mutual authentication in communicating with time servers for security. It is RECOMMENDED that applications enable authentication when communicating with time servers. 49 | 50 |

51 | */ 52 | 53 | /** 54 | @page core_sntp_config Configurations 55 | @brief Configurations of the coreSNTP Library. 56 | 57 | @par configpagestyle 58 | 59 | All the configurations settings for the coreSNTP library are function-like macros for logging. They can be set with a `\#define` in the config file (`core_sntp_config.h`) or by using a compiler option such as -D in gcc. 60 | 61 | @section SNTP_DO_NOT_USE_CUSTOM_CONFIG 62 | @copydoc SNTP_DO_NOT_USE_CUSTOM_CONFIG 63 | 64 | @section sntp_logerror LogError 65 | @copydoc LogError 66 | 67 | @section sntp_logwarn LogWarn 68 | @copydoc LogWarn 69 | 70 | @section sntp_loginfo LogInfo 71 | @copydoc LogInfo 72 | 73 | @section sntp_logdebug LogDebug 74 | @copydoc LogDebug 75 | */ 76 | 77 | /** 78 | @page sntp_functions Functions 79 | @brief Primary functions of the SNTP library:

80 | @subpage sntp_init_function
81 | @subpage sntp_sendtimerequest_function
82 | @subpage sntp_receivetimeresponse_function
83 | @subpage sntp_serializerequest_function
84 | @subpage sntp_deserializeresponse_function
85 | @subpage sntp_calculatepollinterval_function
86 | @subpage sntp_converttounixtime_function
87 | 88 | @page sntp_init_function Sntp_Init 89 | @snippet core_sntp_client.h define_sntp_init 90 | @copydoc Sntp_Init 91 | 92 | For an example POSIX application of using the coreSNTP library APIs to create an SNTP client, refer to @ref code_example. 93 | Below is the part of the code example relevant to the @ref Sntp_Init API. 94 | @snippet example_sntp_client_posix.c code_example_sntp_init 95 | 96 | @page sntp_sendtimerequest_function Sntp_SendTimeRequest 97 | @copydoc Sntp_SendTimeRequest 98 | 99 | For an example POSIX application of using the coreSNTP library APIs to create an SNTP client, refer to @ref code_example. 100 | Below is the part of the code example relevant to the @ref Sntp_ReceiveTimeResponse API. 101 | @snippet example_sntp_client_posix.c code_example_sntp_send_receive 102 | 103 | @page sntp_receivetimeresponse_function Sntp_ReceiveTimeResponse 104 | @copydoc Sntp_ReceiveTimeResponse 105 | 106 | For an example POSIX application of the coreSNTP library APIs to create an SNTP client, refer to @ref code_example. 107 | Below is the part of the example application relevant to the @ref Sntp_ReceiveTimeResponse API. 108 | @snippet example_sntp_client_posix.c code_example_sntp_send_receive 109 | 110 | @page sntp_serializerequest_function Sntp_SerializeRequest 111 | @copydoc Sntp_SerializeRequest 112 | 113 | @page sntp_deserializeresponse_function Sntp_DeserializeResponse 114 | @copydoc Sntp_DeserializeResponse 115 | 116 | @page sntp_calculatepollinterval_function Sntp_CalculatePollInterval 117 | @copydoc Sntp_CalculatePollInterval 118 | 119 | Here is a code example of using the API. 120 | @snippet example_sntp_client_posix.c code_example_sntp_calculatepollinterval 121 | 122 | @page sntp_converttounixtime_function Sntp_ConvertToUnixTime 123 | @copydoc Sntp_ConvertToUnixTime 124 | 125 | Here is a code example of using the API. 126 | @snippet example_sntp_client_posix.c code_example_sntp_converttounixtime 127 | */ 128 | 129 | /** 130 | @page code_example Example application of using coreSNTP APIs 131 | @brief Example application of setting up an SNTP client with coreSNTP Library on POSIX platforms. 132 | 133 | This code ONLY showcases how coreSNTP library APIs can be used. For best practices on running an SNTP client, 134 | refer to the [FreeRTOS Demo on GitHub](https://github.com/FreeRTOS/FreeRTOS/tree/main/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator).
135 | @include example_sntp_client_posix.c 136 | */ 137 | 138 | 139 | /** 140 | @defgroup sntp_enum_types Enumerated Types 141 | @brief Enumerated types of the coreSNTP library 142 | */ 143 | 144 | /** 145 | @defgroup sntp_callback_types Callback Types 146 | @brief Callback function pointer types of the coreSNTP library 147 | */ 148 | 149 | /** 150 | @defgroup sntp_struct_types Struct Types 151 | @brief Struct types of the coreSNTP library 152 | */ 153 | 154 | /** 155 | @defgroup sntp_constants Constants 156 | @brief Constants defined in the coreSNTP library 157 | */ 158 | -------------------------------------------------------------------------------- /docs/doxygen/porting.dox: -------------------------------------------------------------------------------- 1 | /** 2 | @page sntp_porting Porting Guide 3 | @brief Guide for porting coreSNTP library to a new platform. 4 | 5 | A port of coreSNTP library for a new platform must provide the following components: 6 | 1. [Logging Configuration Macros](@ref sntp_porting_config) 7 | 2. [DNS Resolve Function](@ref sntp_porting_dnsresolve) 8 | 3. [UDP Transport Interface](@ref sntp_porting_transport) 9 | 4. [Get Time Function](@ref sntp_porting_gettime) 10 | 5. [Set Time Function](@ref sntp_porting_settime) 11 | 6. [Authentication Interface](@ref sntp_porting_authentication) 12 | 13 | @section sntp_porting_config Configuration Macros for Logging 14 | @brief Macros for enabling logging that can be defined through the config header `core_sntp_config.h`, or passed in as compiler options. 15 | 16 | @note If a custom configuration header `core_sntp_config.h` is not provided, then the @ref SNTP_DO_NOT_USE_CUSTOM_CONFIG macro must be defined. 17 | 18 | @see [Configurations](@ref core_sntp_config) 19 | 20 | The following logging macros are used throughout the library: 21 | - @ref LogError 22 | - @ref LogWarn 23 | - @ref LogInfo 24 | - @ref LogDebug 25 | 26 | Here is an example implementation of logging macros for POSIX platforms 27 | @snippet core_sntp_config.h code_example_loggingmacros 28 | 29 | @section sntp_porting_dnsresolve DNS Resolve Function 30 | @brief The coreSNTP library requires a DNS Resolve interface that must be implemented to obtain the latest IPv4 31 | address information of a time server before sending it a time request. 32 | 33 | @see [DNS Resolve Function](@ref SntpResolveDns_t) 34 | 35 | @note The coreSNTP library will re-resolve the DNS name of a time server on each attempt of requesting time from it. 36 | For efficiency of DNS resolution operations, your implementation can utilize DNS caching of resolved domains if 37 | your platform supports it. 38 | 39 | @snippet example_sntp_client_posix.c code_example_sntpdnsresolve 40 | 41 | @section sntp_porting_transport UDP Transport Interface 42 | @brief The coreSNTP library requires a UDP transport interface that must be implemented 43 | in order to send and receive SNTP packets over the network. 44 | 45 | @see [UDP Transport Interface](@ref UdpTransportInterface_t) 46 | 47 | @note For security against unwanted server response packets, it is RECOMMENDED that the UDP socket that is used 48 | for implementing the UDP transport interface functions of performing network I/O is kept open ONLY during 49 | duration of an SNTP request-response iteration as opposed to keeping it always open across iterations. One way to achieve this is to open a new UDP socket before calling @ref Sntp_SendTimeRequest API and close it after receiving server response (or timeout) with the @ref Sntp_ReceiveTimeResponse API. 50 | 51 | A port must implement functions corresponding to the following functions pointers: 52 | - [UDP Transport Send](@ref UdpTransportSendTo_t): A function to send bytes on the network over UDP. It is RECOMMENDED to implement this function as non-blocking so the total block time can be managed by the @ref Sntp_SendTimeRequest API. 53 | 54 | @snippet example_sntp_client_posix.c code_example_udptransport_sendto 55 | 56 | - [UDP Transport Receive](@ref UdpTransportRecvFrom_t): A function to receive bytes from the network over UDP. It is RECOMMENDED to implement this function as non-blocking so the total block time can be managed by the @ref Sntp_ReceiveTimeResponse API. 57 | 58 | @snippet example_sntp_client_posix.c code_example_udptransport_recvfrom 59 | 60 | The above two functions take in a pointer to a @ref NetworkContext_t, the typename of a 61 | `struct NetworkContext`. The NetworkContext struct must also be defined by the port, and 62 | ought to contain any information necessary to send and receive data with the @ref UdpTransportSendTo_t 63 | and @ref UdpTransportRecvFrom_t implementations, respectively: 64 | 65 | @snippet example_sntp_client_posix.c code_example_networkcontext 66 | 67 | @section sntp_porting_gettime Get Time Function 68 | @brief The coreSNTP library uses this function to obtain time from system for tracking timeout 69 | durations as well as generating SNTP request packet. 70 | 71 | @see @ref SntpGetTime_t 72 | 73 | If the device does not have real-world time information (on device boot-up for example), it is 74 | acceptable for this function to provide the system-time that does not match the real-world time, because once a 75 | time information is received from a time server, the system time can be corrected to match the real-world time. 76 | Refer to the next section on how to correct the system time. 77 | 78 | @snippet example_sntp_client_posix.c code_example_sntpgettime 79 | 80 | @section sntp_porting_settime Set Time Function 81 | @brief The coreSNTP library calls this function to notify the device about the latest time received 82 | from a time server as well as the clock drift of the system time from the server time. 83 | 84 | @snippet example_sntp_client_posix.c code_example_sntpsettime 85 | 86 | @see @ref SntpSetTime_t 87 | 88 | Platforms should implement this function to perform clock disciple operation on the system clock, that is appropriate for 89 | the clock accuracy needs of the application. 90 | 91 | @section sntp_porting_authentication Authentication Interface 92 | @brief The coreSNTP library exposes an authentication interface to allow customer-chosen authentication mechanism to be used 93 | in SNTP communication with time server(s) for security. 94 | 95 | @note It is RECOMMENDED to enable authentication in communication with your time server(s) of choice to protect against attacks 96 | that modify or spoof server responses. The SNTPv4 protocol is flexible to be used with any symmetric-key or asymmetric key 97 | cryptographic algorithm depending on the support provided by time servers of your choice. For an example of using AES-128-CMAC 98 | as the authentication algorithm, please refer to [coreSNTP demo in FreeRTOS/FreeRTOS repository](https://github.com/FreeRTOS/FreeRTOS/tree/main/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator). 99 | 100 | 101 | @see @ref SntpAuthenticationInterface_t 102 | A port that uses authentication to communicate with time server must implement the following function pointers: 103 | - [Add client authentication code](@ref SntpGenerateAuthCode_t): A function to generate and append authentication data for client to be validated 104 | by the time server. The first @ref SNTP_PACKET_BASE_SIZE bytes in the buffer supplied to this function contains the SNTP request data which can be used to 105 | generate the authentication code. The generated authentication code SHOULD be written to the same buffer after the first @ref SNTP_PACKET_BASE_SIZE bytes. 106 | This function should also return the number of authentication bytes appended to the library through an output parameter, so that the library knows about the 107 | total size of the SNTP packet. 108 | 109 | - [Validate server authentication](@ref SntpValidateServerAuth_t): A function to validate the authentication code in a received SNTP time response from the 110 | network to confirm that the expected server is the sender of the response and the timestamps in the packet are trustworthy to 111 | update system time. This server authentication data is usually validated by checking that the data can be regenerated by the client from 112 | the first #SNTP_PACKET_BASE_SIZE bytes of the received SNTP packet from the network. 113 | 114 | The above two functions take in a pointer to a @ref SntpAuthContext_t, the typename of a `struct SntpAuthContext`. The `SntpAuthContext` struct must 115 | also be defined by the port, to store necessary information (like a PKCS#11 label representing credential secret) for performing cryptographic generation 116 | and validation operations in the @ref SntpGenerateAuthCode_t and @ref SntpValidateServerAuth_t functions respectively. 117 | 118 | */ 119 | -------------------------------------------------------------------------------- /docs/doxygen/style.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Stylesheet for Doxygen HTML output. 3 | * 4 | * This file defines styles for custom elements in the header/footer and 5 | * overrides some of the default Doxygen styles. 6 | * 7 | * Styles in this file do not affect the treeview sidebar. 8 | */ 9 | 10 | /* Set the margins to place a small amount of whitespace on the left and right 11 | * side of the page. */ 12 | div.contents { 13 | margin-left:4em; 14 | margin-right:4em; 15 | } 16 | 17 | /* Justify text in paragraphs. */ 18 | p { 19 | text-align: justify; 20 | } 21 | 22 | /* Style of section headings. */ 23 | h1 { 24 | border-bottom: 1px solid #879ECB; 25 | color: #354C7B; 26 | font-size: 160%; 27 | font-weight: normal; 28 | padding-bottom: 4px; 29 | padding-top: 8px; 30 | } 31 | 32 | /* Style of subsection headings. */ 33 | h2:not(.memtitle):not(.groupheader) { 34 | font-size: 125%; 35 | margin-bottom: 0px; 36 | margin-top: 16px; 37 | padding: 0px; 38 | } 39 | 40 | /* Style of paragraphs immediately after subsection headings. */ 41 | h2 + p { 42 | margin: 0px; 43 | padding: 0px; 44 | } 45 | 46 | /* Style of subsection headings. */ 47 | h3 { 48 | font-size: 100%; 49 | margin-bottom: 0px; 50 | margin-left: 2em; 51 | margin-right: 2em; 52 | } 53 | 54 | /* Style of paragraphs immediately after subsubsection headings. */ 55 | h3 + p { 56 | margin-top: 0px; 57 | margin-left: 2em; 58 | margin-right: 2em; 59 | } 60 | 61 | /* Style of the prefix "AWS IoT Device SDK C" that appears in the header. */ 62 | #csdkprefix { 63 | color: #757575; 64 | } 65 | 66 | /* Style of the "Return to main page" link that appears in the header. */ 67 | #returntomain { 68 | padding: 0.5em; 69 | } 70 | 71 | /* Style of the dividers on Configuration Settings pages. */ 72 | div.configpagedivider { 73 | margin-left: 0px !important; 74 | margin-right: 0px !important; 75 | margin-top: 20px !important; 76 | } 77 | 78 | /* Style of configuration setting names. */ 79 | dl.section.user ~ h1 { 80 | border-bottom: none; 81 | color: #000000; 82 | font-family: monospace, fixed; 83 | font-size: 16px; 84 | margin-bottom: 0px; 85 | margin-left: 2em; 86 | margin-top: 1.5em; 87 | } 88 | 89 | /* Style of paragraphs on a configuration settings page. */ 90 | dl.section.user ~ * { 91 | margin-bottom: 10px; 92 | margin-left: 4em; 93 | margin-right: 4em; 94 | margin-top: 0px; 95 | } 96 | 97 | /* Hide the configuration setting marker. */ 98 | dl.section.user { 99 | display: none; 100 | } 101 | 102 | /* Overrides for code fragments and lines. */ 103 | div.fragment { 104 | background: #ffffff; 105 | border: none; 106 | padding: 5px; 107 | } 108 | 109 | div.line { 110 | color: #3a3a3a; 111 | } 112 | 113 | /* Overrides for code syntax highlighting colors. */ 114 | span.comment { 115 | color: #008000; 116 | } 117 | 118 | span.keyword, span.keywordtype, span.keywordflow { 119 | color: #0000ff; 120 | } 121 | 122 | span.preprocessor { 123 | color: #50015a; 124 | } 125 | 126 | span.stringliteral, span.charliteral { 127 | color: #800c0c; 128 | } 129 | 130 | a.code, a.code:visited, a.line, a.line:visited { 131 | color: #496194; 132 | } 133 | -------------------------------------------------------------------------------- /manifest.yml: -------------------------------------------------------------------------------- 1 | name : "coreSNTP" 2 | version: "v1.3.1" 3 | description: | 4 | "SNTP client library to allow embedded devices to synchronize time with time servers.\n" 5 | license: "MIT" 6 | 7 | dependencies: 8 | - name: "CMock" 9 | version: v2.5.3 10 | license: "MIT" 11 | repository: 12 | type: "git" 13 | url: "https://github.com/ThrowTheSwitch/CMock.git" 14 | path: test/unit-test/CMock 15 | -------------------------------------------------------------------------------- /source/include/core_sntp_config_defaults.h: -------------------------------------------------------------------------------- 1 | /* 2 | * coreSNTP v1.3.1 3 | * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * SPDX-License-Identifier: MIT 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | * this software and associated documentation files (the "Software"), to deal in 9 | * the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 | * the Software, and to permit persons to whom the Software is furnished to do so, 12 | * subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 19 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 21 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @file core_sntp_config_defaults.h 27 | * @brief This file represents the default values for the configuration macros 28 | * of the coreSNTP library. 29 | * 30 | * @note This file SHOULD NOT be modified. If custom values are needed for 31 | * any configuration macro, a core_sntp_config.h file should be provided to 32 | * the SNTP library to override the default values defined in this file. 33 | * To build the library with the core_sntp_config.h file, make sure to 34 | * not set the SNTP_DO_NOT_USE_CUSTOM_CONFIG preprocessor macro. 35 | */ 36 | 37 | #ifndef CORE_SNTP_CONFIG_DEFAULTS_H_ 38 | #define CORE_SNTP_CONFIG_DEFAULTS_H_ 39 | 40 | /* The macro definition for SNTP_DO_NOT_USE_CUSTOM_CONFIG is for Doxygen 41 | * documentation only. */ 42 | 43 | /** 44 | * @brief Define this macro to build the SNTP library without the custom config 45 | * file core_sntp_config.h. 46 | * 47 | * Without the custom config, the SNTP library builds with 48 | * default values of config macros defined in core_sntp_config_defaults.h file. 49 | * 50 | * If a custom config is provided, then SNTP_DO_NOT_USE_CUSTOM_CONFIG should not 51 | * be defined. 52 | */ 53 | #ifdef DOXYGEN 54 | #define SNTP_DO_NOT_USE_CUSTOM_CONFIG 55 | #endif 56 | 57 | /* SNTP_DO_NOT_USE_CUSTOM_CONFIG allows building the SNTP library 58 | * without a custom config. If a custom config is provided, the 59 | * SNTP_DO_NOT_USE_CUSTOM_CONFIG macro should not be defined. */ 60 | #ifndef SNTP_DO_NOT_USE_CUSTOM_CONFIG 61 | #include "core_sntp_config.h" 62 | #endif 63 | 64 | /** 65 | * @brief Macro that is called in the SNTP library for logging "Error" level 66 | * messages. 67 | * 68 | * To enable error level logging in the SNTP library, this macro should be mapped to the 69 | * application-specific logging implementation that supports error logging. 70 | * 71 | * @note This logging macro is called in the SNTP library with parameters wrapped in 72 | * double parentheses to be ISO C89/C90 standard compliant. For a reference 73 | * POSIX implementation of the logging macros, refer to core_sntp_config.h files, and the 74 | * logging-stack in demos folder of the 75 | * [AWS IoT Embedded C SDK repository](https://github.com/aws/aws-iot-device-sdk-embedded-C). 76 | * 77 | * Default value: Error logging is turned off, and no code is generated for calls 78 | * to the macro in the SNTP library on compilation. 79 | */ 80 | #ifndef LogError 81 | #define LogError( message ) 82 | #endif 83 | 84 | /** 85 | * @brief Macro that is called in the SNTP library for logging "Warning" level 86 | * messages. 87 | * 88 | * To enable warning level logging in the SNTP library, this macro should be mapped to the 89 | * application-specific logging implementation that supports warning logging. 90 | * 91 | * @note This logging macro is called in the SNTP library with parameters wrapped in 92 | * double parentheses to be ISO C89/C90 standard compliant. For a reference 93 | * POSIX implementation of the logging macros, refer to core_sntp_config.h files, and the 94 | * logging-stack in demos folder of the 95 | * [AWS IoT Embedded C SDK repository](https://github.com/aws/aws-iot-device-sdk-embedded-C/). 96 | * 97 | * Default value: Warning logs are turned off, and no code is generated for calls 98 | * to the macro in the SNTP library on compilation. 99 | */ 100 | #ifndef LogWarn 101 | #define LogWarn( message ) 102 | #endif 103 | 104 | /** 105 | * @brief Macro that is called in the SNTP library for logging "Info" level 106 | * messages. 107 | * 108 | * To enable info level logging in the SNTP library, this macro should be mapped to the 109 | * application-specific logging implementation that supports info logging. 110 | * 111 | * @note This logging macro is called in the SNTP library with parameters wrapped in 112 | * double parentheses to be ISO C89/C90 standard compliant. For a reference 113 | * POSIX implementation of the logging macros, refer to core_sntp_config.h files, and the 114 | * logging-stack in demos folder of the 115 | * [AWS IoT Embedded C SDK repository](https://github.com/aws/aws-iot-device-sdk-embedded-C/). 116 | * 117 | * Default value: Info logging is turned off, and no code is generated for calls 118 | * to the macro in the SNTP library on compilation. 119 | */ 120 | #ifndef LogInfo 121 | #define LogInfo( message ) 122 | #endif 123 | 124 | /** 125 | * @brief Macro that is called in the SNTP library for logging "Debug" level 126 | * messages. 127 | * 128 | * To enable debug level logging from SNTP library, this macro should be mapped to the 129 | * application-specific logging implementation that supports debug logging. 130 | * 131 | * @note This logging macro is called in the SNTP library with parameters wrapped in 132 | * double parentheses to be ISO C89/C90 standard compliant. For a reference 133 | * POSIX implementation of the logging macros, refer to core_sntp_config.h files, and the 134 | * logging-stack in demos folder of the 135 | * [AWS IoT Embedded C SDK repository](https://github.com/aws/aws-iot-device-sdk-embedded-C/). 136 | * 137 | * Default value: Debug logging is turned off, and no code is generated for calls 138 | * to the macro in the SNTP library on compilation. 139 | */ 140 | #ifndef LogDebug 141 | #define LogDebug( message ) 142 | #endif 143 | 144 | #endif /* ifndef CORE_SNTP_CONFIG_DEFAULTS_H_ */ 145 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.13.0 ) 2 | project( "coreSNTP tests" 3 | VERSION 1.3.1 4 | LANGUAGES C ) 5 | 6 | # Allow the project to be organized into folders. 7 | set_property( GLOBAL PROPERTY USE_FOLDERS ON ) 8 | 9 | # Use C90. 10 | set( CMAKE_C_STANDARD 90 ) 11 | set( CMAKE_C_STANDARD_REQUIRED ON ) 12 | 13 | # If no configuration is defined, turn everything on. 14 | if( NOT DEFINED COV_ANALYSIS AND NOT DEFINED UNITTEST AND NOT DEFINED BUILD_CODE_EXAMPLE ) 15 | set( COV_ANALYSIS ON ) 16 | set( UNITTEST ON ) 17 | set( BUILD_CODE_EXAMPLE ON ) 18 | endif() 19 | 20 | # Do not allow in-source build. 21 | if( ${PROJECT_SOURCE_DIR} STREQUAL ${PROJECT_BINARY_DIR} ) 22 | message( FATAL_ERROR "In-source build is not allowed. Please build in a separate directory, such as ${PROJECT_SOURCE_DIR}/build." ) 23 | endif() 24 | 25 | # Set global path variables. 26 | get_filename_component(__MODULE_ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE) 27 | set( MODULE_ROOT_DIR ${__MODULE_ROOT_DIR} CACHE INTERNAL "coreSNTP source root." ) 28 | set( UNIT_TEST_DIR ${MODULE_ROOT_DIR}/test/unit-test CACHE INTERNAL "coreSNTP unit test directory." ) 29 | set( CMOCK_DIR ${UNIT_TEST_DIR}/CMock CACHE INTERNAL "Unity library source directory." ) 30 | 31 | # Configure options to always show in CMake GUI. 32 | option( BUILD_CLONE_SUBMODULES 33 | "Set this to ON to automatically clone any required Git submodules. When OFF, submodules must be manually cloned." 34 | OFF ) 35 | 36 | # Set output directories. 37 | set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin ) 38 | set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib ) 39 | set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib ) 40 | 41 | # Include filepaths for source and include. 42 | include( ${MODULE_ROOT_DIR}/coreSntpFilePaths.cmake ) 43 | 44 | # ================================ Coverity Analysis Configuration ================================= 45 | 46 | if( COV_ANALYSIS ) 47 | 48 | # Target for Coverity analysis that builds the library. 49 | add_library( coverity_analysis 50 | ${CORE_SNTP_SOURCES} ) 51 | 52 | # Add coreSNTP library public include path. 53 | target_include_directories( coverity_analysis 54 | PUBLIC 55 | ${CORE_SNTP_INCLUDE_PUBLIC_DIRS} ) 56 | 57 | # Build SNTP library target without custom config dependency. 58 | target_compile_definitions( coverity_analysis PUBLIC SNTP_DO_NOT_USE_CUSTOM_CONFIG=1 ) 59 | 60 | # Build without debug enabled when performing static analysis 61 | target_compile_options(coverity_analysis PUBLIC -DNDEBUG ) 62 | endif() 63 | 64 | # ==================================== Code Example Build ==================================== 65 | 66 | if( BUILD_CODE_EXAMPLE ) 67 | # Target for Coverity analysis that builds the library. 68 | add_executable( code_example_posix 69 | ${CORE_SNTP_SOURCES} 70 | ${MODULE_ROOT_DIR}/docs/doxygen/code_examples/example_sntp_client_posix.c ) 71 | 72 | target_include_directories( code_example_posix 73 | PUBLIC 74 | ${CORE_SNTP_INCLUDE_PUBLIC_DIRS} ) 75 | 76 | # Build SNTP library target without custom config dependency. 77 | target_compile_definitions( code_example_posix PUBLIC SNTP_DO_NOT_USE_CUSTOM_CONFIG=1 ) 78 | 79 | # Build without debug enabled when performing static analysis 80 | target_compile_options( code_example_posix PUBLIC -DNDEBUG ) 81 | endif() 82 | 83 | # ==================================== Unit Test Configuration ==================================== 84 | 85 | if( UNITTEST ) 86 | # Include CMock build configuration. 87 | include( unit-test/cmock_build.cmake ) 88 | 89 | # Check if the CMock source directory exists, and if not present, clone the submodule 90 | # if BUILD_CLONE_SUBMODULES configuration is enabled. 91 | if( NOT EXISTS ${CMOCK_DIR}/src ) 92 | # Attempt to clone CMock. 93 | clone_cmock() 94 | endif() 95 | 96 | # Add unit test and coverage configuration. 97 | 98 | # Use CTest utility for managing test runs. This has to be added BEFORE 99 | # defining test targets with add_test() 100 | enable_testing() 101 | 102 | # Add build targets for CMock, required for unit testing. 103 | add_cmock_targets() 104 | 105 | # Add function to enable CMock/Unity based tests and coverage. 106 | include( ${MODULE_ROOT_DIR}/tools/cmock/create_test.cmake ) 107 | 108 | # Include build configuration for unit tests. 109 | add_subdirectory( unit-test ) 110 | endif() 111 | 112 | # ==================================== Coverage Analysis configuration ============================ 113 | 114 | # Add a target for running coverage on tests. 115 | add_custom_target( coverage 116 | COMMAND ${CMAKE_COMMAND} -DCMOCK_DIR=${CMOCK_DIR} 117 | -P ${MODULE_ROOT_DIR}/tools/cmock/coverage.cmake 118 | DEPENDS cmock core_sntp_client_utest core_sntp_serializer_utest 119 | WORKING_DIRECTORY ${CMAKE_BINARY_DIR} 120 | ) 121 | -------------------------------------------------------------------------------- /test/cbmc/.gitignore: -------------------------------------------------------------------------------- 1 | # Emitted when running CBMC proofs 2 | proofs/**/logs 3 | proofs/**/gotos 4 | proofs/**/report 5 | proofs/**/html 6 | proofs/output 7 | 8 | # Emitted by CBMC Viewer 9 | TAGS-* 10 | 11 | # Emitted by Arpa 12 | arpa_cmake/ 13 | arpa-validation-logs/ 14 | Makefile.arpa 15 | 16 | # Emitted by litani 17 | .ninja_deps 18 | .ninja_log 19 | .litani_cache_dir 20 | 21 | # These files should be overwritten whenever prepare.py runs 22 | cbmc-batch.yaml 23 | 24 | __pycache__/ 25 | -------------------------------------------------------------------------------- /test/cbmc/include/README.md: -------------------------------------------------------------------------------- 1 | CBMC proof include files 2 | ======================== 3 | 4 | This directory contains include files written for CBMC proof. It is 5 | common to write some code to model aspects of the system under test, 6 | and the header files for this code go here. 7 | -------------------------------------------------------------------------------- /test/cbmc/include/core_sntp_cbmc_state.h: -------------------------------------------------------------------------------- 1 | /* 2 | * coreSNTP v1.3.1 3 | * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * SPDX-License-Identifier: MIT 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | * this software and associated documentation files (the "Software"), to deal in 9 | * the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 | * the Software, and to permit persons to whom the Software is furnished to do so, 12 | * subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 19 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 21 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @file core_sntp_cbmc_state.h 27 | * @brief Allocation and assumption utilities for the SNTP library CBMC proofs. 28 | */ 29 | #ifndef CORE_SNTP_CBMC_STATE_H_ 30 | #define CORE_SNTP_CBMC_STATE_H_ 31 | 32 | #include "core_sntp_client.h" 33 | 34 | /* Application defined Network context. */ 35 | struct NetworkContext 36 | { 37 | void * networkContext; 38 | }; 39 | 40 | /* Application defined authentication context. */ 41 | struct SntpAuthContext 42 | { 43 | void * authContext; 44 | }; 45 | 46 | /** 47 | * @brief Allocate a #SntpContext_t object. 48 | * 49 | * @return NULL or allocated #SntpContext_t memory. 50 | */ 51 | SntpContext_t * unconstrainedCoreSntpContext(); 52 | 53 | #endif /* ifndef CORE_SNTP_CBMC_STATE_H_ */ 54 | -------------------------------------------------------------------------------- /test/cbmc/include/core_sntp_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * coreSNTP v1.3.1 3 | * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * SPDX-License-Identifier: MIT 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | * this software and associated documentation files (the "Software"), to deal in 9 | * the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 | * the Software, and to permit persons to whom the Software is furnished to do so, 12 | * subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 19 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 21 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @file core_sntp_config_defaults.h 27 | * @brief This file represents the default values for the configuration macros 28 | * of the coreSNTP library. 29 | * 30 | * @note This file SHOULD NOT be modified. If custom values are needed for 31 | * any configuration macro, a core_sntp_config.h file should be provided to 32 | * the SNTP library to override the default values defined in this file. 33 | * To build the library with the core_sntp_config.h file, make sure to 34 | * not set the SNTP_DO_NOT_USE_CUSTOM_CONFIG preprocessor macro. 35 | */ 36 | 37 | #ifndef CORE_SNTP_CONFIG_DEFAULTS_H_ 38 | #define CORE_SNTP_CONFIG_DEFAULTS_H_ 39 | 40 | /* The macro definition for SNTP_DO_NOT_USE_CUSTOM_CONFIG is for Doxygen 41 | * documentation only. */ 42 | 43 | /** 44 | * @brief Define this macro to build the SNTP library without the custom config 45 | * file core_sntp_config.h. 46 | * 47 | * Without the custom config, the SNTP library builds with 48 | * default values of config macros defined in core_sntp_config_defaults.h file. 49 | * 50 | * If a custom config is provided, then SNTP_DO_NOT_USE_CUSTOM_CONFIG should not 51 | * be defined. 52 | */ 53 | #ifdef DOXYGEN 54 | #define SNTP_DO_NOT_USE_CUSTOM_CONFIG 55 | #endif 56 | 57 | /** 58 | * @brief The maximum duration between non-empty network reads while 59 | * receiving an SNTP packet via the #Sntp_ReceiveTimeResponse API function. 60 | * 61 | * When an incoming SNTP packet is detected, the transport receive function 62 | * may be called multiple times until all of the expected number of bytes of the 63 | * packet are received. This timeout represents the maximum polling duration that 64 | * is allowed without any data reception from the network for the incoming packet. 65 | * 66 | * If the timeout expires, the #Sntp_ReceiveTimeResponse function will return 67 | * #SntpErrorNetworkFailure. 68 | * 69 | * Possible values: Any positive 16 bit integer. Recommended to use a 70 | * small timeout value.
71 | * Default value: `10` 72 | */ 73 | #ifndef SNTP_RECV_POLLING_TIMEOUT_MS 74 | #define SNTP_RECV_POLLING_TIMEOUT_MS ( 10U ) 75 | #endif 76 | 77 | /** 78 | * @brief The maximum duration between non-empty network transmissions while 79 | * sending an SNTP packet via the #Sntp_SendTimeRequest API function. 80 | * 81 | * When sending an SNTP packet, the transport send function may be called multiple 82 | * times until all of the required number of bytes are sent. 83 | * This timeout represents the maximum duration that is allowed for no data 84 | * transmission over the network through the transport send function. 85 | * 86 | * If the timeout expires, the #Sntp_SendTimeRequest function will return 87 | * #SntpErrorNetworkFailure. 88 | * 89 | * Possible values: Any positive 16 bit integer. Recommended to use a small 90 | * timeout value.
91 | * Default value: `10` 92 | */ 93 | #ifndef SNTP_SEND_RETRY_TIMEOUT_MS 94 | #define SNTP_SEND_RETRY_TIMEOUT_MS ( 10U ) 95 | #endif 96 | 97 | /** 98 | * @brief Macro that is called in the SNTP library for logging "Error" level 99 | * messages. 100 | * 101 | * To enable error level logging in the SNTP library, this macro should be mapped to the 102 | * application-specific logging implementation that supports error logging. 103 | * 104 | * @note This logging macro is called in the SNTP library with parameters wrapped in 105 | * double parentheses to be ISO C89/C90 standard compliant. For a reference 106 | * POSIX implementation of the logging macros, refer to core_sntp_config.h files, and the 107 | * logging-stack in demos folder of the 108 | * [AWS IoT Embedded C SDK repository](https://github.com/aws/aws-iot-device-sdk-embedded-C). 109 | * 110 | * Default value: Error logging is turned off, and no code is generated for calls 111 | * to the macro in the SNTP library on compilation. 112 | */ 113 | #ifndef LogError 114 | #define LogError( message ) 115 | #endif 116 | 117 | /** 118 | * @brief Macro that is called in the SNTP library for logging "Warning" level 119 | * messages. 120 | * 121 | * To enable warning level logging in the SNTP library, this macro should be mapped to the 122 | * application-specific logging implementation that supports warning logging. 123 | * 124 | * @note This logging macro is called in the SNTP library with parameters wrapped in 125 | * double parentheses to be ISO C89/C90 standard compliant. For a reference 126 | * POSIX implementation of the logging macros, refer to core_sntp_config.h files, and the 127 | * logging-stack in demos folder of the 128 | * [AWS IoT Embedded C SDK repository](https://github.com/aws/aws-iot-device-sdk-embedded-C/). 129 | * 130 | * Default value: Warning logs are turned off, and no code is generated for calls 131 | * to the macro in the SNTP library on compilation. 132 | */ 133 | #ifndef LogWarn 134 | #define LogWarn( message ) 135 | #endif 136 | 137 | /** 138 | * @brief Macro that is called in the SNTP library for logging "Info" level 139 | * messages. 140 | * 141 | * To enable info level logging in the SNTP library, this macro should be mapped to the 142 | * application-specific logging implementation that supports info logging. 143 | * 144 | * @note This logging macro is called in the SNTP library with parameters wrapped in 145 | * double parentheses to be ISO C89/C90 standard compliant. For a reference 146 | * POSIX implementation of the logging macros, refer to core_sntp_config.h files, and the 147 | * logging-stack in demos folder of the 148 | * [AWS IoT Embedded C SDK repository](https://github.com/aws/aws-iot-device-sdk-embedded-C/). 149 | * 150 | * Default value: Info logging is turned off, and no code is generated for calls 151 | * to the macro in the SNTP library on compilation. 152 | */ 153 | #ifndef LogInfo 154 | #define LogInfo( message ) 155 | #endif 156 | 157 | /** 158 | * @brief Macro that is called in the SNTP library for logging "Debug" level 159 | * messages. 160 | * 161 | * To enable debug level logging from SNTP library, this macro should be mapped to the 162 | * application-specific logging implementation that supports debug logging. 163 | * 164 | * @note This logging macro is called in the SNTP library with parameters wrapped in 165 | * double parentheses to be ISO C89/C90 standard compliant. For a reference 166 | * POSIX implementation of the logging macros, refer to core_sntp_config.h files, and the 167 | * logging-stack in demos folder of the 168 | * [AWS IoT Embedded C SDK repository](https://github.com/aws/aws-iot-device-sdk-embedded-C/). 169 | * 170 | * Default value: Debug logging is turned off, and no code is generated for calls 171 | * to the macro in the SNTP library on compilation. 172 | */ 173 | #ifndef LogDebug 174 | #define LogDebug( message ) 175 | #endif 176 | 177 | #endif /* ifndef CORE_SNTP_CONFIG_DEFAULTS_H_ */ 178 | -------------------------------------------------------------------------------- /test/cbmc/include/core_sntp_stubs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * coreSNTP v1.3.1 3 | * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * SPDX-License-Identifier: MIT 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | * this software and associated documentation files (the "Software"), to deal in 9 | * the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 | * the Software, and to permit persons to whom the Software is furnished to do so, 12 | * subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 19 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 21 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @file core_sntp_stubs_stubs.h 27 | * @brief Stubs definitions of UDP transport interface and authentication interface of coreSNTP API. 28 | */ 29 | #ifndef CORE_SNTP_CBMC_STUBS_H_ 30 | #define CORE_SNTP_CBMC_STUBS_H_ 31 | 32 | #include 33 | #include 34 | #include 35 | #include "core_sntp_client.h" 36 | 37 | /** 38 | * @brief Application defined network interface send function. 39 | * 40 | * @param[in] pNetworkContext Application defined network interface context. 41 | * @param[in] serverAddr Server address to which application sends data. 42 | * @param[in] serverPort Server port to which application sends data. 43 | * @param[out] pBuffer SNTP network send buffer. 44 | * @param[in] bytesToSend Number of bytes to send over the network. 45 | * 46 | * @return Any value from INT32_MIN to INT32_MAX. 47 | */ 48 | int32_t NetworkInterfaceSendStub( NetworkContext_t * pNetworkContext, 49 | uint32_t serverAddr, 50 | uint16_t serverPort, 51 | const void * pBuffer, 52 | uint16_t bytesToSend ); 53 | 54 | /** 55 | * @brief Application defined network interface receive function. 56 | * 57 | * @param[in] pNetworkContext Application defined network interface context. 58 | * @param[in] serverAddr Server address from which application receives data. 59 | * @param[in] serverPort Server port from which application receives data. 60 | * @param[out] pBuffer SNTP network receive buffer. 61 | * @param[in] bytesToRecv SNTP requested bytes. 62 | * 63 | * @return Any value from INT32_MIN to INT32_MAX. 64 | */ 65 | int32_t NetworkInterfaceReceiveStub( NetworkContext_t * pNetworkContext, 66 | uint32_t serverAddr, 67 | uint16_t serverPort, 68 | void * pBuffer, 69 | uint16_t bytesToRecv ); 70 | 71 | /** 72 | * @brief Application defined function to generate and append 73 | * authentication code in an SNTP request buffer for the SNTP client to be 74 | * authenticated by the time server, if a security mechanism is used. 75 | * 76 | * @param[in] pContext Application defined authentication interface context. 77 | * @param[in] pTimeServer The time server being used to request time from. 78 | * This parameter is useful to choose the security mechanism when multiple time 79 | * servers are configured in the library, and they require different security 80 | * mechanisms or authentication credentials to use. 81 | * @param[in] pBuffer SNTP request buffer. 82 | * @param[in] bufferSize The maximum amount of data that can be held by the buffer. 83 | * @param[out] pAuthCodeSize This should be filled with size of the authentication 84 | * data appended to the SNTP request buffer, @p pBuffer. 85 | * 86 | * @return The function SHOULD return one of the following integer codes: 87 | * - #SntpSuccess when the authentication data is successfully appended to @p pBuffer. 88 | * - #SntpErrorBufferTooSmall when the user-supplied buffer (to the SntpContext_t through 89 | * @ref Sntp_Init) is not large enough to hold authentication data. 90 | */ 91 | SntpStatus_t GenerateClientAuthStub( SntpAuthContext_t * pContext, 92 | const SntpServerInfo_t * pTimeServer, 93 | void * pBuffer, 94 | size_t bufferSize, 95 | uint16_t * pAuthCodeSize ); 96 | 97 | /** 98 | * @brief Application defined function to authenticate server by validating 99 | * the authentication code present in its SNTP response to a time request, if 100 | * a security mechanism is supported by the server. 101 | * 102 | * @param[in,out] pContext The application defined NetworkContext_t which 103 | * is opaque to the coreSNTP library. 104 | * @param[in] pTimeServer The time server that has to be authenticated from its 105 | * SNTP response. 106 | * @param[in] pResponseData The SNTP response from the server that contains the 107 | * authentication code after the first #SNTP_PACKET_BASE_SIZE bytes. 108 | * @param[in] responseSize The total size of the response from the server. 109 | * 110 | * @return The function ALWAYS returns #SntpSuccess 111 | */ 112 | SntpStatus_t ValidateServerAuthStub( SntpAuthContext_t * pContext, 113 | const SntpServerInfo_t * pTimeServer, 114 | const void * pResponseData, 115 | uint16_t responseSize ); 116 | 117 | /** 118 | * @brief Application defined function to resolve time server domain-name 119 | * to an IPv4 address. 120 | * 121 | * @param[in] pTimeServer The time-server whose IPv4 address is to be resolved. 122 | * @param[out] pIpV4Addr This should be filled with the resolved IPv4 address. 123 | * of @p pTimeServer. 124 | * 125 | * @return `true` if DNS resolution is successful; otherwise `false` to represent 126 | * failure. 127 | */ 128 | bool ResolveDnsFuncStub( const SntpServerInfo_t * pServerAddr, 129 | uint32_t * pIpV4Addr ); 130 | 131 | /** 132 | * @brief Application defined function to obtain the current system time 133 | * in SNTP timestamp format. 134 | * 135 | * @param[out] pCurrentTime This should be filled with the current system time 136 | * in SNTP timestamp format. 137 | */ 138 | void GetTimeFuncStub( SntpTimestamp_t * pCurrentTime ); 139 | 140 | /** 141 | * @brief Application defined function to update the system clock time 142 | * so that it is synchronized the time server used for getting current time. 143 | * 144 | * @param[in] pTimeServer The time server used to request time. 145 | * @param[in] pServerTime The current time returned by the @p pTimeServer. 146 | * @param[in] clockOffSetMs The calculated clock offset of the system relative 147 | * to the server time. 148 | * @param[in] leapSecondInfo Information about whether there is about an upcoming 149 | * leap second adjustment. 150 | */ 151 | void SetTimeFuncStub( const SntpServerInfo_t * pTimeServer, 152 | const SntpTimestamp_t * pServerTime, 153 | int64_t clockOffsetMs, 154 | SntpLeapSecondInfo_t leapSecondInfo ); 155 | 156 | #endif /* ifndef CORE_SNTP_CBMC_STUBS_H_ */ 157 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Makefile-project-defines: -------------------------------------------------------------------------------- 1 | # -*- mode: makefile -*- 2 | # The first line sets the emacs major mode to Makefile 3 | 4 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 5 | # SPDX-License-Identifier: MIT-0 6 | 7 | ################################################################ 8 | # Use this file to give project-specific definitions of the command 9 | # line arguments to pass to CBMC tools like goto-cc to build the goto 10 | # binaries and cbmc to do the property and coverage checking. 11 | # 12 | # Use this file to override most default definitions of variables in 13 | # Makefile.common. 14 | ################################################################ 15 | 16 | # Flags to pass to goto-cc for compilation (typically those passed to gcc -c) 17 | COMPILE_FLAGS += -fPIC 18 | COMPILE_FLAGS += -std=gnu90 19 | 20 | # Flags to pass to goto-cc for linking (typically those passed to gcc) 21 | # LINK_FLAGS = 22 | 23 | # Preprocessor include paths -I... 24 | # Consider adding 25 | # INCLUDES += -I$(CBMC_ROOT)/include 26 | # You will want to decide what order that comes in relative to the other 27 | # include directories in your project. 28 | # 29 | INCLUDES += -I$(SRCDIR)/test/cbmc/include 30 | INCLUDES += -I$(SRCDIR)/source/include 31 | 32 | # Preprocessor definitions -D... 33 | # DEFINES = 34 | 35 | # Path to arpa executable 36 | # ARPA = 37 | 38 | # Flags to pass to cmake for building the project 39 | # ARPA_CMAKE_FLAGS = 40 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Makefile-project-targets: -------------------------------------------------------------------------------- 1 | # -*- mode: makefile -*- 2 | # The first line sets the emacs major mode to Makefile 3 | 4 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 5 | # SPDX-License-Identifier: MIT-0 6 | 7 | ################################################################ 8 | # Use this file to give project-specific targets, including targets 9 | # that may depend on targets defined in Makefile.common. 10 | ################################################################ 11 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Makefile-project-testing: -------------------------------------------------------------------------------- 1 | # -*- mode: makefile -*- 2 | # The first line sets the emacs major mode to Makefile 3 | 4 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 5 | # SPDX-License-Identifier: MIT-0 6 | 7 | ################################################################ 8 | # Use this file to define project-specific targets and definitions for 9 | # unit testing or continuous integration that may depend on targets 10 | # defined in Makefile.common 11 | ################################################################ 12 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Makefile-template-defines: -------------------------------------------------------------------------------- 1 | PROOF_ROOT ?= $(abspath .) 2 | 3 | # Absolute path to the root of the source tree. 4 | # 5 | SRCDIR ?= $(abspath $(PROOF_ROOT)/../../..) 6 | 7 | 8 | # Absolute path to the litani script. 9 | # 10 | LITANI ?= litani 11 | 12 | 13 | # Name of this proof project, displayed in proof reports. For example, 14 | # "s2n" or "Amazon FreeRTOS". For projects with multiple proof roots, 15 | # this may be overridden on the command-line to Make, for example 16 | # 17 | # make PROJECT_NAME="FreeRTOS MQTT" report 18 | # 19 | PROJECT_NAME = "coreSNTP" 20 | 21 | -------------------------------------------------------------------------------- /test/cbmc/proofs/README.md: -------------------------------------------------------------------------------- 1 | CBMC proofs 2 | =========== 3 | 4 | This directory contains the CBMC proofs. Each proof is in its own 5 | directory. 6 | 7 | This directory includes four Makefiles. 8 | 9 | One Makefile describes the basic workflow for building and running proofs: 10 | 11 | * Makefile.common: 12 | * make: builds the goto binary, does the cbmc property checking 13 | and coverage checking, and builds the final report. 14 | * make goto: builds the goto binary 15 | * make result: does cbmc property checking 16 | * make coverage: does cbmc coverage checking 17 | * make report: builds the final report 18 | 19 | Three included Makefiles describe project-specific settings and can override 20 | definitions in Makefile.common: 21 | 22 | * Makefile-project-defines: definitions like compiler flags 23 | required to build the goto binaries, and definitions to override 24 | definitions in Makefile.common. 25 | * Makefile-project-targets: other make targets needed for the project 26 | * Makefile-project-testing: other definitions and targets needed for 27 | unit testing or continuous integration. 28 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_CalculatePollInterval/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: MIT-0 3 | 4 | HARNESS_ENTRY = harness 5 | HARNESS_FILE = Sntp_CalculatePollInterval_harness 6 | 7 | # This should be a unique identifier for this proof, and will appear on the 8 | # Litani dashboard. It can be human-readable and contain spaces if you wish. 9 | PROOF_UID = Sntp_CalculatePollInterval 10 | 11 | # Bound for loop unwinding for loop in Sntp_CalculatePollInterval function. Unwinding 12 | # the loop 33 times will be enough as the unsigned 32 integer can take value upto 2^32. 13 | MAX_BOUND_FOR_LOOP=33 14 | 15 | DEFINES += 16 | INCLUDES += 17 | 18 | REMOVE_FUNCTION_BODY += 19 | UNWINDSET += Sntp_CalculatePollInterval.0:$(MAX_BOUND_FOR_LOOP) 20 | 21 | PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE).c 22 | PROJECT_SOURCES += $(SRCDIR)/source/core_sntp_serializer.c 23 | 24 | include ../Makefile.common 25 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_CalculatePollInterval/README.md: -------------------------------------------------------------------------------- 1 | Sntp_CalculatePollInterval proof 2 | ============== 3 | 4 | This directory contains a memory safety proof for Sntp_CalculatePollInterval. 5 | 6 | The proof runs within 3 minutes on a t2.2xlarge. It provides complete coverage of: 7 | * Sntp_CalculatePollInterval() 8 | 9 | To run the proof. 10 | ------------- 11 | 12 | * Add `cbmc`, `goto-cc`, `goto-instrument`, `goto-analyzer`, and `cbmc-viewer` 13 | to your path. 14 | * Run `make`. 15 | * Open html/index.html in a web browser. 16 | 17 | To use [`arpa`](https://awslabs.github.io/aws-proof-build-assistant) to simplify writing Makefiles. 18 | ------------- 19 | 20 | * Run `make arpa` to generate a Makefile.arpa that contains relevant build information for the proof. 21 | * Use Makefile.arpa as the starting point for your proof Makefile by: 22 | 1. Modifying Makefile.arpa (if required). 23 | 2. Including Makefile.arpa into the existing proof Makefile (add `sinclude Makefile.arpa` at the bottom of the Makefile, right before `include ../Makefile.common`). 24 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_CalculatePollInterval/Sntp_CalculatePollInterval_harness.c: -------------------------------------------------------------------------------- 1 | /* 2 | * coreSNTP v1.3.1 3 | * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * SPDX-License-Identifier: MIT 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | * this software and associated documentation files (the "Software"), to deal in 9 | * the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 | * the Software, and to permit persons to whom the Software is furnished to do so, 12 | * subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 19 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 21 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @file Sntp_CalculatePollInterval_harness.c 27 | * @brief Implements the proof harness for Sntp_CalculatePollInterval function. 28 | */ 29 | 30 | #include "core_sntp_serializer.h" 31 | 32 | void harness() 33 | { 34 | uint16_t clockFreqTolerance; 35 | uint16_t desiredAccuracy; 36 | uint32_t * pPollInterval; 37 | SntpStatus_t sntpStatus; 38 | 39 | pPollInterval = malloc( sizeof( uint32_t ) ); 40 | sntpStatus = Sntp_CalculatePollInterval( clockFreqTolerance, desiredAccuracy, pPollInterval ); 41 | 42 | __CPROVER_assert( ( sntpStatus == SntpErrorBadParameter || sntpStatus == SntpSuccess || sntpStatus == SntpZeroPollInterval ), "The return value is not a valid SNTP status." ); 43 | } 44 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_CalculatePollInterval/cbmc-proof.txt: -------------------------------------------------------------------------------- 1 | # This file marks this directory as containing a CBMC proof. 2 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_CalculatePollInterval/cbmc-viewer.json: -------------------------------------------------------------------------------- 1 | { "expected-missing-functions": 2 | [ 3 | 4 | ], 5 | "proof-name": "Sntp_CalculatePollInterval", 6 | "proof-root": "test/cbmc/proofs" 7 | } 8 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_ConvertToUnixTime/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: MIT-0 3 | 4 | HARNESS_ENTRY = harness 5 | HARNESS_FILE = Sntp_ConvertToUnixTime_harness 6 | 7 | # This should be a unique identifier for this proof, and will appear on the 8 | # Litani dashboard. It can be human-readable and contain spaces if you wish. 9 | PROOF_UID = Sntp_ConvertToUnixTime 10 | 11 | DEFINES += 12 | INCLUDES += 13 | 14 | REMOVE_FUNCTION_BODY += 15 | UNWINDSET += 16 | 17 | PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE).c 18 | PROJECT_SOURCES += $(SRCDIR)/source/core_sntp_serializer.c 19 | 20 | include ../Makefile.common 21 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_ConvertToUnixTime/README.md: -------------------------------------------------------------------------------- 1 | Sntp_ConvertToUnixTime proof 2 | ============== 3 | 4 | This directory contains a memory safety proof for Sntp_ConvertToUnixTime. 5 | 6 | The proof runs within 3 minutes on a t2.2xlarge. It provides complete coverage of: 7 | * Sntp_ConvertToUnixTime() 8 | 9 | To run the proof. 10 | ------------- 11 | 12 | * Add `cbmc`, `goto-cc`, `goto-instrument`, `goto-analyzer`, and `cbmc-viewer` 13 | to your path. 14 | * Run `make`. 15 | * Open html/index.html in a web browser. 16 | 17 | To use [`arpa`](https://awslabs.github.io/aws-proof-build-assistant) to simplify writing Makefiles. 18 | ------------- 19 | 20 | * Run `make arpa` to generate a Makefile.arpa that contains relevant build information for the proof. 21 | * Use Makefile.arpa as the starting point for your proof Makefile by: 22 | 1. Modifying Makefile.arpa (if required). 23 | 2. Including Makefile.arpa into the existing proof Makefile (add `sinclude Makefile.arpa` at the bottom of the Makefile, right before `include ../Makefile.common`). 24 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_ConvertToUnixTime/Sntp_ConvertToUnixTime_harness.c: -------------------------------------------------------------------------------- 1 | /* 2 | * coreSNTP v1.3.1 3 | * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * SPDX-License-Identifier: MIT 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | * this software and associated documentation files (the "Software"), to deal in 9 | * the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 | * the Software, and to permit persons to whom the Software is furnished to do so, 12 | * subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 19 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 21 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @file Sntp_ConvertToUnixTime_harness.c 27 | * @brief Implements the proof harness for Sntp_ConvertToUnixTime function. 28 | */ 29 | 30 | #include "core_sntp_serializer.h" 31 | 32 | void harness() 33 | { 34 | SntpTimestamp_t * pSntpTime; 35 | uint32_t * pUnixTimeSecs; 36 | uint32_t * pUnixTimeMicrosecs; 37 | SntpStatus_t sntpStatus; 38 | 39 | pSntpTime = malloc( sizeof( SntpTimestamp_t ) ); 40 | pUnixTimeSecs = malloc( sizeof( uint32_t ) ); 41 | pUnixTimeMicrosecs = malloc( sizeof( uint32_t ) ); 42 | 43 | sntpStatus = Sntp_ConvertToUnixTime( pSntpTime, pUnixTimeSecs, pUnixTimeMicrosecs ); 44 | 45 | __CPROVER_assert( ( sntpStatus == SntpErrorBadParameter || sntpStatus == SntpSuccess ), "The return value is not a valid SNTP Status" ); 46 | } 47 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_ConvertToUnixTime/cbmc-proof.txt: -------------------------------------------------------------------------------- 1 | # This file marks this directory as containing a CBMC proof. 2 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_ConvertToUnixTime/cbmc-viewer.json: -------------------------------------------------------------------------------- 1 | { "expected-missing-functions": 2 | [ 3 | 4 | ], 5 | "proof-name": "Sntp_ConvertToUnixTime", 6 | "proof-root": "test/cbmc/proofs" 7 | } 8 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_DeserializeResponse/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: MIT-0 3 | 4 | HARNESS_ENTRY = harness 5 | HARNESS_FILE = Sntp_DeserializeResponse_harness 6 | 7 | # This should be a unique identifier for this proof, and will appear on the 8 | # Litani dashboard. It can be human-readable and contain spaces if you wish. 9 | PROOF_UID = Sntp_DeserializeResponse 10 | 11 | DEFINES += 12 | INCLUDES += 13 | 14 | REMOVE_FUNCTION_BODY += 15 | UNWINDSET += 16 | 17 | PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE).c 18 | PROJECT_SOURCES += $(SRCDIR)/source/core_sntp_serializer.c 19 | 20 | include ../Makefile.common 21 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_DeserializeResponse/README.md: -------------------------------------------------------------------------------- 1 | Sntp_DeserializeResponse proof 2 | ============== 3 | 4 | This directory contains a memory safety proof for Sntp_DeserializeResponse. 5 | 6 | To run the proof. 7 | ------------- 8 | 9 | * Add `cbmc`, `goto-cc`, `goto-instrument`, `goto-analyzer`, and `cbmc-viewer` 10 | to your path. 11 | * Run `make`. 12 | * Open html/index.html in a web browser. 13 | 14 | To use [`arpa`](https://awslabs.github.io/aws-proof-build-assistant) to simplify writing Makefiles. 15 | ------------- 16 | 17 | * Run `make arpa` to generate a Makefile.arpa that contains relevant build information for the proof. 18 | * Use Makefile.arpa as the starting point for your proof Makefile by: 19 | 1. Modifying Makefile.arpa (if required). 20 | 2. Including Makefile.arpa into the existing proof Makefile (add `sinclude Makefile.arpa` at the bottom of the Makefile, right before `include ../Makefile.common`). 21 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_DeserializeResponse/Sntp_DeserializeResponse_harness.c: -------------------------------------------------------------------------------- 1 | /* 2 | * coreSNTP v1.3.1 3 | * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * SPDX-License-Identifier: MIT 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | * this software and associated documentation files (the "Software"), to deal in 9 | * the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 | * the Software, and to permit persons to whom the Software is furnished to do so, 12 | * subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 19 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 21 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @file Sntp_DeserializeResponse_harness.c 27 | * @brief Implements the proof harness for Sntp_DeserializeResponse function. 28 | */ 29 | 30 | #include 31 | #include "core_sntp_serializer.h" 32 | 33 | void harness() 34 | { 35 | SntpTimestamp_t * pRequestTime; 36 | SntpTimestamp_t * pResponseRxTime; 37 | void * pResponseBuffer; 38 | size_t bufferSize; 39 | SntpResponseData_t * pParsedResponse; 40 | SntpStatus_t sntpStatus; 41 | 42 | __CPROVER_assume( bufferSize < CBMC_MAX_OBJECT_SIZE ); 43 | 44 | pRequestTime = malloc( sizeof( SntpTimestamp_t ) ); 45 | pResponseRxTime = malloc( sizeof( SntpTimestamp_t ) ); 46 | pResponseBuffer = malloc( bufferSize ); 47 | pParsedResponse = malloc( sizeof( SntpResponseData_t ) ); 48 | 49 | sntpStatus = Sntp_DeserializeResponse( pRequestTime, pResponseRxTime, pResponseBuffer, bufferSize, pParsedResponse ); 50 | 51 | __CPROVER_assert( ( sntpStatus == SntpErrorBadParameter ) || ( sntpStatus == SntpErrorBufferTooSmall ) || 52 | ( sntpStatus == SntpInvalidResponse ) || ( sntpStatus == SntpSuccess ) || ( sntpStatus == SntpRejectedResponseChangeServer ) || 53 | ( sntpStatus == SntpRejectedResponseRetryWithBackoff ) || ( sntpStatus == SntpRejectedResponseOtherCode ), "This is a valid sntp return status" ); 54 | } 55 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_DeserializeResponse/cbmc-proof.txt: -------------------------------------------------------------------------------- 1 | # This file marks this directory as containing a CBMC proof. 2 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_DeserializeResponse/cbmc-viewer.json: -------------------------------------------------------------------------------- 1 | { "expected-missing-functions": 2 | [ 3 | 4 | ], 5 | "proof-name": "Sntp_DeserializeResponse", 6 | "proof-root": "test/cbmc/proofs" 7 | } 8 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_Init/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: MIT-0 3 | 4 | HARNESS_ENTRY = harness 5 | HARNESS_FILE = Sntp_Init_harness 6 | 7 | # This should be a unique identifier for this proof, and will appear on the 8 | # Litani dashboard. It can be human-readable and contain spaces if you wish. 9 | PROOF_UID = Sntp_Init 10 | 11 | DEFINES += 12 | INCLUDES += 13 | 14 | REMOVE_FUNCTION_BODY += 15 | UNWINDSET += 16 | 17 | PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE).c 18 | PROJECT_SOURCES += $(SRCDIR)/source/core_sntp_client.c 19 | 20 | include ../Makefile.common 21 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_Init/README.md: -------------------------------------------------------------------------------- 1 | Sntp_Init proof 2 | ============== 3 | 4 | This directory contains a memory safety proof for Sntp_Init. 5 | 6 | The proof runs within 3 minutes on a t2.2xlarge. It provides complete coverage of: 7 | * Sntp_Init() 8 | 9 | To run the proof. 10 | ------------- 11 | 12 | * Add `cbmc`, `goto-cc`, `goto-instrument`, `goto-analyzer`, and `cbmc-viewer` 13 | to your path. 14 | * Run `make`. 15 | * Open html/index.html in a web browser. -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_Init/Sntp_Init_harness.c: -------------------------------------------------------------------------------- 1 | /* 2 | * coreSNTP v1.3.1 3 | * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * SPDX-License-Identifier: MIT 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | * this software and associated documentation files (the "Software"), to deal in 9 | * the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 | * the Software, and to permit persons to whom the Software is furnished to do so, 12 | * subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 19 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 21 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @file Sntp_Init_harness.c 27 | * @brief Implements the proof harness for Sntp_Init function. 28 | */ 29 | 30 | #include 31 | #include "core_sntp_client.h" 32 | 33 | void harness() 34 | { 35 | SntpContext_t * pContext; 36 | SntpServerInfo_t * pTimeServers; 37 | size_t numOfServers; 38 | uint32_t serverResponseTimeoutMs; 39 | uint8_t * pNetworkBuffer; 40 | size_t bufferSize; 41 | SntpResolveDns_t resolveDnsFunc; 42 | SntpGetTime_t getSystemTimeFunc; 43 | SntpSetTime_t setSystemTimeFunc; 44 | UdpTransportInterface_t * pTransportIntf; 45 | SntpAuthenticationInterface_t * pAuthIntf; 46 | SntpStatus_t sntpStatus; 47 | 48 | pContext = malloc( sizeof( SntpContext_t ) ); 49 | pTimeServers = malloc( sizeof( SntpServerInfo_t ) ); 50 | 51 | __CPROVER_assume( bufferSize < CBMC_MAX_OBJECT_SIZE ); 52 | 53 | pNetworkBuffer = malloc( bufferSize ); 54 | pTransportIntf = malloc( sizeof( UdpTransportInterface_t ) ); 55 | pAuthIntf = malloc( sizeof( SntpAuthenticationInterface_t ) ); 56 | 57 | sntpStatus = Sntp_Init( pContext, pTimeServers, numOfServers, serverResponseTimeoutMs, pNetworkBuffer, 58 | bufferSize, resolveDnsFunc, getSystemTimeFunc, setSystemTimeFunc, 59 | pTransportIntf, pAuthIntf ); 60 | 61 | __CPROVER_assert( ( sntpStatus == SntpErrorBadParameter || sntpStatus == SntpSuccess || sntpStatus == SntpErrorBufferTooSmall ), "The return value is not a valid SNTP Status" ); 62 | } 63 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_Init/cbmc-proof.txt: -------------------------------------------------------------------------------- 1 | # This file marks this directory as containing a CBMC proof. 2 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_Init/cbmc-viewer.json: -------------------------------------------------------------------------------- 1 | { "expected-missing-functions": 2 | [ 3 | 4 | ], 5 | "proof-name": "Sntp_Init", 6 | "proof-root": "test/cbmc/proofs" 7 | } 8 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_ReceiveTimeResponse/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: MIT-0 3 | 4 | HARNESS_ENTRY = harness 5 | HARNESS_FILE = Sntp_ReceiveTimeResponse_harness 6 | 7 | # Please see test/cbmc/stubs/core_sntp_stubs.c for 8 | # more information on MAX_NETWORK_RECV_TRIES. 9 | MAX_NETWORK_RECV_TRIES=5 10 | 11 | # Bound on the timeout in Sntp_ReceiveTimeResponse. This timeout is bounded because 12 | # memory saftey can be proven in a only a single iteration. 13 | # Each iteration will try to receive a single packet in its entirey. With a time 14 | # out of 1 we can get coverage of the entire function. Another iteration will 15 | # performed unnecessarily duplicating of the proof. 16 | SNTP_RECEIVE_TIMEOUT=1 17 | 18 | # Maximum number of sntp time servers 19 | MAX_NO_OF_SERVERS=5 20 | 21 | # Maximum number of attempts in outer loop of Sntp_ReceiveTimeResponse needed to receive a response from server. 22 | MAX_ITERATIONS_RECEIVE_RESPONSE=1 23 | 24 | # This should be a unique identifier for this proof, and will appear on the 25 | # Litani dashboard. It can be human-readable and contain spaces if you wish. 26 | PROOF_UID = Sntp_ReceiveTimeResponse 27 | 28 | DEFINES +=-DMAX_NO_OF_SERVERS=$(MAX_NO_OF_SERVERS) 29 | DEFINES +=-DSNTP_RECEIVE_TIMEOUT=$(SNTP_RECEIVE_TIMEOUT) 30 | INCLUDES += 31 | 32 | REMOVE_FUNCTION_BODY +=Sntp_DeserializeResponse 33 | UNWINDSET +=__CPROVER_file_local_core_sntp_client_c_receiveSntpResponse.0:$(shell expr $(MAX_NETWORK_RECV_TRIES) + 1 ) 34 | UNWINDSET +=__CPROVER_file_local_core_sntp_client_c_Sntp_ReceiveTimeResponse.0:$(shell expr $(MAX_ITERATIONS_RECEIVE_RESPONSE) + 1 ) 35 | UNWINDSET +=unconstrainedCoreSntpContext.0:$(shell expr $(MAX_NO_OF_SERVERS) + 1 ) 36 | 37 | 38 | PROOF_SOURCES += $(SRCDIR)/test/cbmc/sources/core_sntp_cbmc_state.c 39 | PROOF_SOURCES += $(SRCDIR)/test/cbmc/stubs/core_sntp_stubs.c 40 | PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE).c 41 | PROJECT_SOURCES += $(SRCDIR)/source/core_sntp_client.c 42 | 43 | include ../Makefile.common 44 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_ReceiveTimeResponse/README.md: -------------------------------------------------------------------------------- 1 | Sntp_ReceiveTimeResponse proof 2 | ============== 3 | 4 | This directory contains a memory safety proof for Sntp_ReceiveTimeResponse. 5 | 6 | To run the proof. 7 | ------------- 8 | 9 | * Add `cbmc`, `goto-cc`, `goto-instrument`, `goto-analyzer`, and `cbmc-viewer` 10 | to your path. 11 | * Run `make`. 12 | * Open html/index.html in a web browser. 13 | 14 | To use [`arpa`](https://awslabs.github.io/aws-proof-build-assistant) to simplify writing Makefiles. 15 | ------------- 16 | 17 | * Run `make arpa` to generate a Makefile.arpa that contains relevant build information for the proof. 18 | * Use Makefile.arpa as the starting point for your proof Makefile by: 19 | 1. Modifying Makefile.arpa (if required). 20 | 2. Including Makefile.arpa into the existing proof Makefile (add `sinclude Makefile.arpa` at the bottom of the Makefile, right before `include ../Makefile.common`). 21 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_ReceiveTimeResponse/Sntp_ReceiveTimeResponse_harness.c: -------------------------------------------------------------------------------- 1 | /* 2 | * coreSNTP v1.3.1 3 | * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * SPDX-License-Identifier: MIT 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | * this software and associated documentation files (the "Software"), to deal in 9 | * the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 | * the Software, and to permit persons to whom the Software is furnished to do so, 12 | * subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 19 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 21 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @file Sntp_ReceiveTimeResponse_harness.c 27 | * @brief Implements the proof harness for Sntp_ReceiveTimeResponse function. 28 | */ 29 | 30 | #include 31 | #include "core_sntp_cbmc_state.h" 32 | #include "core_sntp_stubs.h" 33 | #include "core_sntp_client.h" 34 | 35 | void harness() 36 | { 37 | SntpContext_t * pContext; 38 | uint32_t blockTimeMs; 39 | SntpStatus_t sntpStatus; 40 | 41 | pContext = unconstrainedCoreSntpContext(); 42 | 43 | if( pContext != NULL ) 44 | { 45 | /* Setting the initial value of request time to check for response timeout 46 | * while reading data from network. */ 47 | GetTimeFuncStub( &pContext->lastRequestTime ); 48 | } 49 | 50 | /* The SNTP_RECEIVE_TIMEOUT is used here to control the number of loops 51 | * when receiving on the network. The default is used here because memory 52 | * safety can be proven in only a few iterations. Please see this proof's 53 | * Makefile for more information. */ 54 | __CPROVER_assume( blockTimeMs < SNTP_RECEIVE_TIMEOUT ); 55 | 56 | sntpStatus = Sntp_ReceiveTimeResponse( pContext, blockTimeMs ); 57 | 58 | __CPROVER_assert( ( sntpStatus == SntpErrorBadParameter || sntpStatus == SntpSuccess || 59 | sntpStatus == SntpNoResponseReceived || sntpStatus == SntpRejectedResponse || 60 | sntpStatus == SntpErrorResponseTimeout || sntpStatus == SntpErrorNetworkFailure ), 61 | "The return value is not a valid coreSNTP Status" ); 62 | } 63 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_ReceiveTimeResponse/cbmc-proof.txt: -------------------------------------------------------------------------------- 1 | # This file marks this directory as containing a CBMC proof. 2 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_ReceiveTimeResponse/cbmc-viewer.json: -------------------------------------------------------------------------------- 1 | { "expected-missing-functions": 2 | [ 3 | 4 | ], 5 | "proof-name": "Sntp_ReceiveTimeResponse", 6 | "proof-root": "test/cbmc/proofs" 7 | } 8 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_SendTimeRequest/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: MIT-0 3 | 4 | HARNESS_ENTRY = harness 5 | HARNESS_FILE = Sntp_SendTimeRequest_harness 6 | 7 | # Please see test/cbmc/stubs/core_sntp_stubs.c for 8 | # more information on MAX_NETWORK_SEND_TRIES. 9 | MAX_NETWORK_SEND_TRIES=3 10 | 11 | # Bound on the timeout in Sntp_ReceiveTimeResponse. This timeout is bounded because 12 | # memory saftey can be proven in a only a single iteration. 13 | # Each iteration will try to receive a single packet in its entirey. With a time 14 | # out of 1 we can get coverage of the entire function. Another iteration will 15 | # performed unnecessarily duplicating of the proof. 16 | SNTP_SEND_TIMEOUT=1 17 | 18 | # Maximum number of sntp time servers 19 | MAX_NO_OF_SERVERS=5 20 | 21 | # This should be a unique identifier for this proof, and will appear on the 22 | # Litani dashboard. It can be human-readable and contain spaces if you wish. 23 | PROOF_UID = Sntp_SendTimeRequest 24 | 25 | DEFINES +=-DMAX_NO_OF_SERVERS=$(MAX_NO_OF_SERVERS) 26 | DEFINES +=-DSNTP_SEND_TIMEOUT=$(SNTP_SEND_TIMEOUT) 27 | INCLUDES += 28 | 29 | # Providing a stub for this function as we have already have a separate proof 30 | # for this function 31 | REMOVE_FUNCTION_BODY +=Sntp_SerializeRequest 32 | UNWINDSET +=__CPROVER_file_local_core_sntp_client_c_sendSntpPacket.0:$(MAX_NETWORK_SEND_TRIES) 33 | UNWINDSET +=unconstrainedCoreSntpContext.0:$(shell expr $(MAX_NO_OF_SERVERS) + 1 ) 34 | 35 | PROOF_SOURCES += $(SRCDIR)/test/cbmc/sources/core_sntp_cbmc_state.c 36 | PROOF_SOURCES += $(SRCDIR)/test/cbmc/stubs/core_sntp_stubs.c 37 | PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE).c 38 | PROJECT_SOURCES += $(SRCDIR)/source/core_sntp_client.c 39 | 40 | include ../Makefile.common 41 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_SendTimeRequest/README.md: -------------------------------------------------------------------------------- 1 | Sntp_SendTimeRequest proof 2 | ============== 3 | 4 | This directory contains a memory safety proof for Sntp_SendTimeRequest. 5 | 6 | To run the proof. 7 | ------------- 8 | 9 | * Add `cbmc`, `goto-cc`, `goto-instrument`, `goto-analyzer`, and `cbmc-viewer` 10 | to your path. 11 | * Run `make`. 12 | * Open html/index.html in a web browser. 13 | 14 | ------------- 15 | 16 | * Run `make arpa` to generate a Makefile.arpa that contains relevant build information for the proof. 17 | * Use Makefile.arpa as the starting point for your proof Makefile by: 18 | 1. Modifying Makefile.arpa (if required). 19 | 2. Including Makefile.arpa into the existing proof Makefile (add `sinclude Makefile.arpa` at the bottom of the Makefile, right before `include ../Makefile.common`). 20 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_SendTimeRequest/Sntp_SendTimeRequest_harness.c: -------------------------------------------------------------------------------- 1 | /* 2 | * coreSNTP v1.3.1 3 | * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * SPDX-License-Identifier: MIT 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | * this software and associated documentation files (the "Software"), to deal in 9 | * the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 | * the Software, and to permit persons to whom the Software is furnished to do so, 12 | * subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 19 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 21 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @file Sntp_SendTimeRequest_harness.c 27 | * @brief Implements the proof harness for Sntp_SendTimeRequest function. 28 | */ 29 | 30 | #include 31 | #include "core_sntp_client.h" 32 | #include "core_sntp_cbmc_state.h" 33 | 34 | void harness() 35 | { 36 | SntpContext_t * pContext; 37 | uint32_t randomNumber; 38 | SntpStatus_t sntpStatus; 39 | uint32_t blockTimeMs; 40 | 41 | pContext = unconstrainedCoreSntpContext(); 42 | 43 | /* The SNTP_SEND_TIMEOUT is used here to control the number of loops 44 | * when sending data on the network. The default is used here because memory 45 | * safety can be proven in only a few iterations. Please see this proof's 46 | * Makefile for more information. */ 47 | __CPROVER_assume( blockTimeMs < SNTP_SEND_TIMEOUT ); 48 | 49 | sntpStatus = Sntp_SendTimeRequest( pContext, randomNumber, blockTimeMs ); 50 | 51 | __CPROVER_assert( ( sntpStatus == SntpErrorBadParameter || sntpStatus == SntpSuccess || 52 | sntpStatus == SntpErrorContextNotInitialized || sntpStatus == SntpErrorSendTimeout || 53 | sntpStatus == SntpErrorBufferTooSmall || sntpStatus == SntpErrorDnsFailure || 54 | sntpStatus == SntpErrorAuthFailure || sntpStatus == SntpErrorNetworkFailure ), 55 | "The return value is not a valid coreSNTP Status" ); 56 | } 57 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_SendTimeRequest/cbmc-proof.txt: -------------------------------------------------------------------------------- 1 | # This file marks this directory as containing a CBMC proof. 2 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_SendTimeRequest/cbmc-viewer.json: -------------------------------------------------------------------------------- 1 | { "expected-missing-functions": 2 | [ 3 | 4 | ], 5 | "proof-name": "Sntp_SendTimeRequest", 6 | "proof-root": "test/cbmc/proofs" 7 | } 8 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_SerializeRequest/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: MIT-0 3 | 4 | HARNESS_ENTRY = harness 5 | HARNESS_FILE = Sntp_SerializeRequest_harness 6 | 7 | # This should be a unique identifier for this proof, and will appear on the 8 | # Litani dashboard. It can be human-readable and contain spaces if you wish. 9 | PROOF_UID = Sntp_SerializeRequest 10 | 11 | DEFINES += 12 | INCLUDES += 13 | 14 | REMOVE_FUNCTION_BODY += 15 | UNWINDSET += 16 | 17 | PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE).c 18 | PROJECT_SOURCES += $(SRCDIR)/source/core_sntp_serializer.c 19 | 20 | include ../Makefile.common 21 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_SerializeRequest/README.md: -------------------------------------------------------------------------------- 1 | Sntp_SerializeRequest proof 2 | ============== 3 | 4 | This directory contains a memory safety proof for Sntp_SerializeRequest. 5 | 6 | The proof runs within 3 minutes on a t2.2xlarge. It provides complete coverage of: 7 | * Sntp_SerializeRequest() 8 | 9 | To run the proof. 10 | ------------- 11 | 12 | * Add `cbmc`, `goto-cc`, `goto-instrument`, `goto-analyzer`, and `cbmc-viewer` 13 | to your path. 14 | * Run `make`. 15 | * Open html/index.html in a web browser. 16 | 17 | To use [`arpa`](https://awslabs.github.io/aws-proof-build-assistant) to simplify writing Makefiles. 18 | ------------- 19 | 20 | * Run `make arpa` to generate a Makefile.arpa that contains relevant build information for the proof. 21 | * Use Makefile.arpa as the starting point for your proof Makefile by: 22 | 1. Modifying Makefile.arpa (if required). 23 | 2. Including Makefile.arpa into the existing proof Makefile (add `sinclude Makefile.arpa` at the bottom of the Makefile, right before `include ../Makefile.common`). 24 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_SerializeRequest/Sntp_SerializeRequest_harness.c: -------------------------------------------------------------------------------- 1 | /* 2 | * coreSNTP v1.3.1 3 | * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * SPDX-License-Identifier: MIT 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | * this software and associated documentation files (the "Software"), to deal in 9 | * the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 | * the Software, and to permit persons to whom the Software is furnished to do so, 12 | * subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 19 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 21 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @file Sntp_SerializeRequest_harness.c 27 | * @brief Implements the proof harness for Sntp_SerializeRequest function. 28 | */ 29 | 30 | #include 31 | #include "core_sntp_serializer.h" 32 | 33 | void harness() 34 | { 35 | SntpTimestamp_t * pRequestTime; 36 | uint32_t randomNumber; 37 | void * pBuffer; 38 | size_t bufferSize; 39 | SntpStatus_t sntpStatus; 40 | 41 | pRequestTime = malloc( sizeof( SntpTimestamp_t ) ); 42 | 43 | __CPROVER_assume( bufferSize < CBMC_MAX_OBJECT_SIZE ); 44 | 45 | pBuffer = malloc( bufferSize ); 46 | 47 | sntpStatus = Sntp_SerializeRequest( pRequestTime, randomNumber, pBuffer, bufferSize ); 48 | 49 | __CPROVER_assert( ( sntpStatus == SntpErrorBadParameter || sntpStatus == SntpErrorBufferTooSmall || sntpStatus == SntpSuccess ), "The return value is not a valid SNTP Status" ); 50 | } 51 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_SerializeRequest/cbmc-proof.txt: -------------------------------------------------------------------------------- 1 | # This file marks this directory as containing a CBMC proof. 2 | -------------------------------------------------------------------------------- /test/cbmc/proofs/Sntp_SerializeRequest/cbmc-viewer.json: -------------------------------------------------------------------------------- 1 | { "expected-missing-functions": 2 | [ 3 | 4 | ], 5 | "proof-name": "Sntp_SerializeRequest", 6 | "proof-root": "test/cbmc/proofs" 7 | } 8 | -------------------------------------------------------------------------------- /test/cbmc/proofs/lib/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreeRTOS/coreSNTP/1cbb9a46d0223e4cea621167c38dc8a4aabaa476/test/cbmc/proofs/lib/__init__.py -------------------------------------------------------------------------------- /test/cbmc/proofs/lib/print_tool_versions.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | # SPDX-License-Identifier: MIT-0 5 | 6 | 7 | import logging 8 | import pathlib 9 | import shutil 10 | import subprocess 11 | 12 | 13 | _TOOLS = [ 14 | "cadical", 15 | "cbmc", 16 | "cbmc-viewer", 17 | "cbmc-starter-kit-update", 18 | "kissat", 19 | "litani", 20 | ] 21 | 22 | 23 | def _format_versions(table): 24 | lines = [ 25 | "", 26 | '', 27 | ] 28 | for tool, version in table.items(): 29 | if version: 30 | v_str = f'
{version}
' 31 | else: 32 | v_str = 'not found' 33 | lines.append( 34 | f'' 36 | f'') 37 | lines.append("
Tool Versions
{tool}:{v_str}
") 38 | return "\n".join(lines) 39 | 40 | 41 | def _get_tool_versions(): 42 | ret = {} 43 | for tool in _TOOLS: 44 | err = f"Could not determine version of {tool}: " 45 | ret[tool] = None 46 | if not shutil.which(tool): 47 | logging.error("%s'%s' not found on $PATH", err, tool) 48 | continue 49 | cmd = [tool, "--version"] 50 | proc = subprocess.Popen(cmd, text=True, stdout=subprocess.PIPE) 51 | try: 52 | out, _ = proc.communicate(timeout=10) 53 | except subprocess.TimeoutExpired: 54 | logging.error("%s'%s --version' timed out", err, tool) 55 | continue 56 | if proc.returncode: 57 | logging.error( 58 | "%s'%s --version' returned %s", err, tool, str(proc.returncode)) 59 | continue 60 | ret[tool] = out.strip() 61 | return ret 62 | 63 | 64 | def main(): 65 | exe_name = pathlib.Path(__file__).name 66 | logging.basicConfig(format=f"{exe_name}: %(message)s") 67 | 68 | table = _get_tool_versions() 69 | out = _format_versions(table) 70 | print(out) 71 | 72 | 73 | if __name__ == "__main__": 74 | main() 75 | -------------------------------------------------------------------------------- /test/cbmc/proofs/lib/summarize.py: -------------------------------------------------------------------------------- 1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: MIT-0 3 | 4 | import argparse 5 | import json 6 | import logging 7 | import os 8 | import sys 9 | 10 | 11 | DESCRIPTION = """Print 2 tables in GitHub-flavored Markdown that summarize 12 | an execution of CBMC proofs.""" 13 | 14 | 15 | def get_args(): 16 | """Parse arguments for summarize script.""" 17 | parser = argparse.ArgumentParser(description=DESCRIPTION) 18 | for arg in [{ 19 | "flags": ["--run-file"], 20 | "help": "path to the Litani run.json file", 21 | "required": True, 22 | }]: 23 | flags = arg.pop("flags") 24 | parser.add_argument(*flags, **arg) 25 | return parser.parse_args() 26 | 27 | 28 | def _get_max_length_per_column_list(data): 29 | ret = [len(item) + 1 for item in data[0]] 30 | for row in data[1:]: 31 | for idx, item in enumerate(row): 32 | ret[idx] = max(ret[idx], len(item) + 1) 33 | return ret 34 | 35 | 36 | def _get_table_header_separator(max_length_per_column_list): 37 | line_sep = "" 38 | for max_length_of_word_in_col in max_length_per_column_list: 39 | line_sep += "|" + "-" * (max_length_of_word_in_col + 1) 40 | line_sep += "|\n" 41 | return line_sep 42 | 43 | 44 | def _get_entries(max_length_per_column_list, row_data): 45 | entries = [] 46 | for row in row_data: 47 | entry = "" 48 | for idx, word in enumerate(row): 49 | max_length_of_word_in_col = max_length_per_column_list[idx] 50 | space_formatted_word = (max_length_of_word_in_col - len(word)) * " " 51 | entry += "| " + word + space_formatted_word 52 | entry += "|\n" 53 | entries.append(entry) 54 | return entries 55 | 56 | 57 | def _get_rendered_table(data): 58 | table = [] 59 | max_length_per_column_list = _get_max_length_per_column_list(data) 60 | entries = _get_entries(max_length_per_column_list, data) 61 | for idx, entry in enumerate(entries): 62 | if idx == 1: 63 | line_sep = _get_table_header_separator(max_length_per_column_list) 64 | table.append(line_sep) 65 | table.append(entry) 66 | table.append("\n") 67 | return "".join(table) 68 | 69 | 70 | def _get_status_and_proof_summaries(run_dict): 71 | """Parse a dict representing a Litani run and create lists summarizing the 72 | proof results. 73 | 74 | Parameters 75 | ---------- 76 | run_dict 77 | A dictionary representing a Litani run. 78 | 79 | 80 | Returns 81 | ------- 82 | A list of 2 lists. 83 | The first sub-list maps a status to the number of proofs with that status. 84 | The second sub-list maps each proof to its status. 85 | """ 86 | count_statuses = {} 87 | proofs = [["Proof", "Status"]] 88 | for proof_pipeline in run_dict["pipelines"]: 89 | status_pretty_name = proof_pipeline["status"].title().replace("_", " ") 90 | try: 91 | count_statuses[status_pretty_name] += 1 92 | except KeyError: 93 | count_statuses[status_pretty_name] = 1 94 | if proof_pipeline["name"] == "print_tool_versions": 95 | continue 96 | proofs.append([proof_pipeline["name"], status_pretty_name]) 97 | statuses = [["Status", "Count"]] 98 | for status, count in count_statuses.items(): 99 | statuses.append([status, str(count)]) 100 | return [statuses, proofs] 101 | 102 | 103 | def print_proof_results(out_file): 104 | """ 105 | Print 2 strings that summarize the proof results. 106 | When printing, each string will render as a GitHub flavored Markdown table. 107 | """ 108 | output = "## Summary of CBMC proof results\n\n" 109 | with open(out_file, encoding='utf-8') as run_json: 110 | run_dict = json.load(run_json) 111 | status_table, proof_table = _get_status_and_proof_summaries(run_dict) 112 | for summary in (status_table, proof_table): 113 | output += _get_rendered_table(summary) 114 | 115 | print(output) 116 | sys.stdout.flush() 117 | 118 | github_summary_file = os.getenv("GITHUB_STEP_SUMMARY") 119 | if github_summary_file: 120 | with open(github_summary_file, "a") as handle: 121 | print(output, file=handle) 122 | handle.flush() 123 | else: 124 | logging.warning( 125 | "$GITHUB_STEP_SUMMARY not set, not writing summary file") 126 | 127 | msg = ( 128 | "Click the 'Summary' button to view a Markdown table " 129 | "summarizing all proof results") 130 | if run_dict["status"] != "success": 131 | logging.error("Not all proofs passed.") 132 | logging.error(msg) 133 | sys.exit(1) 134 | logging.info(msg) 135 | 136 | 137 | if __name__ == '__main__': 138 | args = get_args() 139 | logging.basicConfig(format="%(levelname)s: %(message)s") 140 | try: 141 | print_proof_results(args.run_file) 142 | except Exception as ex: # pylint: disable=broad-except 143 | logging.critical("Could not print results. Exception: %s", str(ex)) 144 | -------------------------------------------------------------------------------- /test/cbmc/proofs/run-cbmc-proofs.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | # SPDX-License-Identifier: MIT-0 5 | 6 | 7 | import argparse 8 | import asyncio 9 | import json 10 | import logging 11 | import math 12 | import os 13 | import pathlib 14 | import re 15 | import subprocess 16 | import sys 17 | import tempfile 18 | 19 | from lib.summarize import print_proof_results 20 | 21 | 22 | DESCRIPTION = "Configure and run all CBMC proofs in parallel" 23 | 24 | # Keep the epilog hard-wrapped at 70 characters, as it gets printed 25 | # verbatim in the terminal. 70 characters stops here --------------> | 26 | EPILOG = """ 27 | This tool automates the process of running `make report` in each of 28 | the CBMC proof directories. The tool calculates the dependency graph 29 | of all tasks needed to build, run, and report on all the proofs, and 30 | executes these tasks in parallel. 31 | 32 | The tool is roughly equivalent to doing this: 33 | 34 | litani init --project "my-cool-project"; 35 | 36 | find . -name cbmc-proof.txt | while read -r proof; do 37 | pushd $(dirname ${proof}); 38 | 39 | # The `make _report` rule adds a single proof to litani 40 | # without running it 41 | make _report; 42 | 43 | popd; 44 | done 45 | 46 | litani run-build; 47 | 48 | except that it is much faster and provides some convenience options. 49 | The CBMC CI runs this script with no arguments to build and run all 50 | proofs in parallel. The value of "my-cool-project" is taken from the 51 | PROJECT_NAME variable in Makefile-project-defines. 52 | 53 | The --no-standalone argument omits the `litani init` and `litani 54 | run-build`; use it when you want to add additional proof jobs, not 55 | just the CBMC ones. In that case, you would run `litani init` 56 | yourself; then run `run-cbmc-proofs --no-standalone`; add any 57 | additional jobs that you want to execute with `litani add-job`; and 58 | finally run `litani run-build`. 59 | 60 | The litani dashboard will be written under the `output` directory; the 61 | cbmc-viewer reports remain in the `$PROOF_DIR/report` directory. The 62 | HTML dashboard from the latest Litani run will always be symlinked to 63 | `output/latest/html/index.html`, so you can keep that page open in 64 | your browser and reload the page whenever you re-run this script. 65 | """ 66 | # 70 characters stops here ----------------------------------------> | 67 | 68 | 69 | def get_project_name(): 70 | cmd = [ 71 | "make", 72 | "--no-print-directory", 73 | "-f", "Makefile.common", 74 | "echo-project-name", 75 | ] 76 | logging.debug(" ".join(cmd)) 77 | proc = subprocess.run(cmd, universal_newlines=True, stdout=subprocess.PIPE, check=False) 78 | if proc.returncode: 79 | logging.critical("could not run make to determine project name") 80 | sys.exit(1) 81 | if not proc.stdout.strip(): 82 | logging.warning( 83 | "project name has not been set; using generic name instead. " 84 | "Set the PROJECT_NAME value in Makefile-project-defines to " 85 | "remove this warning") 86 | return "" 87 | return proc.stdout.strip() 88 | 89 | 90 | def get_args(): 91 | pars = argparse.ArgumentParser( 92 | description=DESCRIPTION, epilog=EPILOG, 93 | formatter_class=argparse.RawDescriptionHelpFormatter) 94 | for arg in [{ 95 | "flags": ["-j", "--parallel-jobs"], 96 | "type": int, 97 | "metavar": "N", 98 | "help": "run at most N proof jobs in parallel", 99 | }, { 100 | "flags": ["--fail-on-proof-failure"], 101 | "action": "store_true", 102 | "help": "exit with return code `10' if any proof failed" 103 | " (default: exit 0)", 104 | }, { 105 | "flags": ["--no-standalone"], 106 | "action": "store_true", 107 | "help": "only configure proofs: do not initialize nor run", 108 | }, { 109 | "flags": ["-p", "--proofs"], 110 | "nargs": "+", 111 | "metavar": "DIR", 112 | "help": "only run proof in directory DIR (can pass more than one)", 113 | }, { 114 | "flags": ["--project-name"], 115 | "metavar": "NAME", 116 | "default": get_project_name(), 117 | "help": "project name for report. Default: %(default)s", 118 | }, { 119 | "flags": ["--marker-file"], 120 | "metavar": "FILE", 121 | "default": "cbmc-proof.txt", 122 | "help": ( 123 | "name of file that marks proof directories. Default: " 124 | "%(default)s"), 125 | }, { 126 | "flags": ["--no-memory-profile"], 127 | "action": "store_true", 128 | "help": "disable memory profiling, even if Litani supports it" 129 | }, { 130 | "flags": ["--no-expensive-limit"], 131 | "action": "store_true", 132 | "help": "do not limit parallelism of 'EXPENSIVE' jobs", 133 | }, { 134 | "flags": ["--expensive-jobs-parallelism"], 135 | "metavar": "N", 136 | "default": 1, 137 | "type": int, 138 | "help": ( 139 | "how many proof jobs marked 'EXPENSIVE' to run in parallel. " 140 | "Default: %(default)s"), 141 | }, { 142 | "flags": ["--verbose"], 143 | "action": "store_true", 144 | "help": "verbose output", 145 | }, { 146 | "flags": ["--debug"], 147 | "action": "store_true", 148 | "help": "debug output", 149 | }, { 150 | "flags": ["--summarize"], 151 | "action": "store_true", 152 | "help": "summarize proof results with two tables on stdout", 153 | }, { 154 | "flags": ["--version"], 155 | "action": "version", 156 | "version": "CBMC starter kit 2.5", 157 | "help": "display version and exit" 158 | }]: 159 | flags = arg.pop("flags") 160 | pars.add_argument(*flags, **arg) 161 | return pars.parse_args() 162 | 163 | 164 | def set_up_logging(verbose): 165 | if verbose: 166 | level = logging.DEBUG 167 | else: 168 | level = logging.WARNING 169 | logging.basicConfig( 170 | format="run-cbmc-proofs: %(message)s", level=level) 171 | 172 | 173 | def task_pool_size(): 174 | ret = os.cpu_count() 175 | if ret is None or ret < 3: 176 | return 1 177 | return ret - 2 178 | 179 | 180 | def print_counter(counter): 181 | # pylint: disable=consider-using-f-string 182 | print("\rConfiguring CBMC proofs: " 183 | "{complete:{width}} / {total:{width}}".format(**counter), end="", file=sys.stderr) 184 | 185 | 186 | def get_proof_dirs(proof_root, proof_list, marker_file): 187 | if proof_list is not None: 188 | proofs_remaining = list(proof_list) 189 | else: 190 | proofs_remaining = [] 191 | 192 | for root, _, fyles in os.walk(proof_root): 193 | proof_name = str(pathlib.Path(root).name) 194 | if root != str(proof_root) and ".litani_cache_dir" in fyles: 195 | pathlib.Path(f"{root}/.litani_cache_dir").unlink() 196 | if proof_list and proof_name not in proof_list: 197 | continue 198 | if proof_list and proof_name in proofs_remaining: 199 | proofs_remaining.remove(proof_name) 200 | if marker_file in fyles: 201 | yield root 202 | 203 | if proofs_remaining: 204 | logging.critical( 205 | "The following proofs were not found: %s", 206 | ", ".join(proofs_remaining)) 207 | sys.exit(1) 208 | 209 | 210 | def run_build(litani, jobs, fail_on_proof_failure, summarize): 211 | cmd = [str(litani), "run-build"] 212 | if jobs: 213 | cmd.extend(["-j", str(jobs)]) 214 | if fail_on_proof_failure: 215 | cmd.append("--fail-on-pipeline-failure") 216 | if summarize: 217 | out_file = pathlib.Path(tempfile.gettempdir(), "run.json").resolve() 218 | cmd.extend(["--out-file", str(out_file)]) 219 | 220 | logging.debug(" ".join(cmd)) 221 | proc = subprocess.run(cmd, check=False) 222 | 223 | if proc.returncode and not fail_on_proof_failure: 224 | logging.critical("Failed to run litani run-build") 225 | sys.exit(1) 226 | 227 | if summarize: 228 | print_proof_results(out_file) 229 | out_file.unlink() 230 | 231 | if proc.returncode: 232 | logging.error("One or more proofs failed") 233 | sys.exit(10) 234 | 235 | def get_litani_path(proof_root): 236 | cmd = [ 237 | "make", 238 | "--no-print-directory", 239 | f"PROOF_ROOT={proof_root}", 240 | "-f", "Makefile.common", 241 | "litani-path", 242 | ] 243 | logging.debug(" ".join(cmd)) 244 | proc = subprocess.run(cmd, universal_newlines=True, stdout=subprocess.PIPE, check=False) 245 | if proc.returncode: 246 | logging.critical("Could not determine path to litani") 247 | sys.exit(1) 248 | return proc.stdout.strip() 249 | 250 | 251 | def get_litani_capabilities(litani_path): 252 | cmd = [litani_path, "print-capabilities"] 253 | proc = subprocess.run( 254 | cmd, text=True, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, check=False) 255 | if proc.returncode: 256 | return [] 257 | try: 258 | return json.loads(proc.stdout) 259 | except RuntimeError: 260 | logging.warning("Could not load litani capabilities: '%s'", proc.stdout) 261 | return [] 262 | 263 | 264 | def check_uid_uniqueness(proof_dir, proof_uids): 265 | with (pathlib.Path(proof_dir) / "Makefile").open() as handle: 266 | for line in handle: 267 | match = re.match(r"^PROOF_UID\s*=\s*(?P\w+)", line) 268 | if not match: 269 | continue 270 | if match["uid"] not in proof_uids: 271 | proof_uids[match["uid"]] = proof_dir 272 | return 273 | 274 | logging.critical( 275 | "The Makefile in directory '%s' should have a different " 276 | "PROOF_UID than the Makefile in directory '%s'", 277 | proof_dir, proof_uids[match["uid"]]) 278 | sys.exit(1) 279 | 280 | logging.critical( 281 | "The Makefile in directory '%s' should contain a line like", proof_dir) 282 | logging.critical("PROOF_UID = ...") 283 | logging.critical("with a unique identifier for the proof.") 284 | sys.exit(1) 285 | 286 | 287 | def should_enable_memory_profiling(litani_caps, args): 288 | if args.no_memory_profile: 289 | return False 290 | return "memory_profile" in litani_caps 291 | 292 | 293 | def should_enable_pools(litani_caps, args): 294 | if args.no_expensive_limit: 295 | return False 296 | return "pools" in litani_caps 297 | 298 | 299 | async def configure_proof_dirs( # pylint: disable=too-many-arguments 300 | queue, counter, proof_uids, enable_pools, enable_memory_profiling, debug): 301 | while True: 302 | print_counter(counter) 303 | path = str(await queue.get()) 304 | 305 | check_uid_uniqueness(path, proof_uids) 306 | 307 | pools = ["ENABLE_POOLS=true"] if enable_pools else [] 308 | profiling = [ 309 | "ENABLE_MEMORY_PROFILING=true"] if enable_memory_profiling else [] 310 | 311 | # Allow interactive tasks to preempt proof configuration 312 | proc = await asyncio.create_subprocess_exec( 313 | "nice", "-n", "15", "make", *pools, 314 | *profiling, "-B", "_report", "" if debug else "--quiet", cwd=path, 315 | stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE) 316 | stdout, stderr = await proc.communicate() 317 | logging.debug("returncode: %s", str(proc.returncode)) 318 | logging.debug("stdout:") 319 | for line in stdout.decode().splitlines(): 320 | logging.debug(line) 321 | logging.debug("stderr:") 322 | for line in stderr.decode().splitlines(): 323 | logging.debug(line) 324 | 325 | counter["fail" if proc.returncode else "pass"].append(path) 326 | counter["complete"] += 1 327 | 328 | print_counter(counter) 329 | queue.task_done() 330 | 331 | 332 | async def main(): # pylint: disable=too-many-locals 333 | args = get_args() 334 | set_up_logging(args.verbose) 335 | 336 | proof_root = pathlib.Path(os.getcwd()) 337 | litani = get_litani_path(proof_root) 338 | 339 | litani_caps = get_litani_capabilities(litani) 340 | enable_pools = should_enable_pools(litani_caps, args) 341 | init_pools = [ 342 | "--pools", f"expensive:{args.expensive_jobs_parallelism}" 343 | ] if enable_pools else [] 344 | 345 | if not args.no_standalone: 346 | cmd = [ 347 | str(litani), "init", *init_pools, "--project", args.project_name, 348 | "--no-print-out-dir", 349 | ] 350 | 351 | if "output_directory_flags" in litani_caps: 352 | out_prefix = proof_root / "output" 353 | out_symlink = out_prefix / "latest" 354 | out_index = out_symlink / "html" / "index.html" 355 | cmd.extend([ 356 | "--output-prefix", str(out_prefix), 357 | "--output-symlink", str(out_symlink), 358 | ]) 359 | print( 360 | "\nFor your convenience, the output of this run will be symbolically linked to ", 361 | out_index, "\n") 362 | 363 | logging.debug(" ".join(cmd)) 364 | proc = subprocess.run(cmd, check=False) 365 | if proc.returncode: 366 | logging.critical("Failed to run litani init") 367 | sys.exit(1) 368 | 369 | proof_dirs = list(get_proof_dirs( 370 | proof_root, args.proofs, args.marker_file)) 371 | if not proof_dirs: 372 | logging.critical("No proof directories found") 373 | sys.exit(1) 374 | 375 | proof_queue = asyncio.Queue() 376 | for proof_dir in proof_dirs: 377 | proof_queue.put_nowait(proof_dir) 378 | 379 | counter = { 380 | "pass": [], 381 | "fail": [], 382 | "complete": 0, 383 | "total": len(proof_dirs), 384 | "width": int(math.log10(len(proof_dirs))) + 1 385 | } 386 | 387 | proof_uids = {} 388 | tasks = [] 389 | 390 | enable_memory_profiling = should_enable_memory_profiling(litani_caps, args) 391 | 392 | for _ in range(task_pool_size()): 393 | task = asyncio.create_task(configure_proof_dirs( 394 | proof_queue, counter, proof_uids, enable_pools, 395 | enable_memory_profiling, args.debug)) 396 | tasks.append(task) 397 | 398 | await proof_queue.join() 399 | 400 | print_counter(counter) 401 | print("", file=sys.stderr) 402 | 403 | if counter["fail"]: 404 | logging.critical( 405 | "Failed to configure the following proofs:\n%s", "\n".join( 406 | [str(f) for f in counter["fail"]])) 407 | sys.exit(1) 408 | 409 | if not args.no_standalone: 410 | run_build(litani, args.parallel_jobs, args.fail_on_proof_failure, args.summarize) 411 | 412 | 413 | if __name__ == "__main__": 414 | asyncio.run(main()) 415 | -------------------------------------------------------------------------------- /test/cbmc/sources/README.md: -------------------------------------------------------------------------------- 1 | CBMC proof source code 2 | ====================== 3 | 4 | This directory contains source code written for CBMC proofs. It is 5 | common to write some code to model aspects of the system under test, 6 | and this code goes here. 7 | -------------------------------------------------------------------------------- /test/cbmc/sources/core_sntp_cbmc_state.c: -------------------------------------------------------------------------------- 1 | /* 2 | * coreSNTP v1.3.1 3 | * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * SPDX-License-Identifier: MIT 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | * this software and associated documentation files (the "Software"), to deal in 9 | * the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 | * the Software, and to permit persons to whom the Software is furnished to do so, 12 | * subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 19 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 21 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @file core_sntp_cbmc_state.c 27 | * @brief Implements the functions defined in core_sntp_cbmc_state.h. 28 | */ 29 | #include 30 | #include 31 | #include "core_sntp_client.h" 32 | #include "core_sntp_cbmc_state.h" 33 | #include "core_sntp_stubs.h" 34 | 35 | SntpContext_t * unconstrainedCoreSntpContext() 36 | { 37 | SntpServerInfo_t * pTimeServers; 38 | SntpContext_t * pContext; 39 | size_t currentServerIndex; 40 | size_t numOfServers; 41 | uint32_t serverResponseTimeoutMs; 42 | uint8_t * pNetworkBuffer; 43 | size_t bufferSize; 44 | UdpTransportInterface_t * pNetworkIntf; 45 | SntpAuthenticationInterface_t * pAuthIntf; 46 | SntpStatus_t sntpStatus = SntpSuccess; 47 | 48 | pContext = malloc( sizeof( SntpContext_t ) ); 49 | 50 | __CPROVER_assume( numOfServers < MAX_NO_OF_SERVERS ); 51 | __CPROVER_assume( serverResponseTimeoutMs < CBMC_MAX_OBJECT_SIZE ); 52 | __CPROVER_assume( currentServerIndex < CBMC_MAX_OBJECT_SIZE ); 53 | 54 | if( numOfServers == 0 ) 55 | { 56 | pTimeServers = NULL; 57 | } 58 | else 59 | { 60 | pTimeServers = malloc( numOfServers * sizeof( SntpServerInfo_t ) ); 61 | } 62 | 63 | if( pTimeServers != NULL ) 64 | { 65 | for( size_t i = 0; i < numOfServers; i++ ) 66 | { 67 | __CPROVER_assume( pTimeServers[ i ].serverNameLen < CBMC_MAX_OBJECT_SIZE ); 68 | __CPROVER_assume( pTimeServers[ i ].port < CBMC_MAX_OBJECT_SIZE ); 69 | pTimeServers[ i ].pServerName = malloc( pTimeServers[ i ].serverNameLen ); 70 | } 71 | } 72 | 73 | __CPROVER_assume( bufferSize < CBMC_MAX_OBJECT_SIZE ); 74 | pNetworkBuffer = malloc( bufferSize ); 75 | 76 | pNetworkIntf = malloc( sizeof( UdpTransportInterface_t ) ); 77 | 78 | if( pNetworkIntf != NULL ) 79 | { 80 | pNetworkIntf->pUserContext = malloc( sizeof( NetworkContext_t ) ); 81 | pNetworkIntf->sendTo = NetworkInterfaceSendStub; 82 | pNetworkIntf->recvFrom = NetworkInterfaceReceiveStub; 83 | } 84 | 85 | pAuthIntf = malloc( sizeof( SntpAuthenticationInterface_t ) ); 86 | 87 | if( pAuthIntf != NULL ) 88 | { 89 | pAuthIntf->pAuthContext = malloc( sizeof( SntpAuthContext_t ) ); 90 | pAuthIntf->generateClientAuth = GenerateClientAuthStub; 91 | pAuthIntf->validateServerAuth = ValidateServerAuthStub; 92 | } 93 | 94 | /* It is part of the API contract to call Sntp_Init() with the SntpContext_t 95 | * before any other function in core_sntp_client.h. */ 96 | if( pContext != NULL ) 97 | { 98 | pContext->currentServerIndex = currentServerIndex; 99 | sntpStatus = Sntp_Init( pContext, pTimeServers, numOfServers, serverResponseTimeoutMs, pNetworkBuffer, 100 | bufferSize, ResolveDnsFuncStub, GetTimeFuncStub, SetTimeFuncStub, 101 | pNetworkIntf, pAuthIntf ); 102 | } 103 | 104 | /* If the SntpContext_t initialization failed, then set the context to NULL 105 | * so that function under harness will return immediately upon a NULL 106 | * parameter check. */ 107 | if( sntpStatus != SntpSuccess ) 108 | { 109 | pContext = NULL; 110 | } 111 | 112 | return pContext; 113 | } 114 | -------------------------------------------------------------------------------- /test/cbmc/stubs/README.md: -------------------------------------------------------------------------------- 1 | CBMC proof stubs 2 | ====================== 3 | 4 | This directory contains the stubs written for CBMC proofs. It is 5 | common to stub out functionality like network send and receive methods 6 | when writing a CBMC proof, and the code for these stubs goes here. 7 | -------------------------------------------------------------------------------- /test/cbmc/stubs/core_sntp_stubs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * coreSNTP v1.3.1 3 | * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * SPDX-License-Identifier: MIT 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | * this software and associated documentation files (the "Software"), to deal in 9 | * the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 | * the Software, and to permit persons to whom the Software is furnished to do so, 12 | * subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 19 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 21 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @file core_sntp_stubs.c 27 | * @brief Definition of stubs for UDP transport and authentication interfaces of coreSNTP API. 28 | */ 29 | 30 | #include 31 | #include "core_sntp_client.h" 32 | #include "core_sntp_serializer.h" 33 | #include "core_sntp_stubs.h" 34 | 35 | #define TEST_TIMESTAMP \ 36 | { \ 37 | .seconds = UINT32_MAX, \ 38 | .fractions = 1000 \ 39 | } 40 | 41 | /* An exclusive bound on the times that the NetworkInterfaceSendStub will be 42 | * invoked before returning a loop terminating value. This is usually defined 43 | * in the Makefile of the harnessed function. */ 44 | #ifndef MAX_NETWORK_SEND_TRIES 45 | #define MAX_NETWORK_SEND_TRIES 2 46 | #endif 47 | 48 | /* An exclusive bound on the times that the NetworkInterfaceReceiveStub will 49 | * return an unbound value. At this value and beyond, the 50 | * NetworkInterfaceReceiveStub will return zero on every call. */ 51 | #ifndef MAX_NETWORK_RECV_TRIES 52 | #define MAX_NETWORK_RECV_TRIES 5 53 | #endif 54 | 55 | static SntpTimestamp_t testTime = TEST_TIMESTAMP; 56 | 57 | int32_t NetworkInterfaceReceiveStub( NetworkContext_t * pNetworkContext, 58 | uint32_t serverAddr, 59 | uint16_t serverPort, 60 | void * pBuffer, 61 | uint16_t bytesToRecv ) 62 | { 63 | __CPROVER_assert( pBuffer != NULL, 64 | "NetworkInterfaceReceiveStub pBuffer is NULL." ); 65 | 66 | __CPROVER_assert( __CPROVER_w_ok( pBuffer, bytesToRecv ), 67 | "NetworkInterfaceReceiveStub pBuffer is not writable up to bytesToRecv." ); 68 | 69 | /* The havoc fills the buffer with unconstrained values. */ 70 | __CPROVER_havoc_object( pBuffer ); 71 | 72 | int32_t bytesOrError; 73 | static size_t tries = 0; 74 | 75 | /* It is a bug for the application defined transport receive function to return 76 | * more than bytesToRecv. */ 77 | __CPROVER_assume( bytesOrError <= ( int32_t ) bytesToRecv ); 78 | 79 | if( tries < ( MAX_NETWORK_RECV_TRIES - 1 ) ) 80 | { 81 | tries++; 82 | } 83 | else 84 | { 85 | tries = 0; 86 | 87 | bytesOrError = SNTP_PACKET_BASE_SIZE; 88 | } 89 | 90 | return bytesOrError; 91 | } 92 | int32_t NetworkInterfaceSendStub( NetworkContext_t * pNetworkContext, 93 | uint32_t serverAddr, 94 | uint16_t serverPort, 95 | const void * pBuffer, 96 | uint16_t bytesToSend ) 97 | { 98 | __CPROVER_assert( pBuffer != NULL, 99 | "NetworkInterfaceSendStub pBuffer is NULL." ); 100 | 101 | __CPROVER_assert( __CPROVER_r_ok( pBuffer, bytesToSend ), 102 | "NetworkInterfaceSendStub pBuffer is not readable up to bytesToSend." ); 103 | 104 | /* The number of tries to send the message before this invocation. */ 105 | static size_t tries = 0; 106 | 107 | int32_t bytesOrError; 108 | 109 | /* It is a bug for the application defined transport send function to return 110 | * more than bytesToSend. */ 111 | __CPROVER_assume( bytesOrError <= ( int32_t ) bytesToSend ); 112 | 113 | /* If the maximum tries are reached, then return a timeout. In the SNTP library 114 | * this stub is wrapped in a loop that will not end until the bytesOrError 115 | * returned is negative. This means we could loop possibly INT32_MAX 116 | * iterations. Looping for INT32_MAX times adds no value to the proof. 117 | * What matters is that the SNTP library can handle all the possible values 118 | * that could be returned. */ 119 | if( tries < ( MAX_NETWORK_SEND_TRIES - 1 ) ) 120 | { 121 | tries++; 122 | } 123 | else 124 | { 125 | tries = 0; 126 | /* This ensures that all the remaining bytes are sent in the last try. */ 127 | bytesOrError = bytesToSend; 128 | } 129 | 130 | return bytesOrError; 131 | } 132 | 133 | SntpStatus_t GenerateClientAuthStub( SntpAuthContext_t * pContext, 134 | const SntpServerInfo_t * pTimeServer, 135 | void * pBuffer, 136 | size_t bufferSize, 137 | uint16_t * pAuthCodeSize ) 138 | { 139 | __CPROVER_assert( pTimeServer != NULL, 140 | "GenerateClientAuthStub Time Server is NULL." ); 141 | 142 | __CPROVER_assert( pBuffer != NULL, 143 | "GenerateClientAuthStub pBuffer is NULL." ); 144 | 145 | SntpStatus_t sntpStatus = SntpSuccess; 146 | 147 | if( bufferSize <= SNTP_PACKET_BASE_SIZE ) 148 | { 149 | sntpStatus = SntpErrorBufferTooSmall; 150 | } 151 | else 152 | { 153 | *pAuthCodeSize = SNTP_PACKET_BASE_SIZE; 154 | } 155 | 156 | return sntpStatus; 157 | } 158 | 159 | SntpStatus_t ValidateServerAuthStub( SntpAuthContext_t * pContext, 160 | const SntpServerInfo_t * pTimeServer, 161 | const void * pResponseData, 162 | uint16_t responseSize ) 163 | { 164 | return SntpSuccess; 165 | } 166 | 167 | bool ResolveDnsFuncStub( const SntpServerInfo_t * pServerAddr, 168 | uint32_t * pIpV4Addr ) 169 | { 170 | __CPROVER_assert( pServerAddr != NULL, 171 | "ResolveDnsFuncStub pServerAddr is NULL." ); 172 | 173 | /* For the proofs, returning a non deterministic boolean value 174 | * will be good enough. */ 175 | return nondet_bool(); 176 | } 177 | 178 | void GetTimeFuncStub( SntpTimestamp_t * pCurrentTime ) 179 | { 180 | __CPROVER_assert( pCurrentTime != NULL, 181 | "GetTimeFuncStub pCurrentTime is NULL." ); 182 | 183 | bool value = nondet_bool(); 184 | 185 | if( value ) 186 | { 187 | testTime.fractions = testTime.fractions + ( uint32_t ) 100000000; 188 | } 189 | else 190 | { 191 | testTime.fractions = testTime.fractions - ( uint32_t ) 1; 192 | } 193 | 194 | *pCurrentTime = testTime; 195 | } 196 | 197 | void SetTimeFuncStub( const SntpServerInfo_t * pTimeServer, 198 | const SntpTimestamp_t * pServerTime, 199 | int64_t clockOffsetMs, 200 | SntpLeapSecondInfo_t leapSecondInfo ) 201 | { 202 | __CPROVER_assert( pTimeServer != NULL, 203 | "SetTimeFuncStub pTimeServer is NULL." ); 204 | 205 | __CPROVER_assert( pServerTime != NULL, 206 | "SetTimeFuncStub pServerTime is NULL." ); 207 | } 208 | 209 | SntpStatus_t Sntp_SerializeRequest( SntpTimestamp_t * pRequestTime, 210 | uint32_t randomNumber, 211 | void * pBuffer, 212 | size_t bufferSize ) 213 | { 214 | __CPROVER_assert( pRequestTime != NULL, 215 | "Sntp_SerializeRequest pRequestTime is NULL." ); 216 | 217 | __CPROVER_assert( pBuffer != NULL, 218 | "Sntp_SerializeRequest pBuffer is NULL." ); 219 | 220 | return SntpSuccess; 221 | } 222 | 223 | SntpStatus_t Sntp_DeserializeResponse( const SntpTimestamp_t * pRequestTime, 224 | const SntpTimestamp_t * pResponseRxTime, 225 | const void * pResponseBuffer, 226 | size_t bufferSize, 227 | SntpResponseData_t * pParsedResponse ) 228 | { 229 | if( nondet_bool() ) 230 | { 231 | return SntpSuccess; 232 | } 233 | else 234 | { 235 | return SntpRejectedResponseRetryWithBackoff; 236 | } 237 | } 238 | -------------------------------------------------------------------------------- /test/unit-test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Include file path configuration for coreSNTP library. 2 | include(${MODULE_ROOT_DIR}/coreSntpFilePaths.cmake) 3 | 4 | project ("coreSNTP unit tests") 5 | cmake_minimum_required (VERSION 3.2.0) 6 | 7 | # ==================== Define your project name ======================== 8 | set(project_name "core_sntp") 9 | 10 | # ===================== Create your mock here ======================== 11 | 12 | # list the files to mock here 13 | list(APPEND mock_list 14 | "${MODULE_ROOT_DIR}/source/include/core_sntp_serializer.h" 15 | ) 16 | 17 | # list the directories your mocks need 18 | list(APPEND mock_include_list 19 | ${CORE_SNTP_INCLUDE_PUBLIC_DIRS} 20 | ) 21 | #list the definitions of your mocks to control what to be included 22 | list(APPEND mock_define_list 23 | "" 24 | ) 25 | 26 | # ================= Create the library under test here ================== 27 | 28 | # list the files you would like to test here 29 | list(APPEND real_source_files 30 | ${CORE_SNTP_SOURCES} 31 | ) 32 | 33 | # list the directories the module under test includes 34 | list(APPEND real_include_directories 35 | ${CORE_SNTP_INCLUDE_PUBLIC_DIRS} 36 | ${CMAKE_CURRENT_LIST_DIR} 37 | ) 38 | 39 | # ===================== Create UnitTest Code here ===================== 40 | 41 | # list the directories your test needs to include 42 | list(APPEND test_include_directories 43 | ${CORE_SNTP_INCLUDE_PUBLIC_DIRS} 44 | ${CMAKE_CURRENT_LIST_DIR} 45 | ) 46 | 47 | # ============================= Create unit test targets =================================== 48 | 49 | set(mock_name "${project_name}_mock") 50 | set(real_name "${project_name}_real") 51 | 52 | create_mock_list(${mock_name} 53 | "${mock_list}" 54 | "${MODULE_ROOT_DIR}/tools/cmock/project.yml" 55 | "${mock_include_list}" 56 | "${mock_define_list}" 57 | ) 58 | 59 | create_real_library(${real_name} 60 | "${real_source_files}" 61 | "${real_include_directories}" 62 | "${mock_name}" 63 | ) 64 | 65 | # As both Mock and Real libraries targets contain the 66 | # symbols for the core_sntp_serializer.c file, the linking 67 | # order has the mock library first for the core_sntp_client_utest.c 68 | # to use the mock for Serializer API calls. 69 | list(APPEND utest_link_list 70 | -l${mock_name} 71 | lib${real_name}.a 72 | ) 73 | 74 | list(APPEND utest_dep_list 75 | ${real_name} 76 | ) 77 | 78 | # core_sntp_client_utest target 79 | set(utest_name "${project_name}_client_utest") 80 | set(utest_source "${project_name}_client_utest.c") 81 | create_test(${utest_name} 82 | ${utest_source} 83 | "${utest_link_list}" 84 | "${utest_dep_list}" 85 | "${test_include_directories}" 86 | ) 87 | 88 | # Redefine the linking list as the mock is not needed for 89 | # the core_sntp_serializer tests. 90 | set(utest_link_list "") 91 | list(APPEND utest_link_list 92 | lib${real_name}.a 93 | ) 94 | 95 | # core_sntp_serializer_utest target 96 | set(utest_name "${project_name}_serializer_utest") 97 | set(utest_source "${project_name}_serializer_utest.c") 98 | create_test(${utest_name} 99 | ${utest_source} 100 | "${utest_link_list}" 101 | "${utest_dep_list}" 102 | "${test_include_directories}" 103 | ) 104 | -------------------------------------------------------------------------------- /test/unit-test/cmock_build.cmake: -------------------------------------------------------------------------------- 1 | # Macro utility to clone the CMock submodule. 2 | macro( clone_cmock ) 3 | find_package( Git REQUIRED ) 4 | message( "Cloning submodule CMock." ) 5 | execute_process( COMMAND rm -rf ${CMOCK_DIR} 6 | COMMAND ${GIT_EXECUTABLE} submodule update --checkout --init --recursive ${CMOCK_DIR} 7 | WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} 8 | RESULT_VARIABLE CMOCK_CLONE_RESULT ) 9 | 10 | if( NOT ${CMOCK_CLONE_RESULT} STREQUAL "0" ) 11 | message( FATAL_ERROR "Failed to clone CMock submodule." ) 12 | endif() 13 | endmacro() 14 | 15 | # Macro utility to add library targets for Unity and CMock to build configuration. 16 | macro( add_cmock_targets ) 17 | # Build Configuration for CMock and Unity libraries. 18 | list( APPEND CMOCK_INCLUDE_DIRS 19 | "${CMOCK_DIR}/vendor/unity/src/" 20 | "${CMOCK_DIR}/vendor/unity/extras/fixture/src" 21 | "${CMOCK_DIR}/vendor/unity/extras/memory/src" 22 | "${CMOCK_DIR}/src" 23 | ) 24 | 25 | add_library(cmock STATIC 26 | "${CMOCK_DIR}/src/cmock.c" 27 | ) 28 | 29 | set_target_properties(cmock PROPERTIES 30 | ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib 31 | POSITION_INDEPENDENT_CODE ON 32 | COMPILE_FLAGS "-Og" 33 | ) 34 | 35 | target_include_directories(cmock PUBLIC 36 | ${CMOCK_DIR}/src 37 | ${CMOCK_DIR}/vendor/unity/src/ 38 | ${CMOCK_DIR}/examples 39 | ${CMOCK_INCLUDE_DIRS} 40 | ) 41 | 42 | add_library(unity STATIC 43 | "${CMOCK_DIR}/vendor/unity/src/unity.c" 44 | "${CMOCK_DIR}/vendor/unity/extras/fixture/src/unity_fixture.c" 45 | "${CMOCK_DIR}/vendor/unity/extras/memory/src/unity_memory.c" 46 | ) 47 | 48 | set_target_properties(unity PROPERTIES 49 | ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib 50 | POSITION_INDEPENDENT_CODE ON 51 | ) 52 | 53 | target_include_directories(unity PUBLIC 54 | ${CMOCK_INCLUDE_DIRS} 55 | ) 56 | 57 | target_link_libraries(cmock unity) 58 | endmacro() 59 | -------------------------------------------------------------------------------- /test/unit-test/core_sntp_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * coreSNTP v1.3.1 3 | * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * SPDX-License-Identifier: MIT 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | * this software and associated documentation files (the "Software"), to deal in 9 | * the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 | * the Software, and to permit persons to whom the Software is furnished to do so, 12 | * subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 19 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 21 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @file core_sntp_config.h 27 | * @brief This header sets configuration macros for the SNTP library. 28 | */ 29 | #ifndef CORE_SNTP_CONFIG_H_ 30 | #define CORE_SNTP_CONFIG_H_ 31 | 32 | /* Standard include. */ 33 | #include 34 | 35 | /* @[code_example_loggingmacros] */ 36 | /************* Define Logging Macros using printf function ***********/ 37 | 38 | #define PrintfError( ... ) printf( "Error: "__VA_ARGS__ ); printf( "\n" ) 39 | #define PrintfWarn( ... ) printf( "Warn: "__VA_ARGS__ ); printf( "\n" ) 40 | #define PrintfInfo( ... ) printf( "Info: " __VA_ARGS__ ); printf( "\n" ) 41 | #define PrintfDebug( ... ) printf( "Debug: " __VA_ARGS__ ); printf( "\n" ) 42 | 43 | #ifdef LOGGING_LEVEL_ERROR 44 | #define LogError( message ) PrintfError message 45 | #elif defined( LOGGING_LEVEL_WARNING ) 46 | #define LogError( message ) PrintfError message 47 | #define LogWarn( message ) PrintfWarn message 48 | #elif defined( LOGGING_LEVEL_INFO ) 49 | #define LogError( message ) PrintfError message 50 | #define LogWarn( message ) PrintfWarn message 51 | #define LogInfo( message ) PrintfInfo message 52 | #elif defined( LOGGING_LEVEL_DEBUG ) 53 | #define LogError( message ) PrintfError message 54 | #define LogWarn( message ) PrintfWarn message 55 | #define LogInfo( message ) PrintfInfo message 56 | #define LogDebug( message ) PrintfDebug message 57 | #endif /* ifdef LOGGING_LEVEL_ERROR */ 58 | 59 | /**************************************************/ 60 | /* @[code_example_loggingmacros] */ 61 | 62 | #endif /* ifndef CORE_SNTP_CONFIG_H_ */ 63 | -------------------------------------------------------------------------------- /test/unit-test/unity_build.cmake: -------------------------------------------------------------------------------- 1 | # Macro utility to clone the Unity submodule. 2 | macro( clone_unity ) 3 | find_package( Git REQUIRED ) 4 | message( "Cloning submodule Unity." ) 5 | execute_process( COMMAND rm -rf ${UNITY_DIR} 6 | COMMAND ${GIT_EXECUTABLE} submodule update --checkout --init --recursive ${UNITY_DIR} 7 | WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} 8 | RESULT_VARIABLE UNITY_CLONE_RESULT ) 9 | 10 | if( NOT ${UNITY_CLONE_RESULT} STREQUAL "0" ) 11 | message( FATAL_ERROR "Failed to clone Unity submodule." ) 12 | endif() 13 | endmacro() 14 | 15 | # Macro utility to add library targets for Unity and Unity to build configuration. 16 | macro( add_unity_targets ) 17 | # Build Configuration for Unity and Unity libraries. 18 | list( APPEND UNITY_INCLUDE_DIRS 19 | "${UNITY_DIR}/src/" 20 | "${UNITY_DIR}/extras/fixture/src" 21 | "${UNITY_DIR}/extras/memory/src" 22 | ) 23 | 24 | add_library( unity STATIC 25 | "${UNITY_DIR}/src/unity.c" 26 | "${UNITY_DIR}/extras/fixture/src/unity_fixture.c" 27 | "${UNITY_DIR}/extras/memory/src/unity_memory.c" 28 | ) 29 | 30 | set_target_properties( unity PROPERTIES 31 | ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib 32 | POSITION_INDEPENDENT_CODE ON 33 | ) 34 | 35 | target_include_directories( unity PUBLIC 36 | ${UNITY_INCLUDE_DIRS} 37 | ) 38 | endmacro() 39 | -------------------------------------------------------------------------------- /tools/cmock/coverage.cmake: -------------------------------------------------------------------------------- 1 | # Taken from amazon-freertos repository 2 | cmake_minimum_required(VERSION 3.13) 3 | set(BINARY_DIR ${CMAKE_BINARY_DIR}) 4 | # reset coverage counters 5 | execute_process( 6 | COMMAND lcov --directory ${CMAKE_BINARY_DIR} 7 | --base-directory ${CMAKE_BINARY_DIR} 8 | --zerocounters 9 | 10 | COMMAND mkdir -p ${CMAKE_BINARY_DIR}/coverage 11 | ) 12 | # make the initial/baseline capture a zeroed out files 13 | execute_process( COMMAND lcov --directory ${CMAKE_BINARY_DIR} 14 | --base-directory ${CMAKE_BINARY_DIR} 15 | --initial 16 | --capture 17 | --rc branch_coverage=1 18 | --rc genhtml_branch_coverage=1 19 | --output-file=${CMAKE_BINARY_DIR}/base_coverage.info 20 | --include "*source*" 21 | ) 22 | file(GLOB files "${CMAKE_BINARY_DIR}/bin/tests/*") 23 | 24 | set(REPORT_FILE ${CMAKE_BINARY_DIR}/utest_report.txt) 25 | file(WRITE ${REPORT_FILE} "") 26 | # execute all files in bin directory, gathering the output to show it in CI 27 | foreach(testname ${files}) 28 | get_filename_component(test 29 | ${testname} 30 | NAME_WLE 31 | ) 32 | message("Running ${testname}") 33 | execute_process(COMMAND ${testname} OUTPUT_FILE ${CMAKE_BINARY_DIR}/${test}_out.txt) 34 | 35 | file(READ ${CMAKE_BINARY_DIR}/${test}_out.txt CONTENTS) 36 | file(APPEND ${REPORT_FILE} "${CONTENTS}") 37 | endforeach() 38 | 39 | # generate Junit style xml output 40 | execute_process(COMMAND ruby 41 | ${UNITY_DIR}/auto/parse_output.rb 42 | -xml ${REPORT_FILE} 43 | WORKING_DIRECTORY ${CMAKE_BINARY_DIR} 44 | ) 45 | 46 | # capture data after running the tests 47 | execute_process( 48 | COMMAND lcov --capture 49 | --rc branch_coverage=1 50 | --rc genhtml_branch_coverage=1 51 | --base-directory ${CMAKE_BINARY_DIR} 52 | --directory ${CMAKE_BINARY_DIR} 53 | --output-file ${CMAKE_BINARY_DIR}/second_coverage.info 54 | --include "*source*" 55 | ) 56 | 57 | # combile baseline results (zeros) with the one after running the tests 58 | execute_process( 59 | COMMAND lcov --base-directory ${CMAKE_BINARY_DIR} 60 | --directory ${CMAKE_BINARY_DIR} 61 | --add-tracefile ${CMAKE_BINARY_DIR}/base_coverage.info 62 | --add-tracefile ${CMAKE_BINARY_DIR}/second_coverage.info 63 | --output-file ${CMAKE_BINARY_DIR}/coverage.info 64 | --no-external 65 | --rc branch_coverage=1 66 | ) 67 | execute_process( 68 | COMMAND genhtml --rc branch_coverage=1 69 | --branch-coverage 70 | --output-directory ${CMAKE_BINARY_DIR}/coverage 71 | ${CMAKE_BINARY_DIR}/coverage.info 72 | ) 73 | -------------------------------------------------------------------------------- /tools/cmock/create_test.cmake: -------------------------------------------------------------------------------- 1 | # Taken from amazon-freertos repository 2 | 3 | #function to create the test executable 4 | function(create_test test_name 5 | test_src 6 | link_list 7 | dep_list 8 | include_list) 9 | set(mocks_dir "${CMAKE_CURRENT_BINARY_DIR}/mocks") 10 | include (CTest) 11 | get_filename_component(test_src_absolute ${test_src} ABSOLUTE) 12 | add_custom_command(OUTPUT ${test_name}_runner.c 13 | COMMAND ruby 14 | ${CMOCK_DIR}/vendor/unity/auto/generate_test_runner.rb 15 | ${MODULE_ROOT_DIR}/tools/cmock/project.yml 16 | ${test_src_absolute} 17 | ${test_name}_runner.c 18 | DEPENDS ${test_src} 19 | ) 20 | add_executable(${test_name} ${test_src} ${test_name}_runner.c) 21 | set_target_properties(${test_name} PROPERTIES 22 | COMPILE_FLAG "-O0 -ggdb" 23 | RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/tests" 24 | INSTALL_RPATH_USE_LINK_PATH TRUE 25 | LINK_FLAGS " \ 26 | -Wl,-rpath,${CMAKE_BINARY_DIR}/lib \ 27 | -Wl,-rpath,${CMAKE_CURRENT_BINARY_DIR}/lib" 28 | ) 29 | target_include_directories(${test_name} PUBLIC 30 | ${mocks_dir} 31 | ${include_list} 32 | ) 33 | 34 | target_link_directories(${test_name} PUBLIC 35 | ${CMAKE_CURRENT_BINARY_DIR} 36 | ) 37 | 38 | # link all libraries sent through parameters 39 | foreach(link IN LISTS link_list) 40 | target_link_libraries(${test_name} ${link}) 41 | endforeach() 42 | 43 | # add dependency to all the dep_list parameter 44 | foreach(dependency IN LISTS dep_list) 45 | add_dependencies(${test_name} ${dependency}) 46 | target_link_libraries(${test_name} ${dependency}) 47 | endforeach() 48 | target_link_libraries(${test_name} -lgcov unity) 49 | target_link_directories(${test_name} PUBLIC 50 | ${CMAKE_CURRENT_BINARY_DIR}/lib 51 | ) 52 | add_test(NAME ${test_name} 53 | COMMAND ${CMAKE_BINARY_DIR}/bin/tests/${test_name} 54 | WORKING_DIRECTORY ${CMAKE_BINARY_DIR} 55 | ) 56 | endfunction() 57 | 58 | # Run the C preprocessor on target files. 59 | # Takes a CMAKE list of arguments to pass to the C compiler 60 | function(preprocess_mock_list mock_name file_list compiler_args) 61 | set_property(GLOBAL PROPERTY ${mock_name}_processed TRUE) 62 | foreach (target_file IN LISTS file_list) 63 | # Has to be TARGET ALL so the file is pre-processed before CMOCK 64 | # is executed on the file. 65 | add_custom_command(OUTPUT ${target_file}.backup 66 | COMMAND scp ${target_file} ${target_file}.backup 67 | VERBATIM COMMAND ${CMAKE_C_COMPILER} -E ${compiler_args} ${target_file} > ${target_file}.out 68 | ) 69 | add_custom_target(pre_${mock_name} 70 | COMMAND mv ${target_file}.out ${target_file} 71 | DEPENDS ${target_file}.backup 72 | ) 73 | endforeach() 74 | 75 | # Clean up temporary files that were created. 76 | # First we test to see if the backup file still exists. If it does we revert 77 | # the change made to the original file. 78 | foreach (target_file IN LISTS file_list) 79 | add_custom_command(TARGET ${mock_name} 80 | POST_BUILD 81 | COMMAND test ! -e ${target_file}.backup || mv ${target_file}.backup ${target_file} 82 | ) 83 | endforeach() 84 | endfunction() 85 | 86 | # Generates a mock library based on a module's header file 87 | # places the generated source file in the build directory 88 | # @param mock_name: name of the target name 89 | # @param mock_list list of header files to mock 90 | # @param cmock_config configuration file of the cmock framework 91 | # @param mock_include_list include list for the target 92 | # @param mock_define_list special definitions to control compilation 93 | function(create_mock_list mock_name 94 | mock_list 95 | cmock_config 96 | mock_include_list 97 | mock_define_list) 98 | set(mocks_dir "${CMAKE_CURRENT_BINARY_DIR}/mocks") 99 | add_library(${mock_name} SHARED) 100 | foreach (mock_file IN LISTS mock_list) 101 | get_filename_component(mock_file_abs 102 | ${mock_file} 103 | ABSOLUTE 104 | ) 105 | get_filename_component(mock_file_name 106 | ${mock_file} 107 | NAME_WLE 108 | ) 109 | get_filename_component(mock_file_dir 110 | ${mock_file} 111 | DIRECTORY 112 | ) 113 | add_custom_command ( 114 | OUTPUT ${mocks_dir}/mock_${mock_file_name}.c 115 | COMMAND ruby 116 | ${CMOCK_DIR}/lib/cmock.rb 117 | -o${cmock_config} ${mock_file_abs} 118 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 119 | ) 120 | target_sources(${mock_name} PUBLIC 121 | ${mocks_dir}/mock_${mock_file_name}.c 122 | ) 123 | 124 | target_include_directories(${mock_name} PUBLIC 125 | ${mock_file_dir} 126 | ) 127 | endforeach() 128 | target_include_directories(${mock_name} PUBLIC 129 | ${mocks_dir} 130 | ${mock_include_list} 131 | ) 132 | set_target_properties(${mock_name} PROPERTIES 133 | LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib 134 | POSITION_INDEPENDENT_CODE ON 135 | ) 136 | target_compile_definitions(${mock_name} PUBLIC 137 | ${mock_define_list} 138 | ) 139 | target_link_libraries(${mock_name} cmock unity) 140 | endfunction() 141 | 142 | 143 | function(create_real_library target 144 | src_file 145 | real_include_list 146 | mock_name) 147 | add_library(${target} STATIC 148 | ${src_file} 149 | ) 150 | target_include_directories(${target} PUBLIC 151 | ${real_include_list} 152 | ) 153 | set_target_properties(${target} PROPERTIES 154 | COMPILE_FLAGS "-Wextra -Wpedantic \ 155 | -fprofile-arcs -ftest-coverage -fprofile-generate \ 156 | -Wno-unused-but-set-variable" 157 | LINK_FLAGS "-fprofile-arcs -ftest-coverage \ 158 | -fprofile-generate " 159 | ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib 160 | ) 161 | if(NOT(mock_name STREQUAL "")) 162 | add_dependencies(${target} ${mock_name}) 163 | target_link_libraries(${target} 164 | -l${mock_name} 165 | -lgcov 166 | ) 167 | endif() 168 | endfunction() 169 | -------------------------------------------------------------------------------- /tools/cmock/project.yml: -------------------------------------------------------------------------------- 1 | # Taken from amazon-freertos repository 2 | :cmock: 3 | :mock_prefix: mock_ 4 | :when_no_prototypes: :warn 5 | :enforce_strict_ordering: TRUE 6 | :plugins: 7 | - :ignore 8 | - :ignore_arg 9 | - :expect_any_args 10 | - :array 11 | - :callback 12 | - :return_thru_ptr 13 | :callback_include_count: true # include a count arg when calling the callback 14 | :callback_after_arg_check: false # check arguments before calling the callback 15 | :treat_as: 16 | uint8: HEX8 17 | uint16: HEX16 18 | uint32: UINT32 19 | int8: INT8 20 | bool: UINT8 21 | :includes: # This will add these includes to each mock. 22 | - 23 | - 24 | :treat_externs: :exclude # Now the extern-ed functions will be mocked. 25 | :weak: __attribute__((weak)) 26 | :treat_externs: :include 27 | -------------------------------------------------------------------------------- /tools/coverity/README.md: -------------------------------------------------------------------------------- 1 | # Static code analysis for coreSNTP Library 2 | This directory is made for the purpose of statically testing the MISRA C:2012 compliance of coreSNTP Library using 3 | [Synopsys Coverity](https://www.synopsys.com/software-integrity/security-testing/static-analysis-sast.html) static analysis tool. 4 | To that end, this directory provides a [configuration file](https://github.com/FreeRTOS/coreSNTP/blob/main/tools/coverity/misra.config) to use when 5 | building a binary for the tool to analyze. 6 | 7 | > **Note** 8 | For generating the report as outlined below, we have used Coverity version 2018.09. 9 | 10 | For details regarding the suppressed violations in the report (which can be generated using the instructions described below), please 11 | see the [MISRA.md](https://github.com/FreeRTOS/coreSNTP/blob/main/MISRA.md) file. 12 | 13 | ## Getting Started 14 | ### Prerequisites 15 | You can run this on a platform supported by Coverity. The list and other details can be found [here](https://documentation.blackduck.com/bundle/coverity-docs/page/deploy-install-guide/topics/supported_platforms_for_coverity_analysis.html). 16 | To compile and run the Coverity target successfully, you must have the following: 17 | 18 | 1. CMake version > 3.13.0 (You can check whether you have this by typing `cmake --version`) 19 | 2. GCC compiler 20 | - You can see the downloading and installation instructions [here](https://gcc.gnu.org/install/). 21 | 3. Download the repo and include the submodules using the following commands. 22 | - `git clone --recurse-submodules git@github.com:FreeRTOS/coreSNTP.git ./coreSNTP` 23 | - `cd ./coreSNTP` 24 | - `git submodule update --checkout --init --recursive` 25 | 26 | ### To build and run coverity: 27 | Go to the root directory of the library and run the following commands in terminal: 28 | 1. Update the compiler configuration in Coverity 29 | ~~~ 30 | cov-configure --force --compiler cc --comptype gcc 31 | ~~~ 32 | 2. Create the build files using CMake in a `build` directory 33 | ~~~ 34 | cmake -B build -S test 35 | ~~~ 36 | 3. Go to the build directory and copy the coverity configuration file 37 | ~~~ 38 | cd build/ 39 | ~~~ 40 | 4. Build the static analysis target 41 | ~~~ 42 | cov-build --emit-complementary-info --dir cov-out make coverity_analysis 43 | ~~~ 44 | 5. Go to the Coverity output directory (`cov-out`) and begin Coverity static analysis 45 | ~~~ 46 | cd cov-out/ 47 | cov-analyze --dir . --coding-standard-config ../../tools/coverity/misra.config --tu-pattern "file('.*/source/.*')" 48 | ~~~ 49 | 6. Format the errors in HTML format so that it is more readable while removing the test and build directory from the report 50 | ~~~ 51 | cov-format-errors --dir . --file "source" --exclude-files '(/build/|/test/)' --html-output html-out; 52 | ~~~ 53 | 7. Format the errors in JSON format to perform a jq query to get a simplified list of any exceptions. 54 | NOTE: A blank output means there are no defects that aren't being suppressed by the config or inline comments. 55 | ~~~ 56 | cov-format-errors --dir . --file "source" --exclude-files '(/build/|/test/)' --json-output-v2 defects.json; 57 | echo -e "\n-------------------------Non-Suppresed Deviations, if any, Listed Below-------------------------\n"; 58 | jq '.issues[] | .events[] | .eventTag ' defects.json | sort | uniq -c | sort -nr; 59 | echo -e "\n-------------------------Non-Suppresed Deviations, if any, Listed Above-------------------------\n"; 60 | ~~~ 61 | 62 | For your convenience the commands above are below to be copy/pasted into a UNIX command friendly terminal. 63 | ~~~ 64 | cov-configure --force --compiler cc --comptype gcc; 65 | cmake -B build -S test; 66 | cd build/; 67 | cov-build --emit-complementary-info --dir cov-out make coverity_analysis; 68 | cd cov-out/ 69 | cov-analyze --dir . --coding-standard-config ../../tools/coverity/misra.config --tu-pattern "file('.*/source/.*')"; 70 | cov-format-errors --dir . --file "source" --exclude-files '(/build/|/test/)' --html-output html-out; 71 | cov-format-errors --dir . --file "source" --exclude-files '(/build/|/test/)' --json-output-v2 defects.json; 72 | echo -e "\n-------------------------Non-Suppresed Deviations, if any, Listed Below-------------------------\n"; 73 | jq '.issues[] | .events[] | .eventTag ' defects.json | sort | uniq -c | sort -nr; 74 | echo -e "\n-------------------------Non-Suppresed Deviations, if any, Listed Above-------------------------\n"; 75 | cd ../../; 76 | ~~~ 77 | 78 | You should now have the HTML formatted violations list in a directory named `build/cov-out/html-output`. 79 | With the current configuration and the provided project, you should not see any deviations. 80 | -------------------------------------------------------------------------------- /tools/coverity/misra.config: -------------------------------------------------------------------------------- 1 | { 2 | "version" : "2.0", 3 | "standard" : "c2012", 4 | "title" : "Coverity MISRA Configuration", 5 | "deviations" : [ 6 | { 7 | "deviation": "Directive 4.9", 8 | "reason": "Allow inclusion of function like macros. Asserts and logging are done using function like macros." 9 | }, 10 | { 11 | "deviation": "Rule 2.4", 12 | "reason": "Allow unused tags. Some compilers warn if types are not tagged." 13 | }, 14 | { 15 | "deviation": "Rule 2.5", 16 | "reason": "Allow unused macros. coreSNTP Library headers define macros intended for the application's use, but are not used by the agent." 17 | }, 18 | { 19 | "deviation": "Rule 3.1", 20 | "reason": "Allow nested comments. Documentation blocks contain comments for example code." 21 | }, 22 | { 23 | "deviation": "Rule 8.7", 24 | "reason": "API functions are not used by library. They must be externally visible in order to be used by the application." 25 | } 26 | ] 27 | } 28 | --------------------------------------------------------------------------------