Submitting patches ================== * Always make a new branch for your work. * Patches should be small to facilitate easier review. `Studies have shown`_ that review quality falls off as patch size grows. Sometimes this will result in many small PRs to land a single large feature. * Larger changes should be discussed on `our mailing list`_ before submission. * New features and significant bug fixes should be documented in the :doc:`/changelog`. If you believe you've identified a security issue in ``cryptography``, please follow the directions on the :doc:`security page `. Code ---- When in doubt, refer to :pep:`8` for Python code. You can check if your code meets our automated requirements by running ``flake8`` against it. If you've installed the development requirements this will automatically use our configuration. You can also run the ``tox`` job with ``tox -e pep8``. `Write comments as complete sentences.`_ Every code file must start with the boilerplate notice of the Apache License. Additionally, every Python code file must contain .. code-block:: python from __future__ import absolute_import, division, print_function API considerations ~~~~~~~~~~~~~~~~~~ Most projects' APIs are designed with a philosophy of "make easy things easy, and make hard things possible". One of the perils of writing cryptographic code is that secure code looks just like insecure code, and its results are almost always indistinguishable. As a result ``cryptography`` has, as a design philosophy: "make it hard to do insecure things". Here are a few strategies for API design that should be both followed, and should inspire other API choices: If it is necessary to compare a user provided value with a computed value (for example, verifying a signature), there should be an API provided that performs the verification in a secure way (for example, using a constant time comparison), rather than requiring the user to perform the comparison themselves. If it is incorrect to ignore the result of a method, it should raise an exception, and not return a boolean ``True``/``False`` flag. For example, a method to verify a signature should raise ``InvalidSignature``, and not return whether the signature was valid. .. code-block:: python # This is bad. def verify(sig): # ... return is_valid # Good! def verify(sig): # ... if not is_valid: raise InvalidSignature Every recipe should include a version or algorithmic marker of some sort in its output in order to allow transparent upgrading of the algorithms in use, as the algorithms or parameters needed to achieve a given security margin evolve. APIs at the :doc:`/hazmat/primitives/index` layer should always take an explicit backend, APIs at the recipes layer should automatically use the :func:`~cryptography.hazmat.backends.default_backend`, but optionally allow specifying a different backend. C bindings ~~~~~~~~~~ When binding C code with ``cffi`` we have our own style guide, it's pretty simple. Don't name parameters: .. code-block:: c // Good long f(long); // Bad long f(long x); ...unless they're inside a struct: .. code-block:: c struct my_struct { char *name; int number; ...; }; Include ``void`` if the function takes no arguments: .. code-block:: c // Good long f(void); // Bad long f(); Wrap lines at 80 characters like so: .. code-block:: c // Pretend this went to 80 characters long f(long, long, int *) Include a space after commas between parameters: .. code-block:: c // Good long f(int, char *) // Bad long f(int,char *) Values set by ``#define`` should be assigned the appropriate type. If you see this: .. code-block:: c #define SOME_INTEGER_LITERAL 0x0; #define SOME_UNSIGNED_INTEGER_LITERAL 0x0001U; #define SOME_STRING_LITERAL "hello"; ...it should be added to the bindings like so: .. code-block:: c static const int SOME_INTEGER_LITERAL; static const unsigned int SOME_UNSIGNED_INTEGER_LITERAL; static const char *const SOME_STRING_LITERAL; Tests ----- All code changes must be accompanied by unit tests with 100% code coverage (as measured by the combined metrics across our build matrix). When implementing a new primitive or recipe ``cryptography`` requires that you provide a set of test vectors. See :doc:`/development/test-vectors` for more details. Documentation ------------- All features should be documented with prose in the ``docs`` section. To ensure it builds and passes `doc8`_ style checks you can run ``tox -e docs``. Because of the inherent challenges in implementing correct cryptographic systems, we want to make our documentation point people in the right directions as much as possible. To that end: * When documenting a generic interface, use a strong algorithm in examples. (e.g. when showing a hashing example, don't use :class:`~cryptography.hazmat.primitives.hashes.MD5`) * When giving prescriptive advice, always provide references and supporting material. * When there is real disagreement between cryptographic experts, represent both sides of the argument and describe the trade-offs clearly. When documenting a new module in the ``hazmat`` package, its documentation should begin with the "Hazardous Materials" warning: .. code-block:: rest .. hazmat:: When referring to a hypothetical individual (such as "a person receiving an encrypted message") use gender neutral pronouns (they/them/their). Docstrings are typically only used when writing abstract classes, but should be written like this if required: .. code-block:: python def some_function(some_arg): """ Does some things.
/*
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "ch.h"
#include "hal.h"
#include "test.h"
/*
* Blinker thread.
*/
static THD_WORKING_AREA(waThread1, 128);
static THD_FUNCTION(Thread1, arg) {
(void)arg;
chRegSetThreadName("blinker");
while (true) {
palSetPad(GPIOC, GPIOC_LED);
chThdSleepMilliseconds(500);
palClearPad(GPIOC, GPIOC_LED);
chThdSleepMilliseconds(500);
}
}
/*
* Application entry point.
*/
int main(void) {
/*
* System initializations.
* - HAL initialization, this also initializes the configured device drivers
* and performs the board-specific initializations.
* - Kernel initialization, the main() function becomes a thread and the
* RTOS is active.
*/
halInit();
chSysInit();
/*
* Activates the serial driver 1 using the driver default configuration.
* PA9(TX) and PA10(RX) are routed to USART1.
*/
sdStart(&SD2, NULL);
/*
* Creates the example thread.
*/
chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO+1, Thread1, NULL);
/*
* Normal main() thread activity, in this demo it does nothing except
* sleeping in a loop and check the button state, when the button is
* pressed the test procedure is launched.
*/
while (true) {
if (palReadPad(GPIOA, GPIOA_BUTTON))
TestThread(&SD2);
chThdSleepMilliseconds(500);
}
}