aboutsummaryrefslogblamecommitdiff
path: root/rpc_client_daemon.c
blob: f3283027c5b283711dba4e277d456c16b545510d (plain) (tree)
























































































                                                                                     
/*
 * rpc_client_daemon.c
 * -------------------
 * Remote procedure call transport over a socket to a daemon.
 *
 * Copyright (c) 2016, NORDUnet A/S 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 the NORDUnet 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
 * 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.
 */

#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <unistd.h>
#include <sys/un.h>

#include "hal.h"
#include "hal_internal.h"

#ifndef SOCKET_NAME
#define SOCKET_NAME "/tmp/cryptechd.socket"
#endif

static int sock = -1;

hal_error_t hal_rpc_client_transport_init(void)
{
    struct sockaddr_un name;
    int ret;

    sock = socket(AF_UNIX, SOCK_SEQPACKET, 0);
    if (sock == -1)
        return perror("socket"), HAL_ERROR_RPC_TRANSPORT;
    memset(&name, 0, sizeof(struct sockaddr_un));
    name.sun_family = AF_UNIX;
    strncpy(name.sun_path, SOCKET_NAME, sizeof(name.sun_path) - 1);
    ret = connect(sock, (const struct sockaddr *) &name, sizeof(struct sockaddr_un));
    if (ret == -1)
        return perror("connect"), HAL_ERROR_RPC_TRANSPORT;
    return HAL_OK;
}

hal_error_t hal_rpc_client_transport_close(void)
{
    int ret = close(sock);
    sock = -1;
    if (ret != 0)
        return perror("close"), HAL_ERROR_RPC_TRANSPORT;
    return HAL_OK;
}

hal_error_t hal_rpc_send(const uint8_t * const buf, const size_t len)
{
    ssize_t ret = send(sock, (const void *)buf, len, 0);
    return (ret == -1) ? HAL_ERROR_RPC_TRANSPORT : HAL_OK;
}

