LCOV - code coverage report
Current view: top level - ec - ec2_oct.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 82 164 50.0 %
Date: 2014-08-02 Functions: 2 3 66.7 %
Branches: 50 148 33.8 %

           Branch data     Line data    Source code
       1                 :            : /* crypto/ec/ec2_oct.c */
       2                 :            : /* ====================================================================
       3                 :            :  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
       4                 :            :  *
       5                 :            :  * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
       6                 :            :  * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
       7                 :            :  * to the OpenSSL project.
       8                 :            :  *
       9                 :            :  * The ECC Code is licensed pursuant to the OpenSSL open source
      10                 :            :  * license provided below.
      11                 :            :  *
      12                 :            :  * The software is originally written by Sheueling Chang Shantz and
      13                 :            :  * Douglas Stebila of Sun Microsystems Laboratories.
      14                 :            :  *
      15                 :            :  */
      16                 :            : /* ====================================================================
      17                 :            :  * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
      18                 :            :  *
      19                 :            :  * Redistribution and use in source and binary forms, with or without
      20                 :            :  * modification, are permitted provided that the following conditions
      21                 :            :  * are met:
      22                 :            :  *
      23                 :            :  * 1. Redistributions of source code must retain the above copyright
      24                 :            :  *    notice, this list of conditions and the following disclaimer. 
      25                 :            :  *
      26                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      27                 :            :  *    notice, this list of conditions and the following disclaimer in
      28                 :            :  *    the documentation and/or other materials provided with the
      29                 :            :  *    distribution.
      30                 :            :  *
      31                 :            :  * 3. All advertising materials mentioning features or use of this
      32                 :            :  *    software must display the following acknowledgment:
      33                 :            :  *    "This product includes software developed by the OpenSSL Project
      34                 :            :  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
      35                 :            :  *
      36                 :            :  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
      37                 :            :  *    endorse or promote products derived from this software without
      38                 :            :  *    prior written permission. For written permission, please contact
      39                 :            :  *    openssl-core@openssl.org.
      40                 :            :  *
      41                 :            :  * 5. Products derived from this software may not be called "OpenSSL"
      42                 :            :  *    nor may "OpenSSL" appear in their names without prior written
      43                 :            :  *    permission of the OpenSSL Project.
      44                 :            :  *
      45                 :            :  * 6. Redistributions of any form whatsoever must retain the following
      46                 :            :  *    acknowledgment:
      47                 :            :  *    "This product includes software developed by the OpenSSL Project
      48                 :            :  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
      49                 :            :  *
      50                 :            :  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
      51                 :            :  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      52                 :            :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      53                 :            :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
      54                 :            :  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      55                 :            :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      56                 :            :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
      57                 :            :  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      58                 :            :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
      59                 :            :  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      60                 :            :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
      61                 :            :  * OF THE POSSIBILITY OF SUCH DAMAGE.
      62                 :            :  * ====================================================================
      63                 :            :  *
      64                 :            :  * This product includes cryptographic software written by Eric Young
      65                 :            :  * (eay@cryptsoft.com).  This product includes software written by Tim
      66                 :            :  * Hudson (tjh@cryptsoft.com).
      67                 :            :  *
      68                 :            :  */
      69                 :            : 
      70                 :            : #include <openssl/err.h>
      71                 :            : 
      72                 :            : #include "ec_lcl.h"
      73                 :            : 
      74                 :            : #ifndef OPENSSL_NO_EC2M
      75                 :            : 
      76                 :            : /* Calculates and sets the affine coordinates of an EC_POINT from the given
      77                 :            :  * compressed coordinates.  Uses algorithm 2.3.4 of SEC 1. 
      78                 :            :  * Note that the simple implementation only uses affine coordinates.
      79                 :            :  *
      80                 :            :  * The method is from the following publication:
      81                 :            :  * 
      82                 :            :  *     Harper, Menezes, Vanstone:
      83                 :            :  *     "Public-Key Cryptosystems with Very Small Key Lengths",
      84                 :            :  *     EUROCRYPT '92, Springer-Verlag LNCS 658,
      85                 :            :  *     published February 1993
      86                 :            :  *
      87                 :            :  * US Patents 6,141,420 and 6,618,483 (Vanstone, Mullin, Agnew) describe
      88                 :            :  * the same method, but claim no priority date earlier than July 29, 1994
      89                 :            :  * (and additionally fail to cite the EUROCRYPT '92 publication as prior art).
      90                 :            :  */
      91                 :          0 : int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
      92                 :            :         const BIGNUM *x_, int y_bit, BN_CTX *ctx)
      93                 :            :         {
      94                 :          0 :         BN_CTX *new_ctx = NULL;
      95                 :            :         BIGNUM *tmp, *x, *y, *z;
      96                 :          0 :         int ret = 0, z0;
      97                 :            : 
      98                 :            :         /* clear error queue */
      99                 :          0 :         ERR_clear_error();
     100                 :            : 
     101         [ #  # ]:          0 :         if (ctx == NULL)
     102                 :            :                 {
     103                 :          0 :                 ctx = new_ctx = BN_CTX_new();
     104         [ #  # ]:          0 :                 if (ctx == NULL)
     105                 :            :                         return 0;
     106                 :            :                 }
     107                 :            : 
     108                 :          0 :         y_bit = (y_bit != 0) ? 1 : 0;
     109                 :            : 
     110                 :          0 :         BN_CTX_start(ctx);
     111                 :          0 :         tmp = BN_CTX_get(ctx);
     112                 :          0 :         x = BN_CTX_get(ctx);
     113                 :          0 :         y = BN_CTX_get(ctx);
     114                 :          0 :         z = BN_CTX_get(ctx);
     115         [ #  # ]:          0 :         if (z == NULL) goto err;
     116                 :            : 
     117         [ #  # ]:          0 :         if (!BN_GF2m_mod_arr(x, x_, group->poly)) goto err;
     118         [ #  # ]:          0 :         if (BN_is_zero(x))
     119                 :            :                 {
     120         [ #  # ]:          0 :                 if (!BN_GF2m_mod_sqrt_arr(y, &group->b, group->poly, ctx)) goto err;
     121                 :            :                 }
     122                 :            :         else
     123                 :            :                 {
     124         [ #  # ]:          0 :                 if (!group->meth->field_sqr(group, tmp, x, ctx)) goto err;
     125         [ #  # ]:          0 :                 if (!group->meth->field_div(group, tmp, &group->b, tmp, ctx)) goto err;
     126         [ #  # ]:          0 :                 if (!BN_GF2m_add(tmp, &group->a, tmp)) goto err;
     127         [ #  # ]:          0 :                 if (!BN_GF2m_add(tmp, x, tmp)) goto err;
     128         [ #  # ]:          0 :                 if (!BN_GF2m_mod_solve_quad_arr(z, tmp, group->poly, ctx))
     129                 :            :                         {
     130                 :          0 :                         unsigned long err = ERR_peek_last_error();
     131                 :            :                         
     132 [ #  # ][ #  # ]:          0 :                         if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NO_SOLUTION)
     133                 :            :                                 {
     134                 :          0 :                                 ERR_clear_error();
     135                 :          0 :                                 ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
     136                 :            :                                 }
     137                 :            :                         else
     138                 :          0 :                                 ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB);
     139                 :            :                         goto err;
     140                 :            :                         }
     141 [ #  # ][ #  # ]:          0 :                 z0 = (BN_is_odd(z)) ? 1 : 0;
     142         [ #  # ]:          0 :                 if (!group->meth->field_mul(group, y, x, z, ctx)) goto err;
     143         [ #  # ]:          0 :                 if (z0 != y_bit)
     144                 :            :                         {
     145         [ #  # ]:          0 :                         if (!BN_GF2m_add(y, y, x)) goto err;
     146                 :            :                         }
     147                 :            :                 }
     148                 :            : 
     149         [ #  # ]:          0 :         if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
     150                 :            : 
     151                 :          0 :         ret = 1;
     152                 :            : 
     153                 :            :  err:
     154                 :          0 :         BN_CTX_end(ctx);
     155         [ #  # ]:          0 :         if (new_ctx != NULL)
     156                 :          0 :                 BN_CTX_free(new_ctx);
     157                 :          0 :         return ret;
     158                 :            :         }
     159                 :            : 
     160                 :            : 
     161                 :            : /* Converts an EC_POINT to an octet string.  
     162                 :            :  * If buf is NULL, the encoded length will be returned.
     163                 :            :  * If the length len of buf is smaller than required an error will be returned.
     164                 :            :  */
     165                 :       1852 : size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
     166                 :            :         unsigned char *buf, size_t len, BN_CTX *ctx)
     167                 :            :         {
     168                 :            :         size_t ret;
     169                 :       1852 :         BN_CTX *new_ctx = NULL;
     170                 :       1852 :         int used_ctx = 0;
     171                 :            :         BIGNUM *x, *y, *yxi;
     172                 :            :         size_t field_len, i, skip;
     173                 :            : 
     174         [ -  + ]:       1852 :         if ((form != POINT_CONVERSION_COMPRESSED)
     175                 :       1852 :                 && (form != POINT_CONVERSION_UNCOMPRESSED)
     176         [ #  # ]:          0 :                 && (form != POINT_CONVERSION_HYBRID))
     177                 :            :                 {
     178                 :          0 :                 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
     179                 :          0 :                 goto err;
     180                 :            :                 }
     181                 :            : 
     182         [ -  + ]:       1852 :         if (EC_POINT_is_at_infinity(group, point))
     183                 :            :                 {
     184                 :            :                 /* encodes to a single 0 octet */
     185         [ #  # ]:          0 :                 if (buf != NULL)
     186                 :            :                         {
     187         [ #  # ]:          0 :                         if (len < 1)
     188                 :            :                                 {
     189                 :          0 :                                 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
     190                 :          0 :                                 return 0;
     191                 :            :                                 }
     192                 :          0 :                         buf[0] = 0;
     193                 :            :                         }
     194                 :            :                 return 1;
     195                 :            :                 }
     196                 :            : 
     197                 :            : 
     198                 :            :         /* ret := required output buffer length */
     199                 :       1852 :         field_len = (EC_GROUP_get_degree(group) + 7) / 8;
     200         [ -  + ]:       1852 :         ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
     201                 :            : 
     202                 :            :         /* if 'buf' is NULL, just return required length */
     203         [ +  + ]:       1852 :         if (buf != NULL)
     204                 :            :                 {
     205         [ -  + ]:        926 :                 if (len < ret)
     206                 :            :                         {
     207                 :          0 :                         ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
     208                 :          0 :                         goto err;
     209                 :            :                         }
     210                 :            : 
     211         [ +  + ]:        926 :                 if (ctx == NULL)
     212                 :            :                         {
     213                 :          1 :                         ctx = new_ctx = BN_CTX_new();
     214         [ +  - ]:          1 :                         if (ctx == NULL)
     215                 :            :                                 return 0;
     216                 :            :                         }
     217                 :            : 
     218                 :        926 :                 BN_CTX_start(ctx);
     219                 :        926 :                 used_ctx = 1;
     220                 :        926 :                 x = BN_CTX_get(ctx);
     221                 :        926 :                 y = BN_CTX_get(ctx);
     222                 :        926 :                 yxi = BN_CTX_get(ctx);
     223         [ +  - ]:        926 :                 if (yxi == NULL) goto err;
     224                 :            : 
     225         [ +  - ]:        926 :                 if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
     226                 :            : 
     227                 :        926 :                 buf[0] = form;
     228 [ -  + ][ #  # ]:        926 :                 if ((form != POINT_CONVERSION_UNCOMPRESSED) && !BN_is_zero(x))
     229                 :            :                         {
     230         [ #  # ]:          0 :                         if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err;
     231 [ #  # ][ #  # ]:          0 :                         if (BN_is_odd(yxi)) buf[0]++;
     232                 :            :                         }
     233                 :            : 
     234                 :        926 :                 i = 1;
     235                 :            :                 
     236                 :        926 :                 skip = field_len - BN_num_bytes(x);
     237         [ +  - ]:        926 :                 if (skip > field_len)
     238                 :            :                         {
     239                 :          0 :                         ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
     240                 :          0 :                         goto err;
     241                 :            :                         }
     242         [ +  + ]:       1040 :                 while (skip > 0)
     243                 :            :                         {
     244                 :        114 :                         buf[i++] = 0;
     245                 :        114 :                         skip--;
     246                 :            :                         }
     247                 :        926 :                 skip = BN_bn2bin(x, buf + i);
     248                 :        926 :                 i += skip;
     249         [ -  + ]:        926 :                 if (i != 1 + field_len)
     250                 :            :                         {
     251                 :          0 :                         ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
     252                 :          0 :                         goto err;
     253                 :            :                         }
     254                 :            : 
     255         [ +  - ]:        926 :                 if (form == POINT_CONVERSION_UNCOMPRESSED || form == POINT_CONVERSION_HYBRID)
     256                 :            :                         {
     257                 :        926 :                         skip = field_len - BN_num_bytes(y);
     258         [ +  - ]:        926 :                         if (skip > field_len)
     259                 :            :                                 {
     260                 :          0 :                                 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
     261                 :          0 :                                 goto err;
     262                 :            :                                 }
     263         [ +  + ]:       1028 :                         while (skip > 0)
     264                 :            :                                 {
     265                 :        102 :                                 buf[i++] = 0;
     266                 :        102 :                                 skip--;
     267                 :            :                                 }
     268                 :        926 :                         skip = BN_bn2bin(y, buf + i);
     269                 :        926 :                         i += skip;
     270                 :            :                         }
     271                 :            : 
     272         [ -  + ]:        926 :                 if (i != ret)
     273                 :            :                         {
     274                 :          0 :                         ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
     275                 :          0 :                         goto err;
     276                 :            :                         }
     277                 :            :                 }
     278                 :            :         
     279         [ +  + ]:       1852 :         if (used_ctx)
     280                 :        926 :                 BN_CTX_end(ctx);
     281         [ +  + ]:       1852 :         if (new_ctx != NULL)
     282                 :          1 :                 BN_CTX_free(new_ctx);
     283                 :       1852 :         return ret;
     284                 :            : 
     285                 :            :  err:
     286         [ #  # ]:          0 :         if (used_ctx)
     287                 :          0 :                 BN_CTX_end(ctx);
     288         [ #  # ]:          0 :         if (new_ctx != NULL)
     289                 :          0 :                 BN_CTX_free(new_ctx);
     290                 :            :         return 0;
     291                 :            :         }
     292                 :            : 
     293                 :            : 
     294                 :            : /* Converts an octet string representation to an EC_POINT. 
     295                 :            :  * Note that the simple implementation only uses affine coordinates.
     296                 :            :  */
     297                 :        929 : int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
     298                 :            :         const unsigned char *buf, size_t len, BN_CTX *ctx)
     299                 :            :         {
     300                 :            :         point_conversion_form_t form;
     301                 :            :         int y_bit;
     302                 :        929 :         BN_CTX *new_ctx = NULL;
     303                 :            :         BIGNUM *x, *y, *yxi;
     304                 :            :         size_t field_len, enc_len;
     305                 :        929 :         int ret = 0;
     306                 :            : 
     307         [ -  + ]:        929 :         if (len == 0)
     308                 :            :                 {
     309                 :          0 :                 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
     310                 :          0 :                 return 0;
     311                 :            :                 }
     312                 :        929 :         form = buf[0];
     313                 :        929 :         y_bit = form & 1;
     314                 :        929 :         form = form & ~1U;
     315         [ +  + ]:        929 :         if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
     316                 :        928 :                 && (form != POINT_CONVERSION_UNCOMPRESSED)
     317         [ -  + ]:        928 :                 && (form != POINT_CONVERSION_HYBRID))
     318                 :            :                 {
     319                 :          0 :                 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
     320                 :          0 :                 return 0;
     321                 :            :                 }
     322 [ +  - ][ -  + ]:        929 :         if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit)
     323                 :            :                 {
     324                 :          0 :                 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
     325                 :          0 :                 return 0;
     326                 :            :                 }
     327                 :            : 
     328         [ +  + ]:        929 :         if (form == 0)
     329                 :            :                 {
     330         [ -  + ]:          1 :                 if (len != 1)
     331                 :            :                         {
     332                 :          0 :                         ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
     333                 :          0 :                         return 0;
     334                 :            :                         }
     335                 :            : 
     336                 :          1 :                 return EC_POINT_set_to_infinity(group, point);
     337                 :            :                 }
     338                 :            :         
     339                 :        928 :         field_len = (EC_GROUP_get_degree(group) + 7) / 8;
     340         [ -  + ]:        928 :         enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
     341                 :            : 
     342         [ -  + ]:        928 :         if (len != enc_len)
     343                 :            :                 {
     344                 :          0 :                 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
     345                 :          0 :                 return 0;
     346                 :            :                 }
     347                 :            : 
     348         [ +  + ]:        928 :         if (ctx == NULL)
     349                 :            :                 {
     350                 :          3 :                 ctx = new_ctx = BN_CTX_new();
     351         [ +  - ]:          3 :                 if (ctx == NULL)
     352                 :            :                         return 0;
     353                 :            :                 }
     354                 :            : 
     355                 :        928 :         BN_CTX_start(ctx);
     356                 :        928 :         x = BN_CTX_get(ctx);
     357                 :        928 :         y = BN_CTX_get(ctx);
     358                 :        928 :         yxi = BN_CTX_get(ctx);
     359         [ +  - ]:        928 :         if (yxi == NULL) goto err;
     360                 :            : 
     361         [ +  - ]:        928 :         if (!BN_bin2bn(buf + 1, field_len, x)) goto err;
     362         [ -  + ]:        928 :         if (BN_ucmp(x, &group->field) >= 0)
     363                 :            :                 {
     364                 :          0 :                 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
     365                 :          0 :                 goto err;
     366                 :            :                 }
     367                 :            : 
     368         [ -  + ]:        928 :         if (form == POINT_CONVERSION_COMPRESSED)
     369                 :            :                 {
     370         [ #  # ]:          0 :                 if (!EC_POINT_set_compressed_coordinates_GF2m(group, point, x, y_bit, ctx)) goto err;
     371                 :            :                 }
     372                 :            :         else
     373                 :            :                 {
     374         [ +  - ]:        928 :                 if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) goto err;
     375         [ -  + ]:        928 :                 if (BN_ucmp(y, &group->field) >= 0)
     376                 :            :                         {
     377                 :          0 :                         ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
     378                 :          0 :                         goto err;
     379                 :            :                         }
     380         [ -  + ]:        928 :                 if (form == POINT_CONVERSION_HYBRID)
     381                 :            :                         {
     382         [ #  # ]:          0 :                         if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err;
     383 [ #  # ][ #  # ]:          0 :                         if (y_bit != BN_is_odd(yxi))
                 [ #  # ]
     384                 :            :                                 {
     385                 :          0 :                                 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
     386                 :          0 :                                 goto err;
     387                 :            :                                 }
     388                 :            :                         }
     389                 :            : 
     390         [ +  - ]:        928 :                 if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
     391                 :            :                 }
     392                 :            :         
     393         [ -  + ]:        928 :         if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */
     394                 :            :                 {
     395                 :          0 :                 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
     396                 :          0 :                 goto err;
     397                 :            :                 }
     398                 :            : 
     399                 :            :         ret = 1;
     400                 :            :         
     401                 :            :  err:
     402                 :        928 :         BN_CTX_end(ctx);
     403         [ +  + ]:        928 :         if (new_ctx != NULL)
     404                 :          3 :                 BN_CTX_free(new_ctx);
     405                 :        928 :         return ret;
     406                 :            :         }
     407                 :            : #endif

Generated by: LCOV version 1.9