Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id A2E4F200B9B for ; Wed, 28 Sep 2016 02:43:55 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id A156C160AE7; Wed, 28 Sep 2016 00:43:55 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 218C9160AD2 for ; Wed, 28 Sep 2016 02:43:52 +0200 (CEST) Received: (qmail 17339 invoked by uid 500); 28 Sep 2016 00:43:52 -0000 Mailing-List: contact commits-help@mynewt.incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@mynewt.incubator.apache.org Delivered-To: mailing list commits@mynewt.incubator.apache.org Received: (qmail 17330 invoked by uid 99); 28 Sep 2016 00:43:52 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd4-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 28 Sep 2016 00:43:52 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd4-us-west.apache.org (ASF Mail Server at spamd4-us-west.apache.org) with ESMTP id BE0D9C0C0F for ; Wed, 28 Sep 2016 00:43:51 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd4-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -4.646 X-Spam-Level: X-Spam-Status: No, score=-4.646 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, KAM_LAZY_DOMAIN_SECURITY=1, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RP_MATCHES_RCVD=-1.426] autolearn=disabled Received: from mx1-lw-eu.apache.org ([10.40.0.8]) by localhost (spamd4-us-west.apache.org [10.40.0.11]) (amavisd-new, port 10024) with ESMTP id 4abMuiTsdqfE for ; Wed, 28 Sep 2016 00:43:35 +0000 (UTC) Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx1-lw-eu.apache.org (ASF Mail Server at mx1-lw-eu.apache.org) with SMTP id 94B9360E28 for ; Wed, 28 Sep 2016 00:43:29 +0000 (UTC) Received: (qmail 14547 invoked by uid 99); 28 Sep 2016 00:43:28 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 28 Sep 2016 00:43:28 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 20F1CEEF4B; Wed, 28 Sep 2016 00:43:28 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: sterling@apache.org To: commits@mynewt.incubator.apache.org Date: Wed, 28 Sep 2016 00:43:39 -0000 Message-Id: <77a1960269b942d78a859132aef8e63b@git.apache.org> In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [13/51] [abbrv] [partial] incubator-mynewt-core git commit: directory re-org, part 1 archived-at: Wed, 28 Sep 2016 00:43:55 -0000 http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0216c73e/crypto/tinycrypt/src/ecc.c ---------------------------------------------------------------------- diff --git a/crypto/tinycrypt/src/ecc.c b/crypto/tinycrypt/src/ecc.c new file mode 100644 index 0000000..357139b --- /dev/null +++ b/crypto/tinycrypt/src/ecc.c @@ -0,0 +1,604 @@ +/* ecc.c - TinyCrypt implementation of ECC auxiliary functions */ + +/* + * + * Copyright (c) 2013, Kenneth MacKay + * All rights reserved. + * https://github.com/kmackay/micro-ecc + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Copyright (C) 2015 by Intel Corporation, All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +/* ------ Curve NIST P-256 constants: ------ */ + +#define Curve_P {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, \ + 0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF} + +#define Curve_B {0x27D2604B, 0x3BCE3C3E, 0xCC53B0F6, 0x651D06B0, \ + 0x769886BC, 0xB3EBBD55, 0xAA3A93E7, 0x5AC635D8} + +#define Curve_N {0xFC632551, 0xF3B9CAC2, 0xA7179E84, 0xBCE6FAAD, \ + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF} + +#define Curve_G {{0xD898C296, 0xF4A13945, 0x2DEB33A0, 0x77037D81, \ + 0x63A440F2, 0xF8BCE6E5, 0xE12C4247, 0x6B17D1F2}, \ + {0x37BF51F5, 0xCBB64068, 0x6B315ECE, 0x2BCE3357, \ + 0x7C0F9E16, 0x8EE7EB4A, 0xFE1A7F9B, 0x4FE342E2} } + +#define Curve_P_Barrett {0x00000003, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFE, \ + 0xFFFFFFFE, 0xFFFFFFFE, 0xFFFFFFFF, 0x00000000, 0x00000001} + +#define Curve_N_Barrett {0xEEDF9BFE, 0x012FFD85, 0xDF1A6C21, 0x43190552, \ + 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x00000000, 0x00000001} + +uint32_t curve_p[NUM_ECC_DIGITS] = Curve_P; +uint32_t curve_b[NUM_ECC_DIGITS] = Curve_B; +EccPoint curve_G = Curve_G; +uint32_t curve_n[NUM_ECC_DIGITS] = Curve_N; +uint32_t curve_pb[NUM_ECC_DIGITS + 1] = Curve_P_Barrett; +uint32_t curve_nb[NUM_ECC_DIGITS + 1] = Curve_N_Barrett; + +/* ------ Static functions: ------ */ + +/* Zeroing out p_vli. */ +static void vli_clear(uint32_t *p_vli) +{ + uint32_t i; + + for (i = 0; i < NUM_ECC_DIGITS; ++i) { + p_vli[i] = 0; + } +} + +/* Returns nonzero if bit p_bit of p_vli is set. */ +static uint32_t vli_testBit(uint32_t *p_vli, uint32_t p_bit) +{ + return (p_vli[p_bit / 32] & (1 << (p_bit % 32))); +} + +uint32_t vli_isZero(uint32_t *p_vli) +{ + uint32_t acc = 0; + + for (uint32_t i = 0; i < NUM_ECC_DIGITS; ++i) { + acc |= p_vli[i]; + } + + return (!acc); +} + +/* + * Find the right-most nonzero 32-bit "digits" in p_vli. + * + * Side-channel countermeasure: algorithm strengthened against timing attack. + */ +static uint32_t vli_numDigits(uint32_t *p_vli) +{ + int32_t i; + uint32_t digits = 0; + + for (i = NUM_ECC_DIGITS - 1; i >= 0 ; --i) { + digits += p_vli[i] || digits; + } + + return digits; +} + +/* + * Find the left-most non-zero bit in p_vli. + * + * Side-channel countermeasure: algorithm strengthened against timing attack. + */ +static uint32_t vli_numBits(uint32_t *p_vli) +{ + uint32_t l_digit; + uint32_t i, acc = 32; + uint32_t l_numDigits = vli_numDigits(p_vli); + + l_digit = p_vli[l_numDigits - 1]; + + for (i = 0; i < 32; ++i) { + acc -= !l_digit; + l_digit >>= 1; + } + + return ((l_numDigits - 1) * 32 + acc); +} + +/* + * Computes p_result = p_left + p_right, returns carry. + * + * Side-channel countermeasure: algorithm strengthened against timing attack. + */ +static uint32_t vli_add(uint32_t *p_result, uint32_t *p_left, + uint32_t *p_right) +{ + + uint32_t l_carry = 0; + + for (uint32_t i = 0; i < NUM_ECC_DIGITS; ++i) { + uint32_t l_sum = p_left[i] + p_right[i] + l_carry; + + l_carry = (l_sum < p_left[i]) | ((l_sum == p_left[i]) && l_carry); + p_result[i] = l_sum; + } + + return l_carry; +} + + +/* Computes p_result = p_left * p_right. */ +static void vli_mult(uint32_t *p_result, uint32_t *p_left, + uint32_t *p_right, uint32_t word_size) +{ + + uint64_t r01 = 0; + uint32_t r2 = 0; + + /* Compute each digit of p_result in sequence, maintaining the carries. */ + for (uint32_t k = 0; k < word_size*2 - 1; ++k) { + + uint32_t l_min = (k < word_size ? 0 : (k + 1) - word_size); + + for (uint32_t i = l_min; i <= k && i < word_size; ++i) { + + uint64_t l_product = (uint64_t)p_left[i] * p_right[k - i]; + + r01 += l_product; + r2 += (r01 < l_product); + } + p_result[k] = (uint32_t)r01; + r01 = (r01 >> 32) | (((uint64_t)r2) << 32); + r2 = 0; + } + + p_result[word_size * 2 - 1] = (uint32_t)r01; +} + +/* Computes p_result = p_left^2. */ +static void vli_square(uint32_t *p_result, uint32_t *p_left) +{ + + uint64_t r01 = 0; + uint32_t r2 = 0; + uint32_t i, k; + + for (k = 0; k < NUM_ECC_DIGITS * 2 - 1; ++k) { + + uint32_t l_min = (k < NUM_ECC_DIGITS ? 0 : (k + 1) - NUM_ECC_DIGITS); + + for (i = l_min; i <= k && i <= k - i; ++i) { + + uint64_t l_product = (uint64_t)p_left[i] * p_left[k - i]; + + if (i < k - i) { + + r2 += l_product >> 63; + l_product *= 2; + } + r01 += l_product; + r2 += (r01 < l_product); + } + p_result[k] = (uint32_t)r01; + r01 = (r01 >> 32) | (((uint64_t)r2) << 32); + r2 = 0; + } + + p_result[NUM_ECC_DIGITS * 2 - 1] = (uint32_t)r01; +} + +/* Computes p_result = p_product % curve_p using Barrett reduction. */ +static void vli_mmod_barrett(uint32_t *p_result, uint32_t *p_product, + uint32_t *p_mod, uint32_t *p_barrett) +{ + uint32_t i; + uint32_t q1[NUM_ECC_DIGITS + 1]; + + for (i = NUM_ECC_DIGITS - 1; i < 2 * NUM_ECC_DIGITS; i++) { + q1[i - (NUM_ECC_DIGITS - 1)] = p_product[i]; + } + + uint32_t q2[2*NUM_ECC_DIGITS + 2]; + + vli_mult(q2, q1, p_barrett, NUM_ECC_DIGITS + 1); + for (i = NUM_ECC_DIGITS + 1; i < 2 * NUM_ECC_DIGITS + 2; i++) { + q1[i - (NUM_ECC_DIGITS + 1)] = q2[i]; + } + + uint32_t prime2[2*NUM_ECC_DIGITS]; + + for (i = 0; i < NUM_ECC_DIGITS; i++) { + prime2[i] = p_mod[i]; + prime2[NUM_ECC_DIGITS + i] = 0; + } + + vli_mult(q2, q1, prime2, NUM_ECC_DIGITS + 1); + vli_sub(p_product, p_product, q2, 2 * NUM_ECC_DIGITS); + + uint32_t borrow; + + borrow = vli_sub(q1, p_product, prime2, NUM_ECC_DIGITS + 1); + vli_cond_set(p_product, p_product, q1, borrow); + p_product[NUM_ECC_DIGITS] = q1[NUM_ECC_DIGITS] * (!borrow); + borrow = vli_sub(q1, p_product, prime2, NUM_ECC_DIGITS + 1); + vli_cond_set(p_product, p_product, q1, borrow); + p_product[NUM_ECC_DIGITS] = q1[NUM_ECC_DIGITS] * (!borrow); + borrow = vli_sub(q1, p_product, prime2, NUM_ECC_DIGITS + 1); + vli_cond_set(p_product, p_product, q1, borrow); + p_product[NUM_ECC_DIGITS] = q1[NUM_ECC_DIGITS] * (!borrow); + + for (i = 0; i < NUM_ECC_DIGITS; i++) { + p_result[i] = p_product[i]; + } +} + +/* + * Computes modular exponentiation. + * + * Side-channel countermeasure: algorithm strengthened against timing attack. + */ +static void vli_modExp(uint32_t *p_result, uint32_t *p_base, + uint32_t *p_exp, uint32_t *p_mod, uint32_t *p_barrett) +{ + + uint32_t acc[NUM_ECC_DIGITS], tmp[NUM_ECC_DIGITS], product[2 * NUM_ECC_DIGITS]; + uint32_t j; + int32_t i; + + vli_clear(acc); + acc[0] = 1; + + for (i = NUM_ECC_DIGITS - 1; i >= 0; i--) { + for (j = 1 << 31; j > 0; j = j >> 1) { + vli_square(product, acc); + vli_mmod_barrett(acc, product, p_mod, p_barrett); + vli_mult(product, acc, p_base, NUM_ECC_DIGITS); + vli_mmod_barrett(tmp, product, p_mod, p_barrett); + vli_cond_set(acc, tmp, acc, j & p_exp[i]); + } + } + + vli_set(p_result, acc); +} + +/* Conversion from Affine coordinates to Jacobi coordinates. */ +static void EccPoint_fromAffine(EccPointJacobi *p_point_jacobi, + EccPoint *p_point) { + + vli_set(p_point_jacobi->X, p_point->x); + vli_set(p_point_jacobi->Y, p_point->y); + vli_clear(p_point_jacobi->Z); + p_point_jacobi->Z[0] = 1; +} + +/* + * Elliptic curve point doubling in Jacobi coordinates: P = P + P. + * + * Requires 4 squares and 4 multiplications. + */ +static void EccPoint_double(EccPointJacobi *P) +{ + + uint32_t m[NUM_ECC_DIGITS], s[NUM_ECC_DIGITS], t[NUM_ECC_DIGITS]; + + vli_modSquare_fast(t, P->Z); + vli_modSub(m, P->X, t, curve_p); + vli_modAdd(s, P->X, t, curve_p); + vli_modMult_fast(m, m, s); + vli_modAdd(s, m, m, curve_p); + vli_modAdd(m, s, m, curve_p); /* m = 3X^2 - 3Z^4 */ + vli_modSquare_fast(t, P->Y); + vli_modMult_fast(s, P->X, t); + vli_modAdd(s, s, s, curve_p); + vli_modAdd(s, s, s, curve_p); /* s = 4XY^2 */ + vli_modMult_fast(P->Z, P->Y, P->Z); + vli_modAdd(P->Z, P->Z, P->Z, curve_p); /* Z' = 2YZ */ + vli_modSquare_fast(P->X, m); + vli_modSub(P->X, P->X, s, curve_p); + vli_modSub(P->X, P->X, s, curve_p); /* X' = m^2 - 2s */ + vli_modSquare_fast(P->Y, t); + vli_modAdd(P->Y, P->Y, P->Y, curve_p); + vli_modAdd(P->Y, P->Y, P->Y, curve_p); + vli_modAdd(P->Y, P->Y, P->Y, curve_p); + vli_modSub(t, s, P->X, curve_p); + vli_modMult_fast(t, t, m); + vli_modSub(P->Y, t, P->Y, curve_p); /* Y' = m(s - X') - 8Y^4 */ + +} + +/* Copy input to target. */ +static void EccPointJacobi_set(EccPointJacobi *target, EccPointJacobi *input) +{ + vli_set(target->X, input->X); + vli_set(target->Y, input->Y); + vli_set(target->Z, input->Z); +} + +/* ------ Externally visible functions (see header file for comments): ------ */ + +void vli_set(uint32_t *p_dest, uint32_t *p_src) +{ + + uint32_t i; + + for (i = 0; i < NUM_ECC_DIGITS; ++i) { + p_dest[i] = p_src[i]; + } +} + +int32_t vli_cmp(uint32_t *p_left, uint32_t *p_right, int32_t word_size) +{ + + int32_t i, cmp = 0; + + for (i = word_size-1; i >= 0; --i) { + cmp |= ((p_left[i] > p_right[i]) - (p_left[i] < p_right[i])) * (!cmp); + } + + return cmp; +} + +uint32_t vli_sub(uint32_t *p_result, uint32_t *p_left, uint32_t *p_right, + uint32_t word_size) +{ + + uint32_t l_borrow = 0; + + for (uint32_t i = 0; i < word_size; ++i) { + uint32_t l_diff = p_left[i] - p_right[i] - l_borrow; + + l_borrow = (l_diff > p_left[i]) | ((l_diff == p_left[i]) && l_borrow); + p_result[i] = l_diff; + } + + return l_borrow; +} + +void vli_cond_set(uint32_t *output, uint32_t *p_true, uint32_t *p_false, + uint32_t cond) +{ + uint32_t i; + + cond = (!cond); + + for (i = 0; i < NUM_ECC_DIGITS; i++) { + output[i] = (p_true[i]*(!cond)) | (p_false[i]*cond); + } +} + +void vli_modAdd(uint32_t *p_result, uint32_t *p_left, uint32_t *p_right, + uint32_t *p_mod) +{ + uint32_t l_carry = vli_add(p_result, p_left, p_right); + uint32_t p_temp[NUM_ECC_DIGITS]; + + l_carry = l_carry == vli_sub(p_temp, p_result, p_mod, NUM_ECC_DIGITS); + vli_cond_set(p_result, p_temp, p_result, l_carry); +} + +void vli_modSub(uint32_t *p_result, uint32_t *p_left, uint32_t *p_right, + uint32_t *p_mod) +{ + uint32_t l_borrow = vli_sub(p_result, p_left, p_right, NUM_ECC_DIGITS); + uint32_t p_temp[NUM_ECC_DIGITS]; + + vli_add(p_temp, p_result, p_mod); + vli_cond_set(p_result, p_temp, p_result, l_borrow); +} + +void vli_modMult_fast(uint32_t *p_result, uint32_t *p_left, + uint32_t *p_right) +{ + uint32_t l_product[2 * NUM_ECC_DIGITS]; + + vli_mult(l_product, p_left, p_right, NUM_ECC_DIGITS); + vli_mmod_barrett(p_result, l_product, curve_p, curve_pb); +} + +void vli_modSquare_fast(uint32_t *p_result, uint32_t *p_left) +{ + uint32_t l_product[2 * NUM_ECC_DIGITS]; + + vli_square(l_product, p_left); + vli_mmod_barrett(p_result, l_product, curve_p, curve_pb); +} + +void vli_modMult(uint32_t *p_result, uint32_t *p_left, uint32_t *p_right, + uint32_t *p_mod, uint32_t *p_barrett) +{ + + uint32_t l_product[2 * NUM_ECC_DIGITS]; + + vli_mult(l_product, p_left, p_right, NUM_ECC_DIGITS); + vli_mmod_barrett(p_result, l_product, p_mod, p_barrett); +} + +void vli_modInv(uint32_t *p_result, uint32_t *p_input, uint32_t *p_mod, + uint32_t *p_barrett) +{ + uint32_t p_power[NUM_ECC_DIGITS]; + + vli_set(p_power, p_mod); + p_power[0] -= 2; + vli_modExp(p_result, p_input, p_power, p_mod, p_barrett); +} + +uint32_t EccPoint_isZero(EccPoint *p_point) +{ + return (vli_isZero(p_point->x) && vli_isZero(p_point->y)); +} + +uint32_t EccPointJacobi_isZero(EccPointJacobi *p_point_jacobi) +{ + return vli_isZero(p_point_jacobi->Z); +} + +void EccPoint_toAffine(EccPoint *p_point, EccPointJacobi *p_point_jacobi) +{ + + if (vli_isZero(p_point_jacobi->Z)) { + vli_clear(p_point->x); + vli_clear(p_point->y); + return; + } + + uint32_t z[NUM_ECC_DIGITS]; + + vli_set(z, p_point_jacobi->Z); + vli_modInv(z, z, curve_p, curve_pb); + vli_modSquare_fast(p_point->x, z); + vli_modMult_fast(p_point->y, p_point->x, z); + vli_modMult_fast(p_point->x, p_point->x, p_point_jacobi->X); + vli_modMult_fast(p_point->y, p_point->y, p_point_jacobi->Y); +} + +void EccPoint_add(EccPointJacobi *P1, EccPointJacobi *P2) +{ + + uint32_t s1[NUM_ECC_DIGITS], u1[NUM_ECC_DIGITS], t[NUM_ECC_DIGITS]; + uint32_t h[NUM_ECC_DIGITS], r[NUM_ECC_DIGITS]; + + vli_modSquare_fast(r, P1->Z); + vli_modSquare_fast(s1, P2->Z); + vli_modMult_fast(u1, P1->X, s1); /* u1 = X1 Z2^2 */ + vli_modMult_fast(h, P2->X, r); + vli_modMult_fast(s1, P1->Y, s1); + vli_modMult_fast(s1, s1, P2->Z); /* s1 = Y1 Z2^3 */ + vli_modMult_fast(r, P2->Y, r); + vli_modMult_fast(r, r, P1->Z); + vli_modSub(h, h, u1, curve_p); /* h = X2 Z1^2 - u1 */ + vli_modSub(r, r, s1, curve_p); /* r = Y2 Z1^3 - s1 */ + + if (vli_isZero(h)) { + if (vli_isZero(r)) { + /* P1 = P2 */ + EccPoint_double(P1); + return; + } + /* point at infinity */ + vli_clear(P1->Z); + return; + } + + vli_modMult_fast(P1->Z, P1->Z, P2->Z); + vli_modMult_fast(P1->Z, P1->Z, h); /* Z3 = h Z1 Z2 */ + vli_modSquare_fast(t, h); + vli_modMult_fast(h, t, h); + vli_modMult_fast(u1, u1, t); + vli_modSquare_fast(P1->X, r); + vli_modSub(P1->X, P1->X, h, curve_p); + vli_modSub(P1->X, P1->X, u1, curve_p); + vli_modSub(P1->X, P1->X, u1, curve_p); /* X3 = r^2 - h^3 - 2 u1 h^2 */ + vli_modMult_fast(t, s1, h); + vli_modSub(P1->Y, u1, P1->X, curve_p); + vli_modMult_fast(P1->Y, P1->Y, r); + vli_modSub(P1->Y, P1->Y, t, curve_p); /* Y3 = r(u1 h^2 - X3) - s1 h^3 */ +} + +/* + * Elliptic curve scalar multiplication with result in Jacobi coordinates: + * + * p_result = p_scalar * p_point. + */ +void EccPoint_mult(EccPointJacobi *p_result, EccPoint *p_point, uint32_t *p_scalar) +{ + + int32_t i; + uint32_t bit; + EccPointJacobi p_point_jacobi, p_tmp; + + EccPoint_fromAffine(p_result, p_point); + EccPoint_fromAffine(&p_point_jacobi, p_point); + + for (i = vli_numBits(p_scalar) - 2; i >= 0; i--) { + EccPoint_double(p_result); + EccPointJacobi_set(&p_tmp, p_result); + EccPoint_add(&p_tmp, &p_point_jacobi); + bit = vli_testBit(p_scalar, i); + vli_cond_set(p_result->X, p_tmp.X, p_result->X, bit); + vli_cond_set(p_result->Y, p_tmp.Y, p_result->Y, bit); + vli_cond_set(p_result->Z, p_tmp.Z, p_result->Z, bit); + } +} + +/* -------- Conversions between big endian and little endian: -------- */ + +void ecc_bytes2native(uint32_t p_native[NUM_ECC_DIGITS], + uint8_t p_bytes[NUM_ECC_DIGITS * 4]) +{ + + uint32_t i; + + for (i = 0; i < NUM_ECC_DIGITS; ++i) { + uint8_t *p_digit = p_bytes + 4 * (NUM_ECC_DIGITS - 1 - i); + + p_native[i] = ((uint32_t)p_digit[0] << 24) | + ((uint32_t)p_digit[1] << 16) | + ((uint32_t)p_digit[2] << 8) | + (uint32_t)p_digit[3]; + } +} + +void ecc_native2bytes(uint8_t p_bytes[NUM_ECC_DIGITS * 4], + uint32_t p_native[NUM_ECC_DIGITS]) +{ + + uint32_t i; + + for (i = 0; i < NUM_ECC_DIGITS; ++i) { + uint8_t *p_digit = p_bytes + 4 * (NUM_ECC_DIGITS - 1 - i); + + p_digit[0] = p_native[i] >> 24; + p_digit[1] = p_native[i] >> 16; + p_digit[2] = p_native[i] >> 8; + p_digit[3] = p_native[i]; + } +} + http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0216c73e/crypto/tinycrypt/src/ecc_dh.c ---------------------------------------------------------------------- diff --git a/crypto/tinycrypt/src/ecc_dh.c b/crypto/tinycrypt/src/ecc_dh.c new file mode 100644 index 0000000..965394b --- /dev/null +++ b/crypto/tinycrypt/src/ecc_dh.c @@ -0,0 +1,123 @@ +/* ec_dh.c - TinyCrypt implementation of EC-DH */ + +/* + * Copyright (C) 2015 by Intel Corporation, All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include + +extern uint32_t curve_p[NUM_ECC_DIGITS]; +extern uint32_t curve_b[NUM_ECC_DIGITS]; +extern uint32_t curve_n[NUM_ECC_DIGITS]; +extern EccPoint curve_G; + +int32_t ecc_make_key(EccPoint *p_publicKey, uint32_t p_privateKey[NUM_ECC_DIGITS], + uint32_t p_random[NUM_ECC_DIGITS]) +{ + + /* Make sure the private key is in the range [1, n-1]. + * For the supported curve, n is always large enough + * that we only need to subtract once at most. + */ + uint32_t p_tmp[NUM_ECC_DIGITS]; + + vli_set(p_privateKey, p_random); + vli_sub(p_tmp, p_privateKey, curve_n, NUM_ECC_DIGITS); + + vli_cond_set(p_privateKey, p_privateKey, p_tmp, + vli_cmp(curve_n, p_privateKey, NUM_ECC_DIGITS) == 1); + + if (vli_isZero(p_privateKey)) { + return TC_CRYPTO_FAIL; /* The private key cannot be 0 (mod p). */ + } + + EccPointJacobi P; + + EccPoint_mult(&P, &curve_G, p_privateKey); + EccPoint_toAffine(p_publicKey, &P); + + return TC_CRYPTO_SUCCESS; +} + +/* Compute p_result = x^3 - 3x + b */ +static void curve_x_side(uint32_t p_result[NUM_ECC_DIGITS], + uint32_t x[NUM_ECC_DIGITS]) +{ + + uint32_t _3[NUM_ECC_DIGITS] = {3}; /* -a = 3 */ + + vli_modSquare_fast(p_result, x); /* r = x^2 */ + vli_modSub(p_result, p_result, _3, curve_p); /* r = x^2 - 3 */ + vli_modMult_fast(p_result, p_result, x); /* r = x^3 - 3x */ + vli_modAdd(p_result, p_result, curve_b, curve_p); /* r = x^3 - 3x + b */ + +} + +int32_t ecc_valid_public_key(EccPoint *p_publicKey) +{ + uint32_t l_tmp1[NUM_ECC_DIGITS]; + uint32_t l_tmp2[NUM_ECC_DIGITS]; + + if (EccPoint_isZero(p_publicKey)) { + return -1; + } + + if ((vli_cmp(curve_p, p_publicKey->x, NUM_ECC_DIGITS) != 1) || + (vli_cmp(curve_p, p_publicKey->y, NUM_ECC_DIGITS) != 1)) { + return -2; + } + + vli_modSquare_fast(l_tmp1, p_publicKey->y); /* tmp1 = y^2 */ + + curve_x_side(l_tmp2, p_publicKey->x); /* tmp2 = x^3 - 3x + b */ + + /* Make sure that y^2 == x^3 + ax + b */ + if (vli_cmp(l_tmp1, l_tmp2, NUM_ECC_DIGITS) != 0) { + return -3; + } + + return 0; +} + +int32_t ecdh_shared_secret(uint32_t p_secret[NUM_ECC_DIGITS], + EccPoint *p_publicKey, uint32_t p_privateKey[NUM_ECC_DIGITS]) +{ + + EccPoint p_point; + EccPointJacobi P; + + EccPoint_mult(&P, p_publicKey, p_privateKey); + if (EccPointJacobi_isZero(&P)) { + return TC_CRYPTO_FAIL; + } + EccPoint_toAffine(&p_point, &P); + vli_set(p_secret, p_point.x); + + return TC_CRYPTO_SUCCESS; +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0216c73e/crypto/tinycrypt/src/ecc_dsa.c ---------------------------------------------------------------------- diff --git a/crypto/tinycrypt/src/ecc_dsa.c b/crypto/tinycrypt/src/ecc_dsa.c new file mode 100644 index 0000000..8636fa1 --- /dev/null +++ b/crypto/tinycrypt/src/ecc_dsa.c @@ -0,0 +1,117 @@ +/* ec_dsa.c - TinyCrypt implementation of EC-DSA */ + +/* + * Copyright (C) 2015 by Intel Corporation, All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +extern uint32_t curve_n[NUM_ECC_DIGITS]; +extern EccPoint curve_G; +extern uint32_t curve_nb[NUM_ECC_DIGITS + 1]; + +int32_t ecdsa_sign(uint32_t r[NUM_ECC_DIGITS], uint32_t s[NUM_ECC_DIGITS], + uint32_t p_privateKey[NUM_ECC_DIGITS], uint32_t p_random[NUM_ECC_DIGITS], + uint32_t p_hash[NUM_ECC_DIGITS]) +{ + + uint32_t k[NUM_ECC_DIGITS], tmp[NUM_ECC_DIGITS]; + EccPoint p_point; + EccPointJacobi P; + + if (vli_isZero(p_random)) { + return TC_CRYPTO_FAIL; /* The random number must not be 0. */ + } + + vli_set(k, p_random); + + vli_sub(tmp, k, curve_n, NUM_ECC_DIGITS); + vli_cond_set(k, k, tmp, vli_cmp(curve_n, k, NUM_ECC_DIGITS) == 1); + + /* tmp = k * G */ + EccPoint_mult(&P, &curve_G, k); + EccPoint_toAffine(&p_point, &P); + + /* r = x1 (mod n) */ + vli_set(r, p_point.x); + if (vli_cmp(curve_n, r, NUM_ECC_DIGITS) != 1) { + vli_sub(r, r, curve_n, NUM_ECC_DIGITS); + } + + if (vli_isZero(r)) { + return TC_CRYPTO_FAIL; /* If r == 0, fail (need a different random number). */ + } + + vli_modMult(s, r, p_privateKey, curve_n, curve_nb); /* s = r*d */ + vli_modAdd(s, p_hash, s, curve_n); /* s = e + r*d */ + vli_modInv(k, k, curve_n, curve_nb); /* k = 1 / k */ + vli_modMult(s, s, k, curve_n, curve_nb); /* s = (e + r*d) / k */ + + return TC_CRYPTO_SUCCESS; +} + +int32_t ecdsa_verify(EccPoint *p_publicKey, uint32_t p_hash[NUM_ECC_DIGITS], + uint32_t r[NUM_ECC_DIGITS], uint32_t s[NUM_ECC_DIGITS]) +{ + + uint32_t u1[NUM_ECC_DIGITS], u2[NUM_ECC_DIGITS]; + uint32_t z[NUM_ECC_DIGITS]; + EccPointJacobi P, R; + EccPoint p_point; + + if (vli_isZero(r) || vli_isZero(s)) { + return TC_CRYPTO_FAIL; /* r, s must not be 0. */ + } + + if ((vli_cmp(curve_n, r, NUM_ECC_DIGITS) != 1) || + (vli_cmp(curve_n, s, NUM_ECC_DIGITS) != 1)) { + return TC_CRYPTO_FAIL; /* r, s must be < n. */ + } + + /* Calculate u1 and u2. */ + vli_modInv(z, s, curve_n, curve_nb); /* Z = s^-1 */ + vli_modMult(u1, p_hash, z, curve_n, curve_nb); /* u1 = e/s */ + vli_modMult(u2, r, z, curve_n, curve_nb); /* u2 = r/s */ + + /* calculate P = u1*G + u2*Q */ + EccPoint_mult(&P, &curve_G, u1); + EccPoint_mult(&R, p_publicKey, u2); + EccPoint_add(&P, &R); + EccPoint_toAffine(&p_point, &P); + + /* Accept only if P.x == r. */ + vli_cond_set( + p_point.x, + p_point.x, + z, + vli_sub(z, p_point.x, curve_n, NUM_ECC_DIGITS)); + + return (vli_cmp(p_point.x, r, NUM_ECC_DIGITS) == 0); +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0216c73e/crypto/tinycrypt/src/hmac.c ---------------------------------------------------------------------- diff --git a/crypto/tinycrypt/src/hmac.c b/crypto/tinycrypt/src/hmac.c new file mode 100644 index 0000000..b9af4a6 --- /dev/null +++ b/crypto/tinycrypt/src/hmac.c @@ -0,0 +1,149 @@ +/* hmac.c - TinyCrypt implementation of the HMAC algorithm */ + +/* + * Copyright (C) 2015 by Intel Corporation, All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +static void rekey(uint8_t *key, const uint8_t *new_key, uint32_t key_size) +{ + const uint8_t inner_pad = (uint8_t) 0x36; + const uint8_t outer_pad = (uint8_t) 0x5c; + uint32_t i; + + for (i = 0; i < key_size; ++i) { + key[i] = inner_pad ^ new_key[i]; + key[i + TC_SHA256_BLOCK_SIZE] = outer_pad ^ new_key[i]; + } + for (; i < TC_SHA256_BLOCK_SIZE; ++i) { + key[i] = inner_pad; key[i + TC_SHA256_BLOCK_SIZE] = outer_pad; + } +} + +int32_t tc_hmac_set_key(TCHmacState_t ctx, + const uint8_t *key, + uint32_t key_size) +{ + /* input sanity check: */ + if (ctx == (TCHmacState_t) 0 || + key == (const uint8_t *) 0 || + key_size == 0) { + return TC_FAIL; + } + + const uint8_t dummy_key[key_size]; + struct tc_hmac_state_struct dummy_state; + + if (key_size <= TC_SHA256_BLOCK_SIZE) { + /* + * The next three lines consist of dummy calls just to avoid + * certain timing attacks. Without these dummy calls, + * adversaries would be able to learn whether the key_size is + * greater than TC_SHA256_BLOCK_SIZE by measuring the time + * consumed in this process. + */ + (void)tc_sha256_init(&dummy_state.hash_state); + (void)tc_sha256_update(&dummy_state.hash_state, + dummy_key, + key_size); + (void)tc_sha256_final(&dummy_state.key[TC_SHA256_DIGEST_SIZE], + &dummy_state.hash_state); + + /* Actual code for when key_size <= TC_SHA256_BLOCK_SIZE: */ + rekey(ctx->key, key, key_size); + } else { + (void)tc_sha256_init(&ctx->hash_state); + (void)tc_sha256_update(&ctx->hash_state, key, key_size); + (void)tc_sha256_final(&ctx->key[TC_SHA256_DIGEST_SIZE], + &ctx->hash_state); + rekey(ctx->key, + &ctx->key[TC_SHA256_DIGEST_SIZE], + TC_SHA256_DIGEST_SIZE); + } + + return TC_SUCCESS; +} + +int32_t tc_hmac_init(TCHmacState_t ctx) +{ + /* input sanity check: */ + if (ctx == (TCHmacState_t) 0 || + ctx->key == (uint8_t *) 0) { + return TC_FAIL; + } + + (void)tc_sha256_init(&ctx->hash_state); + (void)tc_sha256_update(&ctx->hash_state, + ctx->key, + TC_SHA256_BLOCK_SIZE); + + return TC_SUCCESS; +} + +int32_t tc_hmac_update(TCHmacState_t ctx, + const void *data, + uint32_t data_length) +{ + /* input sanity check: */ + if (ctx == (TCHmacState_t) 0 || ctx->key == (uint8_t *) 0) { + return TC_FAIL; + } + + (void)tc_sha256_update(&ctx->hash_state, data, data_length); + + return TC_SUCCESS; +} + +int32_t tc_hmac_final(uint8_t *tag, uint32_t taglen, TCHmacState_t ctx) +{ + /* input sanity check: */ + if (tag == (uint8_t *) 0 || + taglen != TC_SHA256_DIGEST_SIZE || + ctx == (TCHmacState_t) 0 || + ctx->key == (uint8_t *) 0) { + return TC_FAIL; + } + + (void) tc_sha256_final(tag, &ctx->hash_state); + + (void)tc_sha256_init(&ctx->hash_state); + (void)tc_sha256_update(&ctx->hash_state, + &ctx->key[TC_SHA256_BLOCK_SIZE], + TC_SHA256_BLOCK_SIZE); + (void)tc_sha256_update(&ctx->hash_state, tag, TC_SHA256_DIGEST_SIZE); + (void)tc_sha256_final(tag, &ctx->hash_state); + + /* destroy the current state */ + _set(ctx, 0, sizeof(*ctx)); + + return TC_SUCCESS; +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0216c73e/crypto/tinycrypt/src/hmac_prng.c ---------------------------------------------------------------------- diff --git a/crypto/tinycrypt/src/hmac_prng.c b/crypto/tinycrypt/src/hmac_prng.c new file mode 100644 index 0000000..c24c37e --- /dev/null +++ b/crypto/tinycrypt/src/hmac_prng.c @@ -0,0 +1,210 @@ +/* Hmac_prng.c - TinyCrypt implementation of HMAC-PRNG */ + +/* + * Copyright (C) 2015 by Intel Corporation, All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +/* + * min bytes in the seed string. + * MIN_SLEN*8 must be at least the expected security level. + */ +static const uint32_t MIN_SLEN = 32; + +/* + * max bytes in the seed string; + * SP800-90A specifies a maximum of 2^35 bits (i.e., 2^32 bytes). + */ +static const uint32_t MAX_SLEN = UINT32_MAX; + +/* + * max bytes in the personalization string; + * SP800-90A specifies a maximum of 2^35 bits (i.e., 2^32 bytes). + */ +static const uint32_t MAX_PLEN = UINT32_MAX; + +/* + * max bytes in the additional_info string; + * SP800-90A specifies a maximum of 2^35 bits (i.e., 2^32 bytes). + */ +static const uint32_t MAX_ALEN = UINT32_MAX; + +/* + * max number of generates between re-seeds; + * TinyCrypt accepts up to (2^32 - 1) which is the maximal value of + * a uint32_t variable, while SP800-90A specifies a maximum of 2^48. + */ +static const uint32_t MAX_GENS = UINT32_MAX; + +/* + * maximum bytes per generate call; + * SP800-90A specifies a maximum up to 2^19. + */ +static const uint32_t MAX_OUT = (1 << 19); + +/* + * Assumes: prng != NULL, e != NULL, len >= 0. + */ +static void update(TCHmacPrng_t prng, const uint8_t *e, uint32_t len) +{ + const uint8_t separator0 = 0x00; + const uint8_t separator1 = 0x01; + + /* use current state, e and separator 0 to compute a new prng key: */ + (void)tc_hmac_init(&prng->h); + (void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v)); + (void)tc_hmac_update(&prng->h, &separator0, sizeof(separator0)); + (void)tc_hmac_update(&prng->h, e, len); + (void)tc_hmac_final(prng->key, sizeof(prng->key), &prng->h); + /* configure the new prng key into the prng's instance of hmac */ + (void)tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key)); + + /* use the new key to compute a new state variable v */ + (void)tc_hmac_init(&prng->h); + (void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v)); + (void)tc_hmac_final(prng->v, sizeof(prng->v), &prng->h); + + /* use current state, e and separator 1 to compute a new prng key: */ + (void)tc_hmac_init(&prng->h); + (void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v)); + (void)tc_hmac_update(&prng->h, &separator1, sizeof(separator1)); + (void)tc_hmac_update(&prng->h, e, len); + (void)tc_hmac_final(prng->key, sizeof(prng->key), &prng->h); + /* configure the new prng key into the prng's instance of hmac */ + (void)tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key)); + + /* use the new key to compute a new state variable v */ + (void)tc_hmac_init(&prng->h); + (void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v)); + (void)tc_hmac_final(prng->v, sizeof(prng->v), &prng->h); +} + +int32_t tc_hmac_prng_init(TCHmacPrng_t prng, + const uint8_t *personalization, + uint32_t plen) +{ + /* input sanity check: */ + if (prng == (TCHmacPrng_t) 0 || + personalization == (uint8_t *) 0 || + plen > MAX_PLEN) { + return TC_FAIL; + } + + /* put the generator into a known state: */ + _set(prng->key, 0x00, sizeof(prng->key)); + _set(prng->v, 0x01, sizeof(prng->v)); + tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key)); + /* update assumes SOME key has been configured into HMAC */ + + update(prng, personalization, plen); + + /* force a reseed before allowing tc_hmac_prng_generate to succeed: */ + prng->countdown = 0; + + return TC_SUCCESS; +} + +int32_t tc_hmac_prng_reseed(TCHmacPrng_t prng, + const uint8_t *seed, + uint32_t seedlen, + const uint8_t *additional_input, + uint32_t additionallen) +{ + /* input sanity check: */ + if (prng == (TCHmacPrng_t) 0 || + seed == (const uint8_t *) 0 || + seedlen < MIN_SLEN || + seedlen > MAX_SLEN) { + return TC_FAIL; + } + + if (additional_input != (const uint8_t *) 0) { + /* + * Abort if additional_input is provided but has inappropriate + * length + */ + if (additionallen == 0 || + additionallen > MAX_ALEN) { + return TC_FAIL; + } else { + /* call update for the seed and additional_input */ + update(prng, seed, seedlen); + update(prng, additional_input, additionallen); + } + } else { + /* call update only for the seed */ + update(prng, seed, seedlen); + } + + /* ... and enable hmac_prng_generate */ + prng->countdown = MAX_GENS; + + return TC_SUCCESS; +} + +int32_t tc_hmac_prng_generate(uint8_t *out, uint32_t outlen, TCHmacPrng_t prng) +{ + uint32_t bufferlen; + + /* input sanity check: */ + if (out == (uint8_t *) 0 || + prng == (TCHmacPrng_t) 0 || + outlen == 0 || + outlen > MAX_OUT) { + return TC_FAIL; + } else if (prng->countdown == 0) { + return TC_HMAC_PRNG_RESEED_REQ; + } + + prng->countdown--; + + while (outlen != 0) { + /* operate HMAC in OFB mode to create "random" outputs */ + (void)tc_hmac_init(&prng->h); + (void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v)); + (void)tc_hmac_final(prng->v, sizeof(prng->v), &prng->h); + + bufferlen = (TC_SHA256_DIGEST_SIZE > outlen) ? + outlen : TC_SHA256_DIGEST_SIZE; + (void)_copy(out, bufferlen, prng->v, bufferlen); + + out += bufferlen; + outlen = (outlen > TC_SHA256_DIGEST_SIZE) ? + (outlen - TC_SHA256_DIGEST_SIZE) : 0; + } + + /* block future PRNG compromises from revealing past state */ + update(prng, prng->v, TC_SHA256_DIGEST_SIZE); + + return TC_SUCCESS; +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0216c73e/crypto/tinycrypt/src/sha256.c ---------------------------------------------------------------------- diff --git a/crypto/tinycrypt/src/sha256.c b/crypto/tinycrypt/src/sha256.c new file mode 100644 index 0000000..1dced76 --- /dev/null +++ b/crypto/tinycrypt/src/sha256.c @@ -0,0 +1,219 @@ +/* sha256.c - TinyCrypt SHA-256 crypto hash algorithm implementation */ + +/* + * Copyright (C) 2015 by Intel Corporation, All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +static void compress(uint32_t *iv, const uint8_t *data); + +int32_t tc_sha256_init(TCSha256State_t s) +{ + /* input sanity check: */ + if (s == (TCSha256State_t) 0) { + return TC_FAIL; + } + + /* + * Setting the initial state values. + * These values correspond to the first 32 bits of the fractional parts + * of the square roots of the first 8 primes: 2, 3, 5, 7, 11, 13, 17 + * and 19. + */ + _set((uint8_t *) s, 0x00, sizeof(*s)); + s->iv[0] = 0x6a09e667; + s->iv[1] = 0xbb67ae85; + s->iv[2] = 0x3c6ef372; + s->iv[3] = 0xa54ff53a; + s->iv[4] = 0x510e527f; + s->iv[5] = 0x9b05688c; + s->iv[6] = 0x1f83d9ab; + s->iv[7] = 0x5be0cd19; + + return TC_SUCCESS; +} + +int32_t tc_sha256_update(TCSha256State_t s, const uint8_t *data, size_t datalen) +{ + /* input sanity check: */ + if (s == (TCSha256State_t) 0 || + s->iv == (uint32_t *) 0 || + data == (void *) 0) { + return TC_FAIL; + } else if (datalen == 0) { + return TC_SUCCESS; + } + + while (datalen-- > 0) { + s->leftover[s->leftover_offset++] = *(data++); + if (s->leftover_offset >= TC_SHA256_BLOCK_SIZE) { + compress(s->iv, s->leftover); + s->leftover_offset = 0; + s->bits_hashed += (TC_SHA256_BLOCK_SIZE << 3); + } + } + + return TC_SUCCESS; +} + +int32_t tc_sha256_final(uint8_t *digest, TCSha256State_t s) +{ + uint32_t i; + + /* input sanity check: */ + if (digest == (uint8_t *) 0 || + s == (TCSha256State_t) 0 || + s->iv == (uint32_t *) 0) { + return TC_FAIL; + } + + s->bits_hashed += (s->leftover_offset << 3); + + s->leftover[s->leftover_offset++] = 0x80; /* always room for one byte */ + if (s->leftover_offset > (sizeof(s->leftover) - 8)) { + /* there is not room for all the padding in this block */ + _set(s->leftover + s->leftover_offset, 0x00, + sizeof(s->leftover) - s->leftover_offset); + compress(s->iv, s->leftover); + s->leftover_offset = 0; + } + + /* add the padding and the length in big-Endian format */ + _set(s->leftover + s->leftover_offset, 0x00, + sizeof(s->leftover) - 8 - s->leftover_offset); + s->leftover[sizeof(s->leftover) - 1] = (uint8_t)(s->bits_hashed); + s->leftover[sizeof(s->leftover) - 2] = (uint8_t)(s->bits_hashed >> 8); + s->leftover[sizeof(s->leftover) - 3] = (uint8_t)(s->bits_hashed >> 16); + s->leftover[sizeof(s->leftover) - 4] = (uint8_t)(s->bits_hashed >> 24); + s->leftover[sizeof(s->leftover) - 5] = (uint8_t)(s->bits_hashed >> 32); + s->leftover[sizeof(s->leftover) - 6] = (uint8_t)(s->bits_hashed >> 40); + s->leftover[sizeof(s->leftover) - 7] = (uint8_t)(s->bits_hashed >> 48); + s->leftover[sizeof(s->leftover) - 8] = (uint8_t)(s->bits_hashed >> 56); + + /* hash the padding and length */ + compress(s->iv, s->leftover); + + /* copy the iv out to digest */ + for (i = 0; i < TC_SHA256_STATE_BLOCKS; ++i) { + uint32_t t = *((uint32_t *) &s->iv[i]); + *digest++ = (uint8_t)(t >> 24); + *digest++ = (uint8_t)(t >> 16); + *digest++ = (uint8_t)(t >> 8); + *digest++ = (uint8_t)(t); + } + + /* destroy the current state */ + _set(s, 0, sizeof(*s)); + + return TC_SUCCESS; +} + +/* + * Initializing SHA-256 Hash constant words K. + * These values correspond to the first 32 bits of the fractional parts of the + * cube roots of the first 64 primes between 2 and 311. + */ +static const uint32_t k256[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, + 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, + 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, + 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, + 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, + 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + +static inline uint32_t ROTR(uint32_t a, uint32_t n) +{ + return (((a) >> n) | ((a) << (32 - n))); +} + +#define Sigma0(a)(ROTR((a), 2) ^ ROTR((a), 13) ^ ROTR((a), 22)) +#define Sigma1(a)(ROTR((a), 6) ^ ROTR((a), 11) ^ ROTR((a), 25)) +#define sigma0(a)(ROTR((a), 7) ^ ROTR((a), 18) ^ ((a) >> 3)) +#define sigma1(a)(ROTR((a), 17) ^ ROTR((a), 19) ^ ((a) >> 10)) + +#define Ch(a, b, c)(((a) & (b)) ^ ((~(a)) & (c))) +#define Maj(a, b, c)(((a) & (b)) ^ ((a) & (c)) ^ ((b) & (c))) + +static inline uint32_t BigEndian(const uint8_t **c) +{ + uint32_t n = 0; + + n = (((uint32_t)(*((*c)++))) << 24); + n |= ((uint32_t)(*((*c)++)) << 16); + n |= ((uint32_t)(*((*c)++)) << 8); + n |= ((uint32_t)(*((*c)++))); + return n; +} + +static void compress(uint32_t *iv, const uint8_t *data) +{ + uint32_t a, b, c, d, e, f, g, h; + uint32_t s0, s1; + uint32_t t1, t2; + uint32_t work_space[16]; + uint32_t n; + uint32_t i; + + a = iv[0]; b = iv[1]; c = iv[2]; d = iv[3]; + e = iv[4]; f = iv[5]; g = iv[6]; h = iv[7]; + + for (i = 0; i < 16; ++i) { + n = BigEndian(&data); + t1 = work_space[i] = n; + t1 += h + Sigma1(e) + Ch(e, f, g) + k256[i]; + t2 = Sigma0(a) + Maj(a, b, c); + h = g; g = f; f = e; e = d + t1; + d = c; c = b; b = a; a = t1 + t2; + } + + for ( ; i < 64; ++i) { + s0 = work_space[(i+1)&0x0f]; + s0 = sigma0(s0); + s1 = work_space[(i+14)&0x0f]; + s1 = sigma1(s1); + + t1 = work_space[i&0xf] += s0 + s1 + work_space[(i+9)&0xf]; + t1 += h + Sigma1(e) + Ch(e, f, g) + k256[i]; + t2 = Sigma0(a) + Maj(a, b, c); + h = g; g = f; f = e; e = d + t1; + d = c; c = b; b = a; a = t1 + t2; + } + + iv[0] += a; iv[1] += b; iv[2] += c; iv[3] += d; + iv[4] += e; iv[5] += f; iv[6] += g; iv[7] += h; +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0216c73e/crypto/tinycrypt/src/utils.c ---------------------------------------------------------------------- diff --git a/crypto/tinycrypt/src/utils.c b/crypto/tinycrypt/src/utils.c new file mode 100644 index 0000000..7f05939 --- /dev/null +++ b/crypto/tinycrypt/src/utils.c @@ -0,0 +1,78 @@ +/* utils.c - TinyCrypt platform-dependent run-time operations */ + +/* + * Copyright (C) 2015 by Intel Corporation, All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#include + +#define MASK_MOST_SIG_BIT 0x80 +#define MASK_TWENTY_SEVEN 0x1b + +uint32_t _copy(uint8_t *to, uint32_t to_len, + const uint8_t *from, uint32_t from_len) +{ + if (from_len <= to_len) { + (void)memcpy(to, from, from_len); + return from_len; + } else { + return TC_FAIL; + } +} + +void _set(void *to, uint8_t val, uint32_t len) +{ + (void)memset(to, val, len); +} + +/* + * Doubles the value of a byte for values up to 127. Original 'return + * ((a<<1) ^ ((a>>7) * 0x1b))' re-written to avoid extra multiplication which + * the compiler won't be able to optimize + */ +uint8_t _double_byte(uint8_t a) +{ + return (a & MASK_MOST_SIG_BIT) ? + ((a << 1) ^ MASK_TWENTY_SEVEN) : (a << 1); +} + +int32_t _compare(const uint8_t *a, const uint8_t *b, size_t size) +{ + const uint8_t *tempa = a; + const uint8_t *tempb = b; + uint8_t result = 0; + + for (uint32_t i = 0; i < size; i++) { + result |= tempa[i] ^ tempb[i]; + } + return result; +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0216c73e/drivers/adc/adc_nrf51/include/adc_nrf51/adc_nrf51.h ---------------------------------------------------------------------- diff --git a/drivers/adc/adc_nrf51/include/adc_nrf51/adc_nrf51.h b/drivers/adc/adc_nrf51/include/adc_nrf51/adc_nrf51.h deleted file mode 100644 index 0006b89..0000000 --- a/drivers/adc/adc_nrf51/include/adc_nrf51/adc_nrf51.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. - */ - -#ifndef __ADC_NRF51_H__ -#define __ADC_NRF51_H__ - -#include - -#include -#include - -int nrf51_adc_dev_init(struct os_dev *, void *); - -#endif /* __ADC_NRF51_H__ */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0216c73e/drivers/adc/adc_nrf51/pkg.yml ---------------------------------------------------------------------- diff --git a/drivers/adc/adc_nrf51/pkg.yml b/drivers/adc/adc_nrf51/pkg.yml deleted file mode 100644 index 2f604ed..0000000 --- a/drivers/adc/adc_nrf51/pkg.yml +++ /dev/null @@ -1,28 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. -# - -pkg.name: drivers/adc/adc_nrf51 -pkg.description: ADC driver for the NRF51 -pkg.author: "Apache Mynewt " -pkg.homepage: "http://mynewt.apache.org/" -pkg.keywords: -pkg.apis: - - ADC_HW_IMPL -pkg.deps: - - drivers/adc http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0216c73e/drivers/adc/adc_nrf51/src/adc_nrf51.c ---------------------------------------------------------------------- diff --git a/drivers/adc/adc_nrf51/src/adc_nrf51.c b/drivers/adc/adc_nrf51/src/adc_nrf51.c deleted file mode 100644 index cf57de6..0000000 --- a/drivers/adc/adc_nrf51/src/adc_nrf51.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 -#include -#include -#include -#include - -/* Nordic headers */ -#include -#include -#include -#include - -/** - * Weak symbol, this is defined in Nordic drivers but not exported. - * Needed for NVIC_SetVector(). - */ -extern void ADC_IRQHandler(void); - -#define NRF_ADC_CHANNEL_COUNT (1) - -struct nrf51_adc_stats { - uint16_t adc_events; - uint16_t adc_events_failed; -}; -static struct nrf51_adc_stats nrf51_adc_stats; - -struct adc_dev *global_adc_dev; - -nrf_adc_config_t adc_cfg; -nrf_drv_adc_config_t *global_adc_config; - -struct adc_chan_config nrf51_adc_chans[NRF_ADC_CHANNEL_COUNT]; -nrf_drv_adc_channel_t *nrf_adc_chan; - -static void -nrf51_adc_event_handler(const nrf_drv_adc_evt_t *event) -{ - nrf_drv_adc_done_evt_t *done_ev; - int rc; - - if (global_adc_dev == NULL) { - ++nrf51_adc_stats.adc_events_failed; - return; - } - - ++nrf51_adc_stats.adc_events; - - /* Right now only data reads supported, assert for unknown event - * type. - */ - assert(event->type == NRF_DRV_ADC_EVT_DONE); - - done_ev = (nrf_drv_adc_done_evt_t * const) &event->data.done; - - rc = global_adc_dev->ad_event_handler_func(global_adc_dev, - global_adc_dev->ad_event_handler_arg, - ADC_EVENT_RESULT, done_ev->p_buffer, - done_ev->size * sizeof(nrf_adc_value_t)); - if (rc != 0) { - ++nrf51_adc_stats.adc_events_failed; - } -} - -/** - * Open the NRF51 ADC device - * - * This function locks the device for access from other tasks. - * - * @param odev The OS device to open - * @param wait The time in MS to wait. If 0 specified, returns immediately - * if resource unavailable. If OS_WAIT_FOREVER specified, blocks - * until resource is available. - * @param arg Argument provided by higher layer to open, in this case - * it can be a nrf_drv_saadc_config_t, to override the default - * configuration. - * - * @return 0 on success, non-zero on failure. - */ -static int -nrf51_adc_open(struct os_dev *odev, uint32_t wait, void *arg) -{ - struct adc_dev *dev; - nrf_drv_adc_config_t *cfg; - int rc; - - dev = (struct adc_dev *) odev; - - if (os_started()) { - rc = os_mutex_pend(&dev->ad_lock, wait); - if (rc != OS_OK) { - goto err; - } - } - - /* Initialize the device */ - cfg = (nrf_drv_adc_config_t *)arg; - rc = nrf_drv_adc_init(cfg, nrf51_adc_event_handler); - if (rc != 0) { - goto err; - } - - global_adc_dev = dev; - global_adc_config = arg; - - return (0); -err: - return (rc); -} - - -/** - * Close the NRF51 ADC device. - * - * This function unlocks the device. - * - * @param odev The device to close. - */ -static int -nrf51_adc_close(struct os_dev *odev) -{ - struct adc_dev *dev; - - dev = (struct adc_dev *) odev; - - nrf_drv_adc_uninit(); - - global_adc_dev = NULL; - global_adc_config = NULL; - - if (os_started()) { - os_mutex_release(&dev->ad_lock); - } - - return (0); -} - -/** - * Configure an ADC channel on the Nordic ADC. - * - * @param dev The ADC device to configure - * @param cnum The channel on the ADC device to configure - * @param cfgdata An opaque pointer to channel config, expected to be - * a nrf_drv_adc_channel_config_t - * - * @return 0 on success, non-zero on failure. - */ -static int -nrf51_adc_configure_channel(struct adc_dev *dev, uint8_t cnum, - void *cfgdata) -{ - nrf_drv_adc_channel_t *cc; - nrf_drv_adc_channel_config_t *cc_cfg; - nrf_adc_config_t adc_cfg; - uint16_t refmv; - uint8_t res; - int rc; - - rc = -1; - if (global_adc_config == NULL) { - goto err; - } - - cc = (nrf_drv_adc_channel_t *)cfgdata; - nrf_adc_chan = cc; - cc_cfg = &cc->config.config; - - adc_cfg.reference = cc_cfg->reference | - (cc_cfg->external_reference << ADC_CONFIG_EXTREFSEL_Pos); - adc_cfg.resolution = cc_cfg->resolution; - adc_cfg.scaling = cc_cfg->input; - nrf_adc_configure(&adc_cfg); - nrf_drv_adc_channel_enable(cc); - - /* Set the resolution and reference voltage for this channel to - * enable conversion functions. - */ - switch (adc_cfg.resolution) { - case NRF_ADC_CONFIG_RES_8BIT: - res = 8; - break; - case NRF_ADC_CONFIG_RES_9BIT: - res = 9; - break; - case NRF_ADC_CONFIG_RES_10BIT: - res = 10; - break; - default: - assert(0); - } - - switch (adc_cfg.reference) { - case NRF_ADC_CONFIG_REF_VBG: - refmv = 1200; /* 1.2V for NRF51 */ - break; - case NRF_ADC_CONFIG_REF_EXT_REF0: - refmv = bsp_get_refmv(cc_cfg); - break; - case NRF_ADC_CONFIG_REF_EXT_REF1: - refmv = bsp_get_refmv(cc_cfg); - break; - case NRF_ADC_CONFIG_REF_SUPPLY_ONE_HALF: - refmv = bsp_get_refmv(cc_cfg) / 2; - break; - case NRF_ADC_CONFIG_REF_SUPPLY_ONE_THIRD: - refmv = bsp_get_refmv(cc_cfg) / 3; - break; - default: - assert(0); - } - - /* Adjust reference voltage for gain. */ - switch (cc_cfg->input) { - case NRF_ADC_CONFIG_SCALING_INPUT_FULL_SCALE: - break; - case NRF_ADC_CONFIG_SCALING_INPUT_ONE_THIRD: - refmv *= 3; - break; - case NRF_ADC_CONFIG_SCALING_INPUT_TWO_THIRDS: - refmv = (refmv * 3) / 2; - break; - case NRF_ADC_CONFIG_SCALING_SUPPLY_ONE_THIRD: - refmv = refmv * 3; - break; - case NRF_ADC_CONFIG_SCALING_SUPPLY_TWO_THIRDS: - refmv = (refmv * 3) / 2; - break; - default: - break; - } - - /* Store these values in channel definitions, for conversions to - * milivolts. - */ - dev->ad_chans[cnum].c_res = res; - dev->ad_chans[cnum].c_refmv = refmv; - dev->ad_chans[cnum].c_configured = 1; - - return (0); -err: - return (rc); -} - -/** - * Set buffer to read data into. Implementation of setbuffer handler. - * Sets both the primary and secondary buffers for DMA. - */ -static int -nrf51_adc_set_buffer(struct adc_dev *dev, void *buf1, void *buf2, - int buf_len) -{ - int rc; - - /* XXX: If this is called in blocking mode, it will result in a wait. */ - - /* Convert overall buffer length, into a total number of samples which - * Nordic APIs expect. - */ - buf_len /= sizeof(nrf_adc_value_t); - - rc = nrf_drv_adc_buffer_convert((nrf_adc_value_t *) buf1, buf_len); - if (rc != 0) { - goto err; - } - - /* XXX: For now, only support one buffer */ -#if 0 - if (buf2) { - rc = nrf_drv_adc_buffer_convert((nrf_adc_value_t *) buf2, - buf_len); - if (rc != 0) { - goto err; - } - } -#endif - return (0); -err: - return (rc); -} - -static int -nrf51_adc_release_buffer(struct adc_dev *dev, void *buf, int buf_len) -{ - int rc; - - buf_len /= sizeof(nrf_adc_value_t); - - rc = nrf_drv_adc_buffer_convert((nrf_adc_value_t *) buf, buf_len); - if (rc != 0) { - goto err; - } - - return (0); -err: - return (rc); -} - -/** - * Trigger an ADC sample. - */ -static int -nrf51_adc_sample(struct adc_dev *dev) -{ - nrf_drv_adc_sample(); - - return (0); -} - -/** - * Blocking read of an ADC channel, returns result as an integer. - */ -static int -nrf51_adc_read_channel(struct adc_dev *dev, uint8_t cnum, int *result) -{ - nrf_adc_value_t adc_value; - int rc; - - rc = nrf_drv_adc_sample_convert(nrf_adc_chan, &adc_value); - if (rc == 0) { - *result = (int) adc_value; - } - return (rc); -} - -static int -nrf51_adc_read_buffer(struct adc_dev *dev, void *buf, int buf_len, int off, - int *result) -{ - nrf_adc_value_t val; - int data_off; - - data_off = off * sizeof(nrf_adc_value_t); - assert(data_off < buf_len); - - val = *(nrf_adc_value_t *) ((uint8_t *) buf + data_off); - *result = val; - - return (0); -} - -static int -nrf51_adc_size_buffer(struct adc_dev *dev, int chans, int samples) -{ - return (sizeof(nrf_adc_value_t) * chans * samples); -} - - -/** - * Callback to initialize an adc_dev structure from the os device - * initialization callback. This sets up a nrf51_adc_device(), so that - * subsequent lookups to this device allow us to manipulate it. - */ -int -nrf51_adc_dev_init(struct os_dev *odev, void *arg) -{ - struct adc_dev *dev; - struct adc_driver_funcs *af; - - dev = (struct adc_dev *) odev; - - os_mutex_init(&dev->ad_lock); - - dev->ad_chans = (void *) nrf51_adc_chans; - dev->ad_chan_count = NRF_ADC_CHANNEL_COUNT; - - OS_DEV_SETHANDLERS(odev, nrf51_adc_open, nrf51_adc_close); - - af = &dev->ad_funcs; - - af->af_configure_channel = nrf51_adc_configure_channel; - af->af_sample = nrf51_adc_sample; - af->af_read_channel = nrf51_adc_read_channel; - af->af_set_buffer = nrf51_adc_set_buffer; - af->af_release_buffer = nrf51_adc_release_buffer; - af->af_read_buffer = nrf51_adc_read_buffer; - af->af_size_buffer = nrf51_adc_size_buffer; - - NVIC_SetVector(ADC_IRQn, (uint32_t) ADC_IRQHandler); - - return (0); -} - - http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0216c73e/drivers/adc/adc_nrf52/include/adc_nrf52/adc_nrf52.h ---------------------------------------------------------------------- diff --git a/drivers/adc/adc_nrf52/include/adc_nrf52/adc_nrf52.h b/drivers/adc/adc_nrf52/include/adc_nrf52/adc_nrf52.h deleted file mode 100644 index f356f89..0000000 --- a/drivers/adc/adc_nrf52/include/adc_nrf52/adc_nrf52.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. - */ - -#ifndef __ADC_NRF52_H__ -#define __ADC_NRF52_H__ - -#include - -#include -#include - -int nrf52_adc_dev_init(struct os_dev *, void *); - -#endif /* __ADC_H__ */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0216c73e/drivers/adc/adc_nrf52/pkg.yml ---------------------------------------------------------------------- diff --git a/drivers/adc/adc_nrf52/pkg.yml b/drivers/adc/adc_nrf52/pkg.yml deleted file mode 100644 index fa2eb70..0000000 --- a/drivers/adc/adc_nrf52/pkg.yml +++ /dev/null @@ -1,28 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. -# - -pkg.name: drivers/adc/adc_nrf52 -pkg.description: ADC driver for the NRF52 -pkg.author: "Apache Mynewt " -pkg.homepage: "http://mynewt.apache.org/" -pkg.keywords: -pkg.apis: - - ADC_HW_IMPL -pkg.deps: - - drivers/adc http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0216c73e/drivers/adc/adc_nrf52/src/adc_nrf52.c ---------------------------------------------------------------------- diff --git a/drivers/adc/adc_nrf52/src/adc_nrf52.c b/drivers/adc/adc_nrf52/src/adc_nrf52.c deleted file mode 100644 index d167175..0000000 --- a/drivers/adc/adc_nrf52/src/adc_nrf52.c +++ /dev/null @@ -1,398 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 -#include -#include -#include -#include - -/* Nordic headers */ -#include -#include -#include -#include - -/** - * Weak symbol, this is defined in Nordic drivers but not exported. - * Needed for NVIC_SetVector(). - */ -extern void SAADC_IRQHandler(void); - -struct nrf52_saadc_stats { - uint16_t saadc_events; - uint16_t saadc_events_failed; -}; -static struct nrf52_saadc_stats nrf52_saadc_stats; - -struct adc_dev *global_adc_dev; -nrf_drv_saadc_config_t *global_adc_config; - -uint8_t nrf52_adc_chans[NRF_SAADC_CHANNEL_COUNT * sizeof(struct adc_chan_config)]; - -static void -nrf52_saadc_event_handler(const nrf_drv_saadc_evt_t *event) -{ - nrf_drv_saadc_done_evt_t *done_ev; - int rc; - - if (global_adc_dev == NULL) { - ++nrf52_saadc_stats.saadc_events_failed; - return; - } - - ++nrf52_saadc_stats.saadc_events; - - /* Right now only data reads supported, assert for unknown event - * type. - */ - assert(event->type == NRF_DRV_SAADC_EVT_DONE); - - done_ev = (nrf_drv_saadc_done_evt_t * const) &event->data.done; - - rc = global_adc_dev->ad_event_handler_func(global_adc_dev, - global_adc_dev->ad_event_handler_arg, - ADC_EVENT_RESULT, done_ev->p_buffer, - done_ev->size * sizeof(nrf_saadc_value_t)); - if (rc != 0) { - ++nrf52_saadc_stats.saadc_events_failed; - } -} - - -/** - * Open the NRF52 ADC device - * - * This function locks the device for access from other tasks. - * - * @param odev The OS device to open - * @param wait The time in MS to wait. If 0 specified, returns immediately - * if resource unavailable. If OS_WAIT_FOREVER specified, blocks - * until resource is available. - * @param arg Argument provided by higher layer to open, in this case - * it can be a nrf_drv_saadc_config_t, to override the default - * configuration. - * - * @return 0 on success, non-zero on failure. - */ -static int -nrf52_adc_open(struct os_dev *odev, uint32_t wait, void *arg) -{ - struct adc_dev *dev; - int rc; - - dev = (struct adc_dev *) odev; - - if (os_started()) { - rc = os_mutex_pend(&dev->ad_lock, wait); - if (rc != OS_OK) { - goto err; - } - } - - if (odev->od_flags & OS_DEV_F_STATUS_OPEN) { - os_mutex_release(&dev->ad_lock); - rc = OS_EBUSY; - goto err; - } - - /* Initialize the device */ - rc = nrf_drv_saadc_init((nrf_drv_saadc_config_t *) arg, - nrf52_saadc_event_handler); - if (rc != 0) { - goto err; - } - - global_adc_dev = dev; - global_adc_config = arg; - - return (0); -err: - return (rc); -} - - -/** - * Close the NRF52 ADC device. - * - * This function unlocks the device. - * - * @param odev The device to close. - */ -static int -nrf52_adc_close(struct os_dev *odev) -{ - struct adc_dev *dev; - - dev = (struct adc_dev *) odev; - - nrf_drv_saadc_uninit(); - - global_adc_dev = NULL; - global_adc_config = NULL; - - if (os_started()) { - os_mutex_release(&dev->ad_lock); - } - - return (0); -} - -/** - * Configure an ADC channel on the Nordic ADC. - * - * @param dev The ADC device to configure - * @param cnum The channel on the ADC device to configure - * @param cfgdata An opaque pointer to channel config, expected to be - * a nrf_saadc_channel_config_t - * - * @return 0 on success, non-zero on failure. - */ -static int -nrf52_adc_configure_channel(struct adc_dev *dev, uint8_t cnum, - void *cfgdata) -{ - nrf_saadc_channel_config_t *cc; - uint16_t refmv; - uint8_t res; - int rc; - - cc = (nrf_saadc_channel_config_t *) cfgdata; - - rc = nrf_drv_saadc_channel_init(cnum, cc); - if (rc != 0) { - goto err; - } - - if (global_adc_config) { - /* Set the resolution and reference voltage for this channel to - * enable conversion functions. - */ - switch (global_adc_config->resolution) { - case NRF_SAADC_RESOLUTION_8BIT: - res = 8; - break; - case NRF_SAADC_RESOLUTION_10BIT: - res = 10; - break; - case NRF_SAADC_RESOLUTION_12BIT: - res = 12; - break; - case NRF_SAADC_RESOLUTION_14BIT: - res = 14; - break; - default: - assert(0); - } - } else { - /* Default to 10-bit resolution. */ - res = 10; - } - - switch (cc->reference) { - case NRF_SAADC_REFERENCE_INTERNAL: - refmv = 600; /* 0.6V for NRF52 */ - break; - case NRF_SAADC_REFERENCE_VDD4: - refmv = bsp_get_refmv(NULL) / 4; - break; - default: - assert(0); - } - - /* Adjust reference voltage for gain. */ - switch (cc->gain) { - case NRF_SAADC_GAIN1_6: - refmv *= 6; - break; - case NRF_SAADC_GAIN1_5: - refmv *= 5; - break; - case NRF_SAADC_GAIN1_4: - refmv *= 4; - break; - case NRF_SAADC_GAIN1_3: - refmv *= 3; - break; - case NRF_SAADC_GAIN1_2: - refmv *= 2; - break; - case NRF_SAADC_GAIN2: - refmv /= 2; - break; - case NRF_SAADC_GAIN4: - refmv /= 4; - break; - default: - break; - } - - /* Store these values in channel definitions, for conversions to - * milivolts. - */ - dev->ad_chans[cnum].c_res = res; - dev->ad_chans[cnum].c_refmv = refmv; - dev->ad_chans[cnum].c_configured = 1; - - return (0); -err: - return (rc); -} - -/** - * Set buffer to read data into. Implementation of setbuffer handler. - * Sets both the primary and secondary buffers for DMA. - */ -static int -nrf52_adc_set_buffer(struct adc_dev *dev, void *buf1, void *buf2, - int buf_len) -{ - int rc; - - /* Convert overall buffer length, into a total number of samples which - * Nordic APIs expect. - */ - buf_len /= sizeof(nrf_saadc_value_t); - - rc = nrf_drv_saadc_buffer_convert((nrf_saadc_value_t *) buf1, buf_len); - if (rc != 0) { - goto err; - } - - if (buf2) { - rc = nrf_drv_saadc_buffer_convert((nrf_saadc_value_t *) buf2, - buf_len); - if (rc != 0) { - goto err; - } - } - return (0); -err: - return (rc); -} - -static int -nrf52_adc_release_buffer(struct adc_dev *dev, void *buf, int buf_len) -{ - int rc; - - buf_len /= sizeof(nrf_saadc_value_t); - - rc = nrf_drv_saadc_buffer_convert((nrf_saadc_value_t *) buf, buf_len); - if (rc != 0) { - goto err; - } - - return (0); -err: - return (rc); -} - -/** - * Trigger an ADC sample. - */ -static int -nrf52_adc_sample(struct adc_dev *dev) -{ - nrf_drv_saadc_sample(); - - return (0); -} - -/** - * Blocking read of an ADC channel, returns result as an integer. - */ -static int -nrf52_adc_read_channel(struct adc_dev *dev, uint8_t cnum, int *result) -{ - nrf_saadc_value_t adc_value; - int rc; - - rc = nrf_drv_saadc_sample_convert(cnum, &adc_value); - if (rc != 0) { - goto err; - } - - *result = (int) adc_value; - - return (0); -err: - return (rc); -} - -static int -nrf52_adc_read_buffer(struct adc_dev *dev, void *buf, int buf_len, int off, - int *result) -{ - nrf_saadc_value_t val; - int data_off; - - data_off = off * sizeof(nrf_saadc_value_t); - assert(data_off < buf_len); - - val = *(nrf_saadc_value_t *) ((uint8_t *) buf + data_off); - *result = val; - - return (0); -} - -static int -nrf52_adc_size_buffer(struct adc_dev *dev, int chans, int samples) -{ - return (sizeof(nrf_saadc_value_t) * chans * samples); -} - - -/** - * Callback to initialize an adc_dev structure from the os device - * initialization callback. This sets up a nrf52_adc_device(), so - * that subsequent lookups to this device allow us to manipulate it. - */ -int -nrf52_adc_dev_init(struct os_dev *odev, void *arg) -{ - struct adc_dev *dev; - struct adc_driver_funcs *af; - - dev = (struct adc_dev *) odev; - - os_mutex_init(&dev->ad_lock); - - dev->ad_chans = (void *) nrf52_adc_chans; - dev->ad_chan_count = NRF_SAADC_CHANNEL_COUNT; - - OS_DEV_SETHANDLERS(odev, nrf52_adc_open, nrf52_adc_close); - - af = &dev->ad_funcs; - - af->af_configure_channel = nrf52_adc_configure_channel; - af->af_sample = nrf52_adc_sample; - af->af_read_channel = nrf52_adc_read_channel; - af->af_set_buffer = nrf52_adc_set_buffer; - af->af_release_buffer = nrf52_adc_release_buffer; - af->af_read_buffer = nrf52_adc_read_buffer; - af->af_size_buffer = nrf52_adc_size_buffer; - - NVIC_SetVector(SAADC_IRQn, (uint32_t) SAADC_IRQHandler); - - return (0); -} - - http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0216c73e/drivers/adc/include/adc/adc.h ---------------------------------------------------------------------- diff --git a/drivers/adc/include/adc/adc.h b/drivers/adc/include/adc/adc.h deleted file mode 100644 index 2ffb6cd..0000000 --- a/drivers/adc/include/adc/adc.h +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. - */ - -#ifndef __ADC_H__ -#define __ADC_H__ - -#include - -struct adc_dev; - -/** - * Types of ADC events passed to the ADC driver. - */ -typedef enum { - /* This event represents the result of an ADC run. */ - ADC_EVENT_RESULT = 0 -} adc_event_type_t; - -/** - * Event handler for ADC events that are processed in asynchronous mode. - * - * @param The ADC device being processed - * @param The argument data passed to adc_set_result_handler() - * @param The event type - * @param The buffer containing event data - * @param The size in bytes of that buffer. - * - * @return 0 on success, non-zero error code on failure - */ -typedef int (*adc_event_handler_func_t)(struct adc_dev *, void *, - adc_event_type_t, void *, int); - -/** - * Configure an ADC channel for this ADC device. This is implemented - * by the HW specific drivers. - * - * @param The ADC device to configure - * @param The channel number to configure - * @param An opaque blob containing HW specific configuration. - * - * @return 0 on success, non-zero error code on failure. - */ -typedef int (*adc_configure_channel_func_t)(struct adc_dev *dev, uint8_t, - void *); - -/** - * Trigger a sample on the ADC device asynchronously. This is implemented - * by the HW specific drivers. - * - * @param The ADC device to sample - * - * @return 0 on success, non-zero error code on failure - */ -typedef int (*adc_sample_func_t)(struct adc_dev *); - -/** - * Blocking read of an ADC channel. This is implemented by the HW specific - * drivers. - * - * @param The ADC device to perform the blocking read on - * @param The channel to read - * @param The result to put the ADC reading into - * - * @return 0 on success, non-zero error code on failure - */ -typedef int (*adc_read_channel_func_t)(struct adc_dev *, uint8_t, int *); - -/** - * Set the buffer(s) to read ADC results into for non-blocking reads. This - * is implemented by the HW specific drivers. - * - * @param The ADC device to read results into - * @param The primary buffer to read results into - * @param The secondary buffer to read results into (for cases where - * DMA'ing occurs, and secondary buffer can be used while primary - * is being processed.) - * @param The length of both buffers in number of bytes - * - * @return 0 on success, non-zero error code on failure. - */ -typedef int (*adc_buf_set_func_t)(struct adc_dev *, void *, void *, int); - -/** - * Release a buffer for an ADC device, allowing the driver to re-use it for - * DMA'ing data. - * - * @param The ADC device to release the buffer to - * @param A pointer to the buffer to release - * @param The length of the buffer being released. - * - * @return 0 on success, non-zero error code on failure. - */ -typedef int (*adc_buf_release_func_t)(struct adc_dev *, void *, int); - -/** - * Read the next entry from an ADC buffer as a integer - * - * @param The ADC device to read the entry from - * @param The buffer to read the entry from - * @param The total length of the buffer - * @param The entry number to read from the buffer - * @param The result to put the entry into - * - * @return 0 on success, non-zero error code on failure. - */ -typedef int (*adc_buf_read_func_t)(struct adc_dev *, void *, int, int, int *); - -/** - * Get the size of a buffer - * - * @param The ADC device to get the buffer size from - * @param The number of channels in the buffer - * @param The number of samples in the buffer - * - * @return The size of the buffer - */ -typedef int (*adc_buf_size_func_t)(struct adc_dev *, int, int); - -struct adc_driver_funcs { - adc_configure_channel_func_t af_configure_channel; - adc_sample_func_t af_sample; - adc_read_channel_func_t af_read_channel; - adc_buf_set_func_t af_set_buffer; - adc_buf_release_func_t af_release_buffer; - adc_buf_read_func_t af_read_buffer; - adc_buf_size_func_t af_size_buffer; -}; - -struct adc_chan_config { - uint16_t c_refmv; - uint8_t c_res; - uint8_t c_configured; - uint8_t c_cnum; -}; - -struct adc_dev { - struct os_dev ad_dev; - struct os_mutex ad_lock; - struct adc_driver_funcs ad_funcs; - struct adc_chan_config *ad_chans; - int ad_chan_count; - adc_event_handler_func_t ad_event_handler_func; - void *ad_event_handler_arg; -}; - -int adc_chan_config(struct adc_dev *, uint8_t, void *); -int adc_chan_read(struct adc_dev *, uint8_t, int *); -int adc_event_handler_set(struct adc_dev *, adc_event_handler_func_t, - void *); - -/** - * Sample the device specified by dev. This is used in non-blocking mode - * to generate samples into the event buffer. - * - * @param dev The device to sample - * - * @return 0 on success, non-zero on failure - */ -static inline int -adc_sample(struct adc_dev *dev) -{ - return (dev->ad_funcs.af_sample(dev)); -} - -/** - * Set a result buffer to store data into. Optionally, provide a - * second buffer to continue writing data into as the first buffer - * fills up. Both buffers must be the same size. - * - * @param dev The ADC device to set the buffer for - * @param buf1 The first buffer to spool data into - * @param buf2 The second buffer to spool data into, while the first - * buffer is being processed. If NULL is provided, it's - * unused. - * @param buf_len The length of both buffers, in bytes. - * - * @return 0 on success, non-zero on failure. - */ -static inline int -adc_buf_set(struct adc_dev *dev, void *buf1, void *buf2, - int buf_len) -{ - return (dev->ad_funcs.af_set_buffer(dev, buf1, buf2, buf_len)); -} - -/** - * Release a result buffer on the ADC device, and allow for it to be - * re-used for DMA'ing results. - * - * @param dev The device to release the buffer for - * @param buf The buffer to release - * @param buf_len The length of the buffer being released. - * - * @return 0 on success, non-zero error code on failure. - */ -static inline int -adc_buf_release(struct adc_dev *dev, void *buf, int buf_len) -{ - return (dev->ad_funcs.af_release_buffer(dev, buf, buf_len)); -} - -/** - * Read an entry from an ADC buffer - * - * @param dev The device that the entry is being read from - * @param buf The buffer that we're reading the entry from - * @param buf_len The length of the buffer we're reading the entry from - * @param off The entry number to read from the buffer - * @param result A pointer to the result to store the data in - * - * @return 0 on success, non-zero error code on failure - */ -static inline int -adc_buf_read(struct adc_dev *dev, void *buf, int buf_len, int entry, - int *result) -{ - return (dev->ad_funcs.af_read_buffer(dev, buf, buf_len, entry, result)); -} - -/** - * Return the size of an ADC buffer - * - * @param dev The ADC device to return the buffer size from - * @param channels The number of channels for these samples - * @param samples The number of SAMPLES on this ADC device - * - * @return The size of the resulting buffer - */ -static inline int -adc_buf_size(struct adc_dev *dev, int chans, int samples) -{ - return (dev->ad_funcs.af_size_buffer(dev, chans, samples)); -} - -/** - * Take an ADC result and convert it to millivolts. - * - * @param dev The ADC dev to convert the result on - * @param cnum The channel number to convert the result from - * @param val The ADC value to convert to millivolts - * - * @return The convert value in millivolts - */ -static inline int -adc_result_mv(struct adc_dev *dev, uint8_t cnum, int val) -{ - int res; - int refmv; - int ret; - - refmv = (int) dev->ad_chans[cnum].c_refmv; - res = (int) dev->ad_chans[cnum].c_res; - - ret = val * refmv; - ret += (1 << (res - 2)); - ret = ret >> res; - - return (ret); -} - -#endif /* __ADC_H__ */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0216c73e/drivers/adc/pkg.yml ---------------------------------------------------------------------- diff --git a/drivers/adc/pkg.yml b/drivers/adc/pkg.yml deleted file mode 100644 index bf0205a..0000000 --- a/drivers/adc/pkg.yml +++ /dev/null @@ -1,26 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. -# - -pkg.name: drivers/adc -pkg.description: ADC driver interfaces -pkg.author: "Apache Mynewt " -pkg.homepage: "http://mynewt.apache.org/" -pkg.keywords: -pkg.req_apis: - - ADC_HW_IMPL