hal_error_t hal_rpc_recv(uint8_t * const buf, size_t * const len)
{
    ssize_t ret = recv(sock, (void *)buf, *len, 0);
    if (ret == -1)
	return HAL_ERROR_RPC_TRANSPORT;
    *len = (size_t)ret;
    return HAL_OK;
}
ing-right: 5px; } .highlight .hll { background-color: #ffffcc } .highlight .c { color: #888888 } /* Comment */ .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .highlight .k { color: #008800; font-weight: bold } /* Keyword */ .highlight .ch { color: #888888 } /* Comment.Hashbang */ .highlight .cm { color: #888888 } /* Comment.Multiline */ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
# Test vectors from "Suite B Implementer's Guide to FIPS 186-3".
#
# e is given in decimal, all other values are hex, because that's how
# these were given in the paper

p256_d    = 0x70a12c2db16845ed56ff68cfc21a472b3f04d7d6851bf6349f2d7d5b3452b38a
p256_Qx   = 0x8101ece47464a6ead70cf69a6e2bd3d88691a3262d22cba4f7635eaff26680a8
p256_Qy   = 0xd8a12ba61d599235f67d9cb4d58f1783d3ca43e78f0a5abaa624079936c0c3a9
p256_k    = 0x580ec00d856434334cef3f71ecaed4965b12ae37fa47055b1965c7b134ee45d0
p256_kinv = 0x6a664fa115356d33f16331b54c4e7ce967965386c7dcbf2904604d0c132b4a74
p256_Rx   = 0x7214bc9647160bbd39ff2f80533f5dc6ddd70ddf86bb815661e805d5d4e6f27c
p256_Ry   = 0x8b81e3e977597110c7cf2633435b2294b72642987defd3d4007e1cfc5df84541
p256_r    = p256_Rx
p256_M    = 0x54686973206973206f6e6c7920612074657374206d6573736167652e204974206973203438206279746573206c6f6e67
p256_H    = 0x7c3e883ddc8bd688f96eac5e9324222c8f30f9d6bb59e9c5f020bd39ba2b8377
p256_e    = 56197278047627432394583341962843287937266210957576322469816113796290471232375
p256_s    = 0x7d1ff961980f961bdaa3233b6209f4013317d3e3f9e1493592dbeaa1af2bc367
p256_w    = 0xd69be75f67ee5394cabb6c286f3610cf62d722cba9eea70faee770a6b2ed72dc
p256_u1   = 0xbb252401d6fb322bb747184cf2ac52bf8d54b95a1515062a2f6141f2e2092ed8
p256_u2   = 0xaae7d1c7f2c232dfc641948af3dba141d4de8634e571cf84c486301b510cfc04
p256_v    = 0x7214bc9647160bbd39ff2f80533f5dc6ddd70ddf86bb815661e805d5d4e6f27c

p384_d    = 0xc838b85253ef8dc7394fa5808a5183981c7deef5a69ba8f4f2117ffea39cfcd90e95f6cbc854abacab701d50c1f3cf24
p384_Qx   = 0x1fbac8eebd0cbf35640b39efe0808dd774debff20a2a329e91713baf7d7f3c3e81546d883730bee7e48678f857b02ca0
p384_Qy   = 0xeb213103bd68ce343365a8a4c3d4555fa385f5330203bdd76ffad1f3affb95751c132007e1b240353cb0a4cf1693bdf9
p384_k    = 0xdc6b44036989a196e39d1cdac000812f4bdd8b2db41bb33af51372585ebd1db63f0ce8275aa1fd45e2d2a735f8749359
p384_kinv = 0x7436f03088e65c37ba8e7b33887fbc87757514d611f7d1fbdf6d2104a297ad318cdbf7404e4ba37e599666df37b8d8be
p384_Rx   = 0xa0c27ec893092dea1e1bd2ccfed3cf945c8134ed0c9f81311a0f4a05942db8dbed8dd59f267471d5462aa14fe72de856
p384_Ry   = 0x855649409815bb91424eaca5fd76c97375d575d1422ec53d343bd33b847fdf0c11569685b528ab25493015428d7cf72b
p384_r    = p384_Rx
p384_M    = 0x54686973206973206f6e6c7920612074657374206d6573736167652e204974206973203438206279746573206c6f6e67
p384_H    = 0xb9210c9d7e20897ab86597266a9d5077e8db1b06f7220ed6ee75bd8b45db37891f8ba5550304004159f4453dc5b3f5a1
p384_e    = 28493976155450475404302482243066463769180620629462008675793884393889401828800663731864240088367206094074919580333473
p384_s    = 0x20ab3f45b74f10b6e11f96a2c8eb694d206b9dda86d3c7e331c26b22c987b7537726577667adadf168ebbe803794a402
p384_w    = 0x1798845cd0a6cea5327c501a71a4baf2f7be882cfbc303750a7c861af8fe8225467a257f5bf91a4aaa5a79a8637d218a
p384_u1   = 0x6ce25649d42d223e020c11140fe772326612bb11b686d35ee98ed4550e0635d9dd3a2afbca0cf2c4baedcd23313b189e
p384_u2   = 0xf3b240751d5d8ed394a4b5bf8e2a4c0e1e21aa51f2620a08b8c55a2bc334c9689923162648f06e5f4659fc526d9c1fd6
p384_v    = 0xa0c27ec893092dea1e1bd2ccfed3cf945c8134ed0c9f81311a0f4a05942db8dbed8dd59f267471d5462aa14fe72de856

from textwrap                   import TextWrapper
from os.path                    import basename
from sys                        import argv
from pyasn1.type.univ           import Sequence, Choice, Integer, OctetString, ObjectIdentifier, BitString
from pyasn1.type.namedtype      import NamedTypes, NamedType, OptionalNamedType
from pyasn1.type.namedval       import NamedValues
from pyasn1.type.tag            import Tag, tagClassContext, tagFormatSimple
from pyasn1.type.constraint     import SingleValueConstraint
from pyasn1.codec.der.encoder   import encode as DER_Encode
from pyasn1.codec.der.decoder   import decode as DER_Decode

wrapper = TextWrapper(width = 78, initial_indent = " " * 2, subsequent_indent = " " * 2)

def long_to_bytes(number, order):
  #
  # This is just plain nasty.
  #
  s = "%x" % number
  s = ("0" * (order/8 - len(s))) + s
  return s.decode("hex")

def bytes_to_bits(bytes):
  #
  # This, on the other hand, is not just plain nasty, this is fancy nasty.
  # This is nasty with raisins in it.
  #
  s = bin(long(bytes.encode("hex"), 16))[2:]
  if len(s) % 8:
    s = ("0" * (8 - len(s) % 8)) + s
  return tuple(int(i) for i in s)

###

def encode_sig(r, s, order):
  return long_to_bytes(r, order) + long_to_bytes(s, order)

p256_sig = encode_sig(p256_r, p256_s, 256)
p384_sig = encode_sig(p384_r, p384_s, 384)

###

class ECPrivateKey(Sequence):
  componentType = NamedTypes(
    NamedType("version", Integer(namedValues = NamedValues(("ecPrivkeyVer1", 1))
                                 ).subtype(subtypeSpec = Integer.subtypeSpec + SingleValueConstraint(1))),
    NamedType("privateKey", OctetString()),
    OptionalNamedType("parameters", ObjectIdentifier().subtype(explicitTag = Tag(tagClassContext, tagFormatSimple, 0))),
    OptionalNamedType("publicKey", BitString().subtype(explicitTag = Tag(tagClassContext, tagFormatSimple, 1))))

def encode_key(d, Qx, Qy, order, oid):
  private_key = long_to_bytes(d, order)
  public_key  = bytes_to_bits(chr(0x04) + long_to_bytes(Qx, order) + long_to_bytes(Qy, order))
  parameters = oid
  key = ECPrivateKey()
  key["version"]    = 1
  key["privateKey"] = private_key
  key["parameters"] = parameters
  key["publicKey"]  = public_key
  return DER_Encode(key)

p256_key = encode_key(p256_d, p256_Qx, p256_Qy, 256, "1.2.840.10045.3.1.7")
p384_key = encode_key(p384_d, p384_Qx, p384_Qy, 384, "1.3.132.0.34")

###

print "/*"
print " * ECDSA test data."
print " * File automatically generated by", basename(argv[0])
print " */"

curves = ("p256", "p384")
vars   = set()

for name in dir():
  head, sep, tail = name.partition("_")
  if head in curves:
    vars.add(tail)

vars = sorted(vars)

for curve in curves:
  order = int(curve[1:])
  for var in vars:
    name = curve + "_" + var
    value = globals().get(name, None)
    if isinstance(value, (int, long)):
      value = long_to_bytes(value, order)
    if value is not None:
      print
      print "static const uint8_t %s[] = { /* %d bytes */" % (name, len(value))
      print wrapper.fill(", ".join("0x%02x" % ord(v) for v in value))
      print "};"

print
print "typedef struct {"
print "  hal_curve_name_t curve;"
for var in vars:
  print "  const uint8_t *%8s; size_t %8s_len;" % (var, var)
print "} ecdsa_tc_t;"
print
print "static const ecdsa_tc_t ecdsa_tc[] = {"
for curve in curves:
  print "  { HAL_CURVE_%s," % curve.upper()
  for var in vars:
    name = curve + "_" + var
    if name in globals():
      print "    %-14s sizeof(%s)," % (name + ",", name)
    else:
      print "    %-14s 0," % "NULL,"
  print "  },"
print "};"