{"id":19217,"date":"2022-06-01T07:20:57","date_gmt":"2022-06-01T15:20:57","guid":{"rendered":"https:\/\/www.palada.net\/index.php\/2022\/06\/01\/news-12950\/"},"modified":"2022-06-01T07:20:57","modified_gmt":"2022-06-01T15:20:57","slug":"news-12950","status":"publish","type":"post","link":"http:\/\/www.palada.net\/index.php\/2022\/06\/01\/news-12950\/","title":{"rendered":"Analyzing CVE-2022-0778: When Square Root Results in a Denial of Service"},"content":{"rendered":"<p><strong>Credit to Author: hardikshah| Date: Wed, 01 Jun 2022 14:31:06 +0000<\/strong><\/p>\n<div class=\"entry-content lg:prose-lg mx-auto prose max-w-4xl\">\n<p>Generally speaking, secure communications should be part of infosec\u2019s solution set, not part of the problem. When CVE-2022-0778 revealed that a maliciously crafted SSL certificate could lead to near-total CPU utilization and denial of service on a targeted machine, we thought it would be instructive to see exactly how something so right can, in very specific situations, go so wrong.<\/p>\n<p><strong>CVE-2022-0778 in a Nutshell<\/strong><\/p>\n<p>OpenSSL is a very popular library, widely used by many organizations and software applications requiring secure communications. A recently revealed OpenSSL vulnerability, CVE-2022-0778, can use specially crafted certificates to cause a Denial of Service (DoS). The vulnerability affects both clients and servers.<\/p>\n<p>The vulnerability lies in OpenSSL\u2019s implementation of the Tonelli-Shanks algorithm, used to find the square roots of numbers in the elliptic curve cryptography at the heart of the encryption library. This vulnerability occurs when instead of a prime number, a composite number is passed to the algorithm. This results in a computational problem like integer <a href=\"https:\/\/handwiki.org\/wiki\/Integer_factorization\">factorization<\/a>.<\/p>\n<p>In this report we\u2019ll first explain the basics of elliptic curve cryptography, and then provide a detailed analysis of the issue that leads to CVE-2022-0778. This is interesting math, so we\u2019ll walk through it carefully.<\/p>\n<p><strong>Elliptic Curve Cryptography in Short<\/strong><\/p>\n<p>Elliptic curve cryptography (ECC) is a public-key cryptography based on <a href=\"https:\/\/medium.com\/@youssef.housni21\/why-elliptic-curves-are-called-elliptic-a8327d94e3d1\">elliptic curves<\/a>. It is a modern successor of the legendary RSA cryptosystem, but using the interesting properties of elliptic curves instead of RSA\u2019s multiplication of prime numbers. Because ECC can use smaller key sizes, it is faster than RSA \u2013 an obvious benefit.<\/p>\n<p>Elliptic curves are algebraic curves. The following equation describes an elliptic curve:<\/p>\n<p style=\"text-align: center\"><em>Ax<sup>3<\/sup> + Bx<sup>2<\/sup> y + Cxy<sup>2<\/sup> + Dy<sup>3<\/sup> + Ex<sup>2<\/sup> + Fxy + Gy<sup>2<\/sup> + Hx + Iy +J = 0<\/em><\/p>\n<p>Here <em>A,B\u2026J<\/em> defines the curve. In cryptography, however, a simplified form of the equation \u2013 called the Weierstrass elliptic function &#8212; is used:<\/p>\n<p style=\"text-align: center\"><em>y<sup>2<\/sup> = x<sup>3<\/sup> + ax + b<\/em><\/p>\n<p>If we visualize the curve, we see something like this:<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/05\/Picture1.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-84973\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/05\/Picture1.png\" alt=\"Image showing an elliptic curve with several points identified\" width=\"602\" height=\"450\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/05\/Picture1.png 602w, https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/05\/Picture1.png?resize=300,224 300w\" sizes=\"auto, (max-width: 602px) 100vw, 602px\" \/><\/a><\/p>\n<p><em>Figure 1: <u>An elliptic curve. (\u201cElliptic\u201d in this context refers to the algebra describing the curve, not to the oval shape known as an ellipse.) Image source: <\/u><\/em><a href=\"https:\/\/www.desmos.com\/\"><em>https:\/\/www.desmos.com\/<\/em><\/a><\/p>\n<p>If we take two points on this curve &#8212; point 1 and point 2 &#8212; and draw a line, that line intersects the curve at point 3. If we take the opposite point (that is, the point equal to point 3, on the other side of the X axis), it will be point 1 + point2 as shown in the above image.<\/p>\n<p>ECC uses an elliptic curve over finite fields, and the points on the curve are limited to integer coordinates. Thus, the above curve in the modular form will be as follows:<\/p>\n<p style=\"text-align: center\"><em>y<sup>2<\/sup> \u2261 x<sup>3<\/sup> + ax + b (mod p)<\/em><\/p>\n<p>where <em>p<\/em> is a prime number denoting the size of the field. (The symbol \u2261\u00a0denotes congruence.)<\/p>\n<p>Secondly, elliptic curves are defined over finite fields. Because of this, there exists for every elliptic curve a pre-defined constant point, which is denoted G &#8212; the generator point, also known as the base point. Any point P in the subgroup over the elliptic curve can be generated by multiplying G with some integer, K, like so:<\/p>\n<p style=\"text-align: center\"><em>P = K*G<\/em><\/p>\n<p>Finally, performing the algebraic equation on any two points in the field will result in another point in the field. All the points in the elliptic curve over a finite field form a finite group; the total number of points is called the order of curve, and is denoted by <em>n<\/em>. There can be multiple non-overlapping subgroups and those will be denoted by <em>h<\/em>; this is called the cofactor. The number of points in each subgroup is denoted by <em>r<\/em>. So:<\/p>\n<p style=\"text-align: center\"><em>n=h*r<\/em><\/p>\n<p>We will not delve further into order and cofactor in this report; it is sufficient for our purposes here to note they exist.<\/p>\n<p><strong>How Is It Used for Encryption?<\/strong><\/p>\n<p>So, in an elliptic curve we have the following:<\/p>\n<ol>\n<li>The elliptic curve over a finite field of form \u2013 <em>y<sup>2<\/sup>\u2261 x<sup>3<\/sup>\u00a0+\u00a0ax +\u00a0b\u00a0(mod\u00a0p)<\/em><\/li>\n<li>The generator point or base point &#8212; denoted by <em>G<\/em>.<\/li>\n<li>An integer value <em>K<\/em> which, when multiplied with <em>G<\/em>, results in another point <em>P<\/em> on the curve \u2013 <em>P = K*G.<\/em><\/li>\n<\/ol>\n<p>Now, it is quick and easy to calculate <em>P<\/em> as shown, by multiplying <em>K<\/em> and <em>G<\/em>. But if we want to figure out <em>K<\/em>\u00a0 by dividing <em>P<\/em> by <em>G<\/em>, i.e., <em>K =P\/G<\/em>, then it is very difficult or infeasible for large values of <em>K<\/em>.<\/p>\n<p>This asymmetry, in which multiplying is easy but dividing (factoring) is hard, is the basis of elliptic curve cryptography and is known as the elliptic curve discrete logarithmic problem (ECDLP). Many ECC algorithms rely on this problem by using carefully chosen elliptic curves &#8212; fields for which no efficient algorithm exists.<\/p>\n<p>In ECC encryption, <em>K<\/em> is the private key, <em>P<\/em> is the public key, and <em>G<\/em> is the generator point. By understanding ECDLP as shown above, we know that given a generator point <em>G<\/em>, it\u2019s very easy to figure out public key <em>P<\/em> on the elliptic curve by multiplying <em>G<\/em> by private key <em>K<\/em>. But even with the generator point <em>G<\/em> and public key <em>P<\/em> known, it remains very difficult to calculate private key <em>K<\/em>!<\/p>\n<p><strong>Saving Space with Compressed EC Points\u2026 at a Price<\/strong><\/p>\n<p>Now we know that a public key is simply a point on the elliptic curve. As such, it will have an X coordinate and a Y coordinate. As a reminder, the equation for the elliptic curve itself is<\/p>\n<p style=\"text-align: center\">y<sup>2<\/sup>\u00a0\u2261 x<sup>3<\/sup>\u00a0+\u00a0<em>a<\/em>x +\u00a0<em>b<\/em>\u00a0(mod\u00a0<em>p<\/em>)<\/p>\n<p>So, if we know <em>x<\/em>, we can easily figure out two values of <em>y<\/em> by solving the following two equations:<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/05\/math1.png\"><img decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-84976 aligncenter\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/05\/math1.png\" alt=\"y1\u2261\u221a(\u3016(x\u3017^3+ax+b)) (mod p) , and also y2\u2261p-\u221a(x^3+ax+b)  (mod p)\" width=\"220\" height=\"73\" \/><\/a><\/p>\n<p><em>p<\/em> is an odd prime number, so one value of <em>y<\/em> would be even and another one would be odd, and either will satisfy the equation.<\/p>\n<p>So we don\u2019t need to use <em>{x,y}<\/em> coordinates in the public key; we can simply use {<em>x, [even] or [odd]<\/em>} for our <em>x<\/em> coordinates, with <em>even<\/em> or <em>odd<\/em> denoted by an extra parity bit called a Compressed EC Point. Doing so can save us some space, which is useful for network encryption since it\u2019s less data to transfer.<\/p>\n<p>However, it\u2019s at this point we encounter the vulnerability in OpenSSL\u2019s implementation of the Tonelli-Shanks algorithm, which is used to calculate the two square-root values that give us <em>y1<\/em> and <em>y2<\/em>. Basically, thanks to incautious implementation, the issue in OpenSSL can be triggered while finding the value of <em>y<\/em> from <em>x<\/em> if the public key uses coordinates in the Compressed EC Point format.<\/p>\n<p><strong>How Is It Used in SSL Certificates?<\/strong><\/p>\n<p>With all this in mind, we can see a number of things when looking at an SSL certificate that uses elliptic curve cryptography, as shown in Figure 2:<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/05\/Picture2.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-84977\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/05\/Picture2.png\" alt=\"An SSL certificate\" width=\"602\" height=\"719\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/05\/Picture2.png 602w, https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/05\/Picture2.png?resize=251,300 251w\" sizes=\"auto, (max-width: 602px) 100vw, 602px\" \/><\/a><\/p>\n<p><em>Figure 2: Details of an SSL certificate<\/em><\/p>\n<p>As we see, in SSL certificates we have the following fields:<\/p>\n<ol>\n<li><strong>Public Key (pub)<\/strong> = this is <em>P<\/em>, a point on the curve; i.e., x and y coordinates. This can be in compressed format.<\/li>\n<li><strong>Prime<\/strong> = this is the prime number <em>p,<\/em> which will be used as (mod <em>p<\/em>)<\/li>\n<li><strong>A and B<\/strong> = these two define the curve, i.e., y<sup>2<\/sup>\u00a0\u2261 x<sup>3<\/sup>\u00a0+\u00a0<em>a<\/em>x +\u00a0<em>b<\/em>\u00a0(mod\u00a0<em>p<\/em>)<\/li>\n<li><strong>Generator<\/strong> = This is the base point on the curve by which any other point on the curve can be calculated.<\/li>\n<li><strong>Order and Cofactor<\/strong> = These denote the order and cofactor of the curve. (Again, we will not be using these for this report.)<\/li>\n<\/ol>\n<p>This certificate can be used by the server or by clients. Once this certificate reaches the receiver, the receiver will use the public key to encrypt. If the public key is in the compressed format, the receiver needs to decompress it to figure out <em>y,<\/em> and to do that they need to solve the curve equation &#8212; y<sup>2<\/sup>\u00a0\u2261 x<sup>3<\/sup>\u00a0+\u00a0<em>a<\/em>x +\u00a0<em>b<\/em>\u00a0(mod\u00a0<em>p<\/em>) .<\/p>\n<p>Since solving the curve equation requires calculating a modular square root of a potentially big number, the function BN_mod_sqrt() will be called. This is the specific function where the CVE-2022-0778 vulnerability can be triggered by a specially crafted certificate with malicious values.<\/p>\n<p><strong>Calculating the Modular Square Root<\/strong><\/p>\n<p>As mentioned, OpenSSL uses the function BN_mod_sqrt() to calculate modular square roots. As per OpenSSL\u2019s <a href=\"https:\/\/www.openssl.org\/docs\/man1.1.1\/man3\/BN_mod_sqrt.html\">documentation<\/a>, BN_mod_sqrt() returns the modular square root of\u00a0<em>a<\/em>\u00a0such that\u00a0in<sup>2<\/sup> = <em>a<\/em> (mod <em>p<\/em>). The modulus\u00a0<em>p<\/em>\u00a0must be a prime or an error or an incorrect &#8220;result&#8221; will be returned. The result is stored into\u00a0<em>in<\/em>\u00a0which can be NULL. The result will be newly allocated in that case. We can see, therefore, that <em>p <\/em>must be a prime number or the result would be incorrect.<\/p>\n<p>As mentioned, the CVE-2022-0778 vulnerability lies in OpenSSL\u2019s implementation of the Tonelli-Shanks algorithm used to perform that calculation.<strong>\u00a0 <\/strong>This algorithm finds a square root or a number <em>n<\/em> modulo <em>p<\/em> and expects two parameters, <em>p<\/em> and <em>n<\/em>. Here <em>p<\/em> is a prime number, and <em>n<\/em> is the number for which we want to find a square root.<\/p>\n<p>There are a few fundamental assumptions and steps for this algorithm, which are summarized below. (For detailed information on the algorithms and proofs supporting this, please check the reference section at the end of this blog.)<\/p>\n<ol>\n<li>If given a non-zero number <em>n<\/em> and an odd prime <em>p<\/em>, as per Euler\u2019s criterion, <em>n<\/em> will have a square root if and only if following holds true:<\/li>\n<\/ol>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/math2.png\"><img decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-84979 aligncenter\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/math2.png\" alt=\"n^((p-1)\/2)\u22611 (mod p) \" width=\"127\" height=\"31\" \/><\/a><\/p>\n<p><em>n<\/em> will be a quadratic residue.<\/p>\n<p>2. If a number <em>z<\/em> doesn\u2019t have a square root, then as per Euler\u2019s criterion the following will hold true:<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/math3.png\"><img decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-84981 aligncenter\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/math3.png\" alt=\"z^((p-1)\/2)\u2261 -1 (mod p)\" width=\"136\" height=\"31\" \/><\/a><\/p>\n<p>Half of the integers between 1 and <em>p-1<\/em> will have this property. <em>z<\/em> will be non-residue.<\/p>\n<p>3. Since <em>p<\/em> is a prime number, we can write p &#8211; 1 = 2<sup>s<\/sup> * Q\u00a0(Here <em>Q<\/em> is an odd number.)<\/p>\n<p>Now if we try:<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/math4.png\"><img decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-84982 aligncenter\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/math4.png\" alt=\"R\u2261n^(((Q+1))\/2) (mod p)\" width=\"130\" height=\"34\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/math4.png 130w, https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/math4.png?resize=128,34 128w\" sizes=\"auto, (max-width: 130px) 100vw, 130px\" \/><\/a><\/p>\n<p>Then:<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/math5.png\"><img decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-84983 aligncenter\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/math5.png\" alt=\"R^2\u2261n^(Q+1)=(n)(n^Q )(mod p)\" width=\"195\" height=\"22\" \/><\/a><\/p>\n<p>Here, if we say <i>t = n<sup>Q<\/sup><\/i>,\u00a0we can have the following conditions:<\/p>\n<p>1. If <em>t<\/em>=1, then <em>R<\/em> will be the square root of <em>n,<\/em> as the equation will become<\/p>\n<p style=\"text-align: center\"><i>R<sup>2<\/sup> \u2261 nt (mod p)<\/i><\/p>\n<p>Also, for <em>M=S<\/em> it will satisfy the following:<\/p>\n<p style=\"text-align: center\"><em>t is 2<sup>M-1<\/sup>\u00a0<\/em>root of 1<\/p>\n<p>2. If <em>t<\/em> = 0, then <em>R<\/em> will be 0 as per the above equation.<\/p>\n<p>3. If <em>t<\/em> is not 0 or 1, we need to calculate another value of <em>R<\/em> and <em>t<\/em> for <em>M<\/em>-1, and we need to repeat this until <em>t<\/em> becomes 1 (i.e., <em>t<\/em> becomes 2<sup>0<\/sup>, at which point R will be the square root of <em>n<\/em>).<\/p>\n<p>4. To find new values of <em>R<\/em> and <em>t<\/em>, we can multiply it by a factor b<sup>2<\/sup> which will be 2<sup>M-2<\/sup>\u00a0&#8212; the root of -1. To calculate <em>b<\/em>, z<sup>Q <\/sup>will be repeatedly squared.<\/p>\n<p>If the first solution is R, the second will be p-R.<\/p>\n<p><strong>Replicating the Issue and Debugging the Code<\/strong><\/p>\n<p>Proof-of-concept code has been <a href=\"https:\/\/github.com\/drago-96\/CVE-2022-0778\">posted to GitHub<\/a> by drago-96 (Riccardo Zanotto). We can generate a certificate with crafted parameters and use the following command to replicate the issue with a vulnerable OpenSSL version:<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture3.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-84985\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture3.png\" alt=\"IMproper parameters passed to OpenSSL\" width=\"528\" height=\"36\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture3.png 528w, https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture3.png?resize=300,20 300w\" sizes=\"auto, (max-width: 528px) 100vw, 528px\" \/><\/a><\/p>\n<p><em>Figure 3: Passing OpenSSL a certificate with improper parameters<\/em><\/p>\n<p>We can see the CPU utilization is almost 100%:<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture4.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-84986\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture4.png\" alt=\"Not the kind of thing you want to see as far as CPU utilization\" width=\"640\" height=\"33\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture4.png 767w, https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture4.png?resize=300,15 300w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><\/p>\n<p><em>Figure 4: OpenSSL 100% CPU utilization<\/em><\/p>\n<p>For debugging purposes we will use drago96\u2019s <a href=\"https:\/\/github.com\/drago-96\/CVE-2022-0778\/blob\/master\/my_bad_sqrt.c\">simple proof of concept<\/a><em>, <\/em>which calls the vulnerable function. On compiling and running it, we can see that it goes into an infinite loop causing almost 100% CPU utilization.<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture5.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-84987\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture5.png\" alt=\"In this image CPU utilization is 99.4 percent\" width=\"602\" height=\"21\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture5.png 602w, https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture5.png?resize=300,10 300w\" sizes=\"auto, (max-width: 602px) 100vw, 602px\" \/><\/a><\/p>\n<p><em>Figure 5: Parsing the improper certificate leads to severe CPU utilization<\/em><\/p>\n<p>Looking at the certificate we can see that it uses two specific values of <em>p<\/em> and <em>a<\/em>, which are 697 and 696 respectively.<\/p>\n<p>If we look at the elliptic curve equation using those values, it becomes<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/math6.png\"><img decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-84988 aligncenter\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/math6.png\" alt=\"y^2 = 696 (mod 697)  i.e. y=\u221a696(mod 697)\" width=\"285\" height=\"30\" \/><\/a><\/p>\n<p>where <em>x<sup>3<\/sup> + ax + b <\/em>= 696<\/p>\n<p>Since we know the value of <em>p<\/em> should be prime, we should notice that 697 is not actually a prime number. (It can be written as 2<sup>3<\/sup> * 87 + 1.)<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture6.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-84990\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture6.png\" alt=\"697 is not a prime number; it's 17 times 41.\" width=\"215\" height=\"51\" \/><\/a><\/p>\n<p><em>Figure 6: Prime or not prime? Not prime.<\/em><\/p>\n<p>If we try this program with any other random numbers, then this issue will not be replicated. (The logic behind using these specific values, and finding more such values of <em>p<\/em> and <em>a<\/em><strong>,<\/strong> is discussed later in this post.)<\/p>\n<p>On running OpenSSL with this proof of concept and looking at the call to bn_mod_sqrt, we can see that parameters passed to it are 696 and 697, as shown in Figure 7.<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture7.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-84991\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture7.png\" alt=\"Pass that parameter!\" width=\"602\" height=\"568\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture7.png 602w, https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture7.png?resize=300,283 300w\" sizes=\"auto, (max-width: 602px) 100vw, 602px\" \/><\/a><\/p>\n<p><em>Figure 7: Passing the parameters to the square-root function.<\/em><\/p>\n<p>There is a check to see if <em>p<\/em> is odd, or if it is 1 or 2, but there is no check to see whether <em>p<\/em> is prime, as shown below. First <em>p<\/em> is checked:<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture8.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-84992\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture8.png\" alt=\"An odd number, neither 1 nor 0 -- good enough for the checker\" width=\"549\" height=\"87\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture8.png 549w, https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture8.png?resize=300,48 300w\" sizes=\"auto, (max-width: 549px) 100vw, 549px\" \/><\/a><\/p>\n<p><em>Figure 8: <\/em>p<em> is an odd number that is neither 0 nor 1, so it passes the checks<\/em><\/p>\n<p>Then there is a check to see if <em>a<\/em> is 0 or 1:<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture9.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-84993\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture9.png\" alt=\"a isn't one or zero, you say? Good to know.\" width=\"469\" height=\"291\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture9.png 469w, https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture9.png?resize=300,186 300w\" sizes=\"auto, (max-width: 469px) 100vw, 469px\" \/><\/a><\/p>\n<p><em>Figure 9: Making sure <\/em>a<em> is neither 1 nor 0<\/em><\/p>\n<p>At this point, the function sets the value of <em>e<\/em> as 1 and calls the BN_is_bit_set function, which basically converts it in the form 2<sup>e <\/sup>* q as shown below, incrementing the value of <em>e<\/em> for each loop iteration:<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture10.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-84994\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture10.png\" alt=\"Converting the value of e\" width=\"562\" height=\"129\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture10.png 562w, https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture10.png?resize=300,69 300w\" sizes=\"auto, (max-width: 562px) 100vw, 562px\" \/><\/a><\/p>\n<p><em>Figure 10: Converting the value of <\/em>e<\/p>\n<p>So, <em>e<\/em> is the power of 2, and <em>q<\/em> is an odd number.<\/p>\n<p>At this point there are different potential outcomes depending on the value of <em>e<\/em>. If the value of <em>e<\/em> is either 1 or 2, the vulnerable code will not be reached. But if the value of <em>e<\/em> is 3 or more, then the vulnerable code can be reached, and the Tonelli-Shanks algorithm will be used:<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture11.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-84995\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture11.png\" alt=\"Seeking a value of y\" width=\"602\" height=\"410\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture11.png 602w, https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture11.png?resize=300,204 300w\" sizes=\"auto, (max-width: 602px) 100vw, 602px\" \/><\/a><\/p>\n<p><em>Figure 11: In search of a value of <\/em>y<em> that is not a square<\/em><\/p>\n<p>It takes <em>y<\/em> from 2 to 22 and then finds a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Kronecker_symbol\">Kronecker symbol<\/a> (which is a generalized version of a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Jacobi_symbol\">Jacobi symbol<\/a>, which is a generalized version of a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Legendre_symbol\">Legendre symbol<\/a>) with a value of <em>q<\/em>.<\/p>\n<p>This in turn is used to find the non-quadratic residue modulo p. There are few conditions at this point:<\/p>\n<ol>\n<li>If the returned value is 0 or &lt; -1, then the program will exit.<\/li>\n<li>If the returned value is 1, then the do while loop will continue.<\/li>\n<li>If the returned value is -1, then the program will go to the next step, and we have found <em>z<\/em> ; that is, the non-quadratic residue modulo <em>p<\/em>.<\/li>\n<\/ol>\n<p>It will then calculate the value of <em>b<\/em>, and enter into a while loop:<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture12.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-84996\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture12.png\" alt=\"The loop\" width=\"602\" height=\"560\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture12.png 602w, https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture12.png?resize=300,279 300w\" sizes=\"auto, (max-width: 602px) 100vw, 602px\" \/><\/a><\/p>\n<p><em>Figure 12: In the loop<\/em><\/p>\n<p>It then checks if <em>b<\/em> is one; if so, then the solution is found. Otherwise, it will calculate the value of <em>t = b<sup>2<\/sup>(mod p)<\/em>.<\/p>\n<p>But in our example, <em>t<\/em> will be 1 for the first time, as the value of <em>p<\/em> is 697 and <em>b<\/em> is 696.<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture13.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-84997\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture13.png\" alt=\"T =1 now\" width=\"602\" height=\"514\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture13.png 602w, https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture13.png?resize=300,256 300w\" sizes=\"auto, (max-width: 602px) 100vw, 602px\" \/><\/a><\/p>\n<p><em>Figure 13: And now t=1<\/em><\/p>\n<p>Under these circumstances, the program will not enter the second while loop. After performing a few operations, the value of <em>t<\/em> will be changed:<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture14.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-84998\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture14.png\" alt=\"A change in value\" width=\"602\" height=\"476\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture14.png 602w, https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture14.png?resize=300,237 300w\" sizes=\"auto, (max-width: 602px) 100vw, 602px\" \/><\/a><\/p>\n<p><em>Figure 14: A change in value<\/em><\/p>\n<p>Then it will move the value of <em>i<\/em>, which is 1, to <em>e<\/em>:<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture15.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-84999\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture15.png\" alt=\"the value of is is added to e\" width=\"602\" height=\"473\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture15.png 602w, https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture15.png?resize=300,236 300w\" sizes=\"auto, (max-width: 602px) 100vw, 602px\" \/><\/a><\/p>\n<p><em>Figure 15: Adding the value of <\/em>i<em> to <\/em>e<\/p>\n<p>It will then again go to the while loop start. At this point <em>t<\/em> is not 1, so this time it will enter in the while loop. The value of <em>i<\/em> is 2 but the value of <em>e<\/em> is still 1, so the exit condition is not satisfied.<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture16.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-85000\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture16.png\" alt=\"And on it goes\" width=\"602\" height=\"484\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture16.png 602w, https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture16.png?resize=300,241 300w\" sizes=\"auto, (max-width: 602px) 100vw, 602px\" \/><\/a><\/p>\n<p><em>Figure 16: No exit<\/em><\/p>\n<p>Next the process will call another function, BN_mod_mul, to calculate the value of <em>t<\/em>:<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture17a.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-85002\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture17a.png\" alt=\"The BN_mod_mul function in action\" width=\"602\" height=\"489\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture17a.png 602w, https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture17a.png?resize=300,244 300w\" sizes=\"auto, (max-width: 602px) 100vw, 602px\" \/><\/a><\/p>\n<p><em>Figure 17: Enter BN_mod_mul<\/em><\/p>\n<p>If we step through this function, we can see the following:<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture18.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-85003\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture18.png\" alt=\"The BN_sqrt function is called\" width=\"602\" height=\"506\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture18.png 602w, https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture18.png?resize=300,252 300w\" sizes=\"auto, (max-width: 602px) 100vw, 602px\" \/><\/a><\/p>\n<p><em>Figure 18: With <\/em>a<em> and <\/em>b<em> equivalent, the BN_sqrt function is called<\/em><\/p>\n<p>Here <em>a<\/em> and <em>b<\/em> are the same, so the process will call the BN_sqrt function, which will calculate <em>t = a<sup>2<\/sup>(mod p)<\/em>.<\/p>\n<p>The value of <em>t<\/em> will never become 1, as <em>p<\/em> is not a prime number but a composite number. This loop will therefore continue forever. The endless, pointless calculation will thus cause extreme resource utilization and ultimately DoS in the application.<\/p>\n<p>How does a loop like this happen? In this article we\u2019re looking at the math and code, not the coding choices, but our colleagues at Naked Security have <a href=\"https:\/\/nakedsecurity.sophos.com\/2022\/03\/18\/openssl-patches-infinite-loop-dos-bug-in-certificate-verification\/\">a post concerning CVE-2022-0778<\/a> that leads into a discussion of the oddly framed and nested loops in OpenSSL\u2019s code that led to this problem.<\/p>\n<p><strong>Generating Numbers That Can Cause DoS<\/strong><\/p>\n<p>So far during the debugging we have used <em>p<\/em>=697 and <em>n<\/em>=696 as our values. But there are many such pairs of numbers that can cause this infinite loop (and thus the DoS). We can easily set forth the conditions for such pairs:<\/p>\n<p>1. <em>p<\/em> should be a composite odd number. (Again, if it is a prime number, the value of <em>t<\/em> becomes 1 and we exit the loop.)<\/p>\n<p>2. As mentioned earlier in the blog, if <em>p<\/em> is an odd prime number, then we can write <em>p-1<\/em> as<\/p>\n<p style=\"text-align: center\"><em>p-1 = 2<sup>Q<\/sup> * S<\/em><\/p>\n<p>Now we need value of <em>e<\/em> &gt;= 3, so let\u2019s use 3. This equation becomes<\/p>\n<p style=\"text-align: center\"><em>p-1 =\u00a02<sup>3<\/sup> * 2<sup>c<\/sup> * S <\/em>\u00a0(where <em>c=Q<\/em>-3) , which we can write as<\/p>\n<p style=\"text-align: center\"><em>p-1 = 8 * 2<sup>c<\/sup> * S<\/em><\/p>\n<p>This means <em>p-1<\/em> must be a multiple of 8.\u00a0 We can write that as:<\/p>\n<p style=\"text-align: center\"><em>p-1 = 8 * d * S<\/em><\/p>\n<p>Now if we calculate p, it will be:<\/p>\n<p style=\"text-align: center\"><em>p= 8*d*S+1<\/em> \u00a0<\/p>\n<p>Here <em>S<\/em> should be an odd number.<\/p>\n<p>3. We have seen how the Kronecker symbol was calculated from 2 to 22 with <em>p<\/em>:<\/p>\n<ol>\n<li>If it\u2019s 1, we continue the loop.<\/li>\n<li>If it\u2019s 0, we discard that value.<\/li>\n<li>If it\u2019s -1, that\u2019s the number.<\/li>\n<\/ol>\n<p>Based on this we can write a simple program in C that can generate various problematic pairs for <em>p<\/em> and <em>p<\/em>-1.<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture19.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-85004\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture19.png\" alt=\"A simple C program\" width=\"640\" height=\"422\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture19.png 754w, https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture19.png?resize=300,198 300w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><\/p>\n<p><em>Figure 19: A simple C program to find dangerous pairs of values<\/em><\/p>\n<p>If we run this program, we get the following:<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture20.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-85005\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture20.png\" alt=\"Five pairs of dangerous numbers\" width=\"332\" height=\"164\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture20.png 332w, https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture20.png?resize=300,148 300w\" sizes=\"auto, (max-width: 332px) 100vw, 332px\" \/><\/a><\/p>\n<p><em>Figure 20: Five pairs of numbers that can trigger the CVE-2022-0778 DoS<\/em><\/p>\n<p>Twitter user <a href=\"https:\/\/twitter.com\/fwarashi\">fwarashi<\/a> has <a href=\"https:\/\/zenn.dev\/kurenaif\/articles\/ec2eec4ec7ec52\">explained this in detail<\/a> in a post. (A sample python program is also available at that URL.)<\/p>\n<p>As we see in Figure 20, a few other number pairs that can cause the CVE-2022-0778 DoS are (184,185), (328,329), (376,377), (424,425), and (472,473). There are more, but to look briefly at two sets we found:<\/p>\n<p style=\"text-align: center\"><em>y<sup>2<\/sup><\/em> \u2261 184(<em>mod\u00a0 <\/em>185) &#8212; i.e., <em>x<sup>3<\/sup> + ax + b<\/em> = 184<\/p>\n<p style=\"text-align: center\"><em>y<sup>2<\/sup> <\/em>\u2261 328(<em>mod<\/em>\u00a0 329) &#8212; i.e., <em>x<sup>3<\/sup> + ax + b<\/em> = 328<\/p>\n<p>and proper values of <em>x<\/em>,<em>a <\/em>and <em>b <\/em>can be selected that satisfy this equation.<\/p>\n<p><strong>Fixing a Hole<\/strong><\/p>\n<p>In the unpatched version of OpenSSL, there was a while loop checking for the value of <em>t<\/em>, and inside that there was an if condition which was checking the value of <em>i ==e<\/em>, so the program was missing cases where <em>i&gt;e<\/em>. If the value of <em>i &gt; <\/em>e, and the value of <em>t<\/em> does not become 1 in case of a non-prime number, an infinite loop results, and DoS results from that.<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture21.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-85007\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture21.png\" alt=\"HIghlight section of unpatched code\" width=\"602\" height=\"382\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture21.png 602w, https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture21.png?resize=300,190 300w\" sizes=\"auto, (max-width: 602px) 100vw, 602px\" \/><\/a><\/p>\n<p><em>Figure 21: The unpatched code<\/em><\/p>\n<p>If we look at the patched code, we can see that instead of the while loop, a for loop is added. This runs till the value of <em>i&lt;e, <\/em>thus preventing the infinite loop issue.<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture22.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-85008\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture22.png\" alt=\"Fixed it!\" width=\"510\" height=\"443\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture22.png 510w, https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/picture22.png?resize=300,261 300w\" sizes=\"auto, (max-width: 510px) 100vw, 510px\" \/><\/a><\/p>\n<p><em>Figure 22: Patched code<\/em><\/p>\n<p>If the value of <em>i &gt; e,<\/em> then it will simply exit.<\/p>\n<p><strong>Conclusion<\/strong><\/p>\n<p>OpenSSL is a popular, broadly used library; it is not limited to any specific platform or application. Thus, the CVE-2022-0778 vulnerability could potentially affect systems of all sorts around the globe. The issue in OpenSSL can be triggered while finding the value of <em>y<\/em> from <em>x<\/em> if the public key uses coordinates in the Compressed EC Point format, causing high system utilization and potentially leading to a Denial of Service attack.<\/p>\n<p>Since implementing cryptographic algorithms is a niche task, sometime errors such as these may go unnoticed. In cases such as OpenSSL, where the code itself is complex, the complexity of the math itself can make it hard to spot a potential bug. All is not lost, though, as careful analysis can unpack the problem and guide us toward a solution.<\/p>\n<p><strong>Sophos coverage<\/strong><\/p>\n<p>Sophos IPS customers are protected against this threat by following sids which checks for malicious certificate download: \u00a02306976, 2306977 .<\/p>\n<p><strong>References and Credits<\/strong><\/p>\n<p>This vulnerability involves cryptography, number theory, algorithms, and so on. During this research I was helped by various available resources over the web and offline books. The following are some of the online materials I have used.<\/p>\n<p><strong>Source code and proof of concept:<\/strong><\/p>\n<p>OpenSSL: <a href=\"https:\/\/www.openssl.org\/\">https:\/\/www.openssl.org\/<\/a><\/p>\n<p>OpenSSL\u2019s repository:\u00a0 <a href=\"https:\/\/github.com\/openssl\/openssl\">https:\/\/github.com\/openssl\/openssl<\/a><\/p>\n<p>POC for CVE-2022-0778 from Drago-96 [Riccardo Zanotto]: <a href=\"https:\/\/github.com\/drago-96\/CVE-2022-0778\">https:\/\/github.com\/drago-96\/CVE-2022-0778<\/a><\/p>\n<p>Analysis by Kurenaif [@fwarashi]: <a href=\"https:\/\/zenn.dev\/kurenaif\/articles\/ec2eec4ec7ec52\">https:\/\/zenn.dev\/kurenaif\/articles\/ec2eec4ec7ec52<\/a><\/p>\n<p><strong>For further information:<\/strong><\/p>\n<p>Elliptic Curve Cryptography (from Nakov, Svetlin, <em>Practical Cryptography for Developers<\/em> [2018]): <strong>\u00a0<\/strong><a href=\"https:\/\/wizardforcel.gitbooks.io\/practical-cryptography-for-developers-book\/content\/asymmetric-key-ciphers\/elliptic-curve-cryptography-ecc.html\">https:\/\/wizardforcel.gitbooks.io\/practical-cryptography-for-developers-book\/content\/asymmetric-key-ciphers\/elliptic-curve-cryptography-ecc.html<\/a><\/p>\n<p>Hasan, Harady, <em>Elliptic Curves: A journey through theory and its applications<\/em> (2019): \u00a0\u00a0<a href=\"https:\/\/uu.diva-portal.org\/smash\/get\/diva2:1334316\/FULLTEXT01.pdf\">https:\/\/uu.diva-portal.org\/smash\/get\/diva2:1334316\/FULLTEXT01.pdf<\/a><\/p>\n<p>Integer Factorization Problem (HandWiki): <a href=\"https:\/\/handwiki.org\/wiki\/Integer_factorization\">https:\/\/handwiki.org\/wiki\/Integer_factorization<\/a><\/p>\n<p>\u201cOpenSSL patches infinite-loop DoS bug in certificate verification,\u201d Naked Security (Sophos blog, 18 March 2022), <a href=\"https:\/\/nakedsecurity.sophos.com\/2022\/03\/18\/openssl-patches-infinite-loop-dos-bug-in-certificate-verification\/\">https:\/\/nakedsecurity.sophos.com\/2022\/03\/18\/openssl-patches-infinite-loop-dos-bug-in-certificate-verification\/<\/a><\/p>\n<p>Tonelli-Shanks algorithm (HandWiki): <a href=\"https:\/\/handwiki.org\/wiki\/Tonelli%E2%80%93Shanks_algorithm\">https:\/\/handwiki.org\/wiki\/Tonelli%E2%80%93Shanks_algorithm<\/a><\/p>\n<p>Tonelli-Shanks algorithm (Wikipedia): <a href=\"https:\/\/en.wikipedia.org\/wiki\/Tonelli%E2%80%93Shanks_algorithm\">https:\/\/en.wikipedia.org\/wiki\/Tonelli%E2%80%93Shanks_algorithm<\/a><\/p>\n<\/p><\/div>\n<p><a href=\"https:\/\/news.sophos.com\/en-us\/2022\/06\/01\/cve-2022-0778-openssl-denial-of-service\/\" target=\"bwo\" >http:\/\/feeds.feedburner.com\/sophos\/dgdY<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p><img decoding=\"async\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2022\/06\/crypto-hero-image.png\"\/><\/p>\n<p><strong>Credit to Author: hardikshah| Date: Wed, 01 Jun 2022 14:31:06 +0000<\/strong><\/p>\n<p>How could a humble SSL certificate entirely gridlock a system? Walk with us through the math<\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"colormag_page_container_layout":"default_layout","colormag_page_sidebar_layout":"default_layout","footnotes":""},"categories":[10378,10377],"tags":[11047,10533,22787,26383,18513,16771],"class_list":["post-19217","post","type-post","status-publish","format-standard","hentry","category-security","category-sophos","tag-cryptography","tag-dos","tag-openssl","tag-sophos-secops","tag-sophoslabs-uncut","tag-threat-research"],"_links":{"self":[{"href":"http:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/posts\/19217","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"http:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/comments?post=19217"}],"version-history":[{"count":0,"href":"http:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/posts\/19217\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/media?parent=19217"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/categories?post=19217"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/tags?post=19217"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}