<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Generator" content="Microsoft Word 14 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:Wingdings;
        panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
        {font-family:Wingdings;
        panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Consolas;
        panose-1:2 11 6 9 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri","sans-serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
span.EmailStyle17
        {mso-style-type:personal-compose;
        font-family:"Calibri","sans-serif";
        color:windowtext;
        font-weight:normal;
        font-style:normal;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;
        font-family:"Calibri","sans-serif";}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal">Hi,<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">We have observed memory leak when we register for ECDH callback(SSL_set_tmp_ecdh_callback<span style="font-size:10.0pt;font-family:Consolas;color:black">).
</span>While performing negative testing with load we find that the applications starts leaking memory. 
<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Further checking the Openssl implementation in the s3_srvr.c file (openssl version 1.0.2). I find that a pointer is not deleted after copying EC_KEY from the application or EC_KEY_new being called.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I suspect the below code.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">if (type & SSL_kEECDH) {<o:p></o:p></p>
<p class="MsoNormal">            const EC_GROUP *group;<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">            ecdhp = cert->ecdh_tmp;<o:p></o:p></p>
<p class="MsoNormal">            <b><span style="background:yellow;mso-highlight:yellow">if (s->cert->ecdh_tmp_auto) {<o:p></o:p></span></b></p>
<p class="MsoNormal"><b><span style="background:yellow;mso-highlight:yellow">                /* Get NID of appropriate shared curve */<o:p></o:p></span></b></p>
<p class="MsoNormal"><b><span style="background:yellow;mso-highlight:yellow">                int nid = tls1_shared_curve(s, -2);<o:p></o:p></span></b></p>
<p class="MsoNormal"><b><span style="background:yellow;mso-highlight:yellow">                if (nid != NID_undef)<o:p></o:p></span></b></p>
<p class="MsoNormal"><b><span style="background:yellow;mso-highlight:yellow">                    ecdhp = EC_KEY_new_by_curve_name(nid);
</span></b><b><span style="font-family:Wingdings;background:yellow;mso-highlight:yellow">ß</span></b><b><span style="background:yellow;mso-highlight:yellow"> Even memory allocated in this case is not de-allocated.</span></b><b><o:p></o:p></b></p>
<p class="MsoNormal">            } else if ((ecdhp == NULL) && s->cert->ecdh_tmp_cb) {<o:p></o:p></p>
<p class="MsoNormal">                <b><span style="background:yellow;mso-highlight:yellow">ecdhp = s->cert->ecdh_tmp_cb(s,                                                          
</span></b><b><span style="font-family:Wingdings;background:yellow;mso-highlight:yellow">ß</span></b><b><span style="background:yellow;mso-highlight:yellow"> Application is responsible for the EC_KEY and its memory<o:p></o:p></span></b></p>
<p class="MsoNormal"><b><span style="background:yellow;mso-highlight:yellow">                                             SSL_C_IS_EXPORT(s->s3-><o:p></o:p></span></b></p>
<p class="MsoNormal"><b><span style="background:yellow;mso-highlight:yellow">                                                             tmp.new_cipher),<o:p></o:p></span></b></p>
<p class="MsoNormal"><b><span style="background:yellow;mso-highlight:yellow">                                             SSL_C_EXPORT_PKEYLENGTH(s-><o:p></o:p></span></b></p>
<p class="MsoNormal"><b><span style="background:yellow;mso-highlight:yellow">                                                                     s3->tmp.new_cipher));</span></b><b><o:p></o:p></b></p>
<p class="MsoNormal">            }<o:p></o:p></p>
<p class="MsoNormal">            if (ecdhp == NULL) {<o:p></o:p></p>
<p class="MsoNormal">                al = SSL_AD_HANDSHAKE_FAILURE;<o:p></o:p></p>
<p class="MsoNormal">                SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,<o:p></o:p></p>
<p class="MsoNormal">                       SSL_R_MISSING_TMP_ECDH_KEY);<o:p></o:p></p>
<p class="MsoNormal">                goto f_err;<o:p></o:p></p>
<p class="MsoNormal">            }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">            if (s->s3->tmp.ecdh != NULL) {<o:p></o:p></p>
<p class="MsoNormal">                SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,<o:p></o:p></p>
<p class="MsoNormal">                       ERR_R_INTERNAL_ERROR);<o:p></o:p></p>
<p class="MsoNormal">                goto err;<o:p></o:p></p>
<p class="MsoNormal">            }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">            /* Duplicate the ECDH structure. */<o:p></o:p></p>
<p class="MsoNormal">            if (ecdhp == NULL) {<o:p></o:p></p>
<p class="MsoNormal">                SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB);<o:p></o:p></p>
<p class="MsoNormal">                goto err;<o:p></o:p></p>
<p class="MsoNormal">            }<o:p></o:p></p>
<p class="MsoNormal">            if (s->cert->ecdh_tmp_auto)<o:p></o:p></p>
<p class="MsoNormal">                ecdh = ecdhp;<o:p></o:p></p>
<p class="MsoNormal">            <b><span style="background:yellow;mso-highlight:yellow">else if ((ecdh = EC_KEY_dup(ecdhp)) == NULL) {                                                   
</span></b><b><span style="font-family:Wingdings;background:yellow;mso-highlight:yellow">ß</span></b><b><span style="background:yellow;mso-highlight:yellow"> Once the key is duplicated the memory for the application should be released?</span></b><b><o:p></o:p></b></p>
<p class="MsoNormal">                SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB);<o:p></o:p></p>
<p class="MsoNormal">                goto err;<o:p></o:p></p>
<p class="MsoNormal">            }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">            s->s3->tmp.ecdh = ecdh;<o:p></o:p></p>
<p class="MsoNormal">            if ((EC_KEY_get0_public_key(ecdh) == NULL) ||<o:p></o:p></p>
<p class="MsoNormal">                (EC_KEY_get0_private_key(ecdh) == NULL) ||<o:p></o:p></p>
<p class="MsoNormal">                (s->options & SSL_OP_SINGLE_ECDH_USE)) {<o:p></o:p></p>
<p class="MsoNormal">                if (!EC_KEY_generate_key(ecdh)) {<o:p></o:p></p>
<p class="MsoNormal">                    SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,<o:p></o:p></p>
<p class="MsoNormal">                           ERR_R_ECDH_LIB);<o:p></o:p></p>
<p class="MsoNormal">                    goto err;<o:p></o:p></p>
<p class="MsoNormal">                }<o:p></o:p></p>
<p class="MsoNormal">            }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">            if (((group = EC_KEY_get0_group(ecdh)) == NULL) ||<o:p></o:p></p>
<p class="MsoNormal">                (EC_KEY_get0_public_key(ecdh) == NULL) ||<o:p></o:p></p>
<p class="MsoNormal">                (EC_KEY_get0_private_key(ecdh) == NULL)) {<o:p></o:p></p>
<p class="MsoNormal">                SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB);<o:p></o:p></p>
<p class="MsoNormal">                goto err;<o:p></o:p></p>
<p class="MsoNormal">            }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">            if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) &&<o:p></o:p></p>
<p class="MsoNormal">                (EC_GROUP_get_degree(group) > 163)) {<o:p></o:p></p>
<p class="MsoNormal">                SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,<o:p></o:p></p>
<p class="MsoNormal">                       SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER);<o:p></o:p></p>
<p class="MsoNormal">                goto err;<o:p></o:p></p>
<p class="MsoNormal">            }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">            /*<o:p></o:p></p>
<p class="MsoNormal">             * XXX: For now, we only support ephemeral ECDH keys over named<o:p></o:p></p>
<p class="MsoNormal">             * (not generic) curves. For supported named curves, curve_id is<o:p></o:p></p>
<p class="MsoNormal">             * non-zero.<o:p></o:p></p>
<p class="MsoNormal">             */<o:p></o:p></p>
<p class="MsoNormal">            if ((curve_id =<o:p></o:p></p>
<p class="MsoNormal">                 tls1_ec_nid2curve_id(EC_GROUP_get_curve_name(group)))<o:p></o:p></p>
<p class="MsoNormal">                == 0) {<o:p></o:p></p>
<p class="MsoNormal">                SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,<o:p></o:p></p>
<p class="MsoNormal">                       SSL_R_UNSUPPORTED_ELLIPTIC_CURVE);<o:p></o:p></p>
<p class="MsoNormal">                goto err;<o:p></o:p></p>
<p class="MsoNormal">            }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">            /*<o:p></o:p></p>
<p class="MsoNormal">             * Encode the public key. First check the size of encoding and<o:p></o:p></p>
<p class="MsoNormal">             * allocate memory accordingly.<o:p></o:p></p>
<p class="MsoNormal">             */<o:p></o:p></p>
<p class="MsoNormal">            encodedlen = EC_POINT_point2oct(group,<o:p></o:p></p>
<p class="MsoNormal">                                            EC_KEY_get0_public_key(ecdh),<o:p></o:p></p>
<p class="MsoNormal">                                            POINT_CONVERSION_UNCOMPRESSED,<o:p></o:p></p>
<p class="MsoNormal">                                            NULL, 0, NULL);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">            encodedPoint = (unsigned char *)<o:p></o:p></p>
<p class="MsoNormal">                OPENSSL_malloc(encodedlen * sizeof(unsigned char));<o:p></o:p></p>
<p class="MsoNormal">            bn_ctx = BN_CTX_new();<o:p></o:p></p>
<p class="MsoNormal">            if ((encodedPoint == NULL) || (bn_ctx == NULL)) {<o:p></o:p></p>
<p class="MsoNormal">                SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,<o:p></o:p></p>
<p class="MsoNormal">                       ERR_R_MALLOC_FAILURE);<o:p></o:p></p>
<p class="MsoNormal">                goto err;<o:p></o:p></p>
<p class="MsoNormal">            }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">            encodedlen = EC_POINT_point2oct(group,<o:p></o:p></p>
<p class="MsoNormal">                                            EC_KEY_get0_public_key(ecdh),<o:p></o:p></p>
<p class="MsoNormal">                                            POINT_CONVERSION_UNCOMPRESSED,<o:p></o:p></p>
<p class="MsoNormal">                                            encodedPoint, encodedlen, bn_ctx);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">            if (encodedlen == 0) {<o:p></o:p></p>
<p class="MsoNormal">                SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB);<o:p></o:p></p>
<p class="MsoNormal">                goto err;<o:p></o:p></p>
<p class="MsoNormal">            }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">            BN_CTX_free(bn_ctx);<o:p></o:p></p>
<p class="MsoNormal">            bn_ctx = NULL;<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">            /*<o:p></o:p></p>
<p class="MsoNormal">             * XXX: For now, we only support named (not generic) curves in<o:p></o:p></p>
<p class="MsoNormal">             * ECDH ephemeral key exchanges. In this situation, we need four<o:p></o:p></p>
<p class="MsoNormal">             * additional bytes to encode the entire ServerECDHParams<o:p></o:p></p>
<p class="MsoNormal">             * structure.<o:p></o:p></p>
<p class="MsoNormal">             */<o:p></o:p></p>
<p class="MsoNormal">            n = 4 + encodedlen;<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">            /*<o:p></o:p></p>
<p class="MsoNormal">             * We'll generate the serverKeyExchange message explicitly so we<o:p></o:p></p>
<p class="MsoNormal">             * can set these to NULLs<o:p></o:p></p>
<p class="MsoNormal">             */<o:p></o:p></p>
<p class="MsoNormal">            r[0] = NULL;<o:p></o:p></p>
<p class="MsoNormal">            r[1] = NULL;<o:p></o:p></p>
<p class="MsoNormal">            r[2] = NULL;<o:p></o:p></p>
<p class="MsoNormal">            r[3] = NULL;<o:p></o:p></p>
<p class="MsoNormal">        } else<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Thanks for your help in advance<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Regards<o:p></o:p></p>
<p class="MsoNormal">Darshan<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</body>
</html